/**********************************************************************************************************************
 *  COPYRIGHT
 *  -------------------------------------------------------------------------------------------------------------------
 *  \verbatim
 *
 *                 TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION
 *
 *                 Property of Texas Instruments, Unauthorized reproduction and/or distribution
 *                 is strictly prohibited.  This product  is  protected  under  copyright  law
 *                 and  trade  secret law as an  unpublished work.
 *                 (C) Copyright Texas Instruments.  All rights reserved.
 *
 *  \endverbatim
 *  -------------------------------------------------------------------------------------------------------------------
 *  FILE DESCRIPTION
 *  -------------------------------------------------------------------------------------------------------------------
 *         File:  Dio.c
 *    Component:  Tms570_AutosarDioDriver
 *       Module:  DioDriver
 *    Generator:  -
 *
 *   Description: This DIO Driver provides services for
 *                reading and writing to/from
 *                        -   DIO Channels (Pins)
 *                        -   DIO Ports
 *                        -   DIO Channel Groups
 *
 *                This module works on pins and ports which are configured by the PORT driver for this purpose.
 *                For this reason there is no configuration and initialization of this port structure in the DIO
 *                Driver.
 *---------------------------------------------------------------------------------------------------------------------
 * Author:  Sunil Kumar T V
 *---------------------------------------------------------------------------------------------------------------------
 * Revision History
 *---------------------------------------------------------------------------------------------------------------------
 * Version        Date         Author                 Change ID       Description
 *---------------------------------------------------------------------------------------------------------------------
 * 02.10.00       11Feb2013    Sapthagiri G           0000000000000   Initial version (adapted from TMS570LS3xx v01.10.00).
 * 02.20.00       29Aug2013    Sreyas K               SDOCM00103509   Changes for Production Version Champion
 * 02.21.00       30Sep2014    Vineeth T Alex         SDOCM00113124   Changes for 2.21.00 release; Files restructured
 * 02.21.01       11Mar2016    Enrique Lizarraga      SDOCM00121657   -Changes for 2.21.01 version
 *                                                                    -Remove duplicated MemMap definition
 * 02.30.00       01Dec2016    Sudhakar Singh           None          -Update version info
 * 05.30.00       15Mar2017    Sudhakar Singh         SDOCM00122834   Version supports TMS570LSxx Family of Devices.
 *********************************************************************************************************************/

#define DIO_SOURCE

/**********************************************************************************************************************
 *  INCLUDES
 *********************************************************************************************************************/
/* SourceId : DIO_SourceId_004 */
/* DesignId : Dio_DesignId_04 */
/* Requirements : AR_DIO_SR7, AR_DIO_SR6 */
#include "Dio.h"
/* SourceId : DIO_SourceId_005 */
/* DesignId : Dio_DesignId_04 */
/* Requirements : AR_DIO_SR9 */
#if (DIO_DEM_ENABLE == STD_ON)
#include "Dem.h"
#endif

#include "SchM_Dio.h"

/* SourceId : DIO_SourceId_003 */
/* DesignId : Dio_DesignId_06 */
/* Requirements : AR_DIO_SR7, AR_DIO_SR45 */
#if (DIO_DEV_ERROR_DETECT == STD_ON)
#include "Det.h"
#endif

/**********************************************************************************************************************
 *  VERSION CHECK
 *********************************************************************************************************************/
#define DIO_SW_C_MAJOR_VERSION               (5U)
#define DIO_SW_C_MINOR_VERSION               (30U)
#define DIO_SW_C_PATCH_VERSION               (0U)
 
 /* AUTOSAR version information check has to match definition in header file */
#if (  (DIO_AR_RELEASE_MAJOR_VERSION    != (0x04U)) \
    || (DIO_AR_RELEASE_MINOR_VERSION    != (0x00U)) \
    || (DIO_AR_RELEASE_REVISION_VERSION != (0x03U)) )
  #error "AUTOSAR Version Numbers of Dio are different"
#endif

#if ((DIO_SW_MAJOR_VERSION != DIO_SW_C_MAJOR_VERSION) || \
     (DIO_SW_MINOR_VERSION != DIO_SW_C_MINOR_VERSION))
  #error "Version numbers of Dio.c and Dio.h are inconsistent!"
#endif

#if (  (DIO_CFG_MAJOR_VERSION != DIO_SW_C_MAJOR_VERSION) || \
       (DIO_CFG_MINOR_VERSION != DIO_SW_C_MINOR_VERSION) )
  #error "Version numbers of Dio.c and Dio_Cfg.h are inconsistent!"
#endif

/**********************************************************************************************************************
 *  LOCAL CONSTANT MACROS
 *********************************************************************************************************************/
#define DIO_REGISTER_BASE       (0xFFF70000U)

/**********************************************************************************************************************
 *  Explanation of symbolic channel and port names in Dio_ChannelCheckTable[] and Dio_PortCheckTable[];:
 **********************************************************************************************************************
 *
 * the symbolic channel name contains a value with all necessary attributes and addresses needed to
 * access a port:
 *
 *      #define SomePort   (0U)
 *      Dio_PortCheckTable[] = {0x00002e14u}
 *
 *
 * This value means (binary value):
 * --------------------------------
 *
 *
 *
 *      0b    0001 0100 0001 1010   0011 1111 1111 1111
 *            \|||||||/ \|||/ |||   || \\|||| |||| |||/
 *             ---+---   ---+ |||   || ------+--------
 *                |         | |||   ||       |
 *                |         | |||   ||       |
 *                |         | |||   ||       |
 *                |         | |||   ||       +-> port offset to the base address 0xFFF7 0000. KEEP IN MIND, that the
 *                |         | |||   ||              least two significant bits of the address are removed, since the
 *                |         | |||   ||              registers are 32bit-aligned (and the least two bits default to
 *                |         | |||   ||              zero).
 *                |         | |||   ||
 *                |         | |||   ||              The layout (mask) of the whole port offset address (including
 *                |         | |||   ||              the extension in bit 17) in the port/channel id looks like this:
 *                |         | |||   ||
 *                |         | |||   ||                  0x0002 3FFF
 *                |         | |||   ||
 *                |         | |||   ||              The real port offset can be retrieved by shifting this by two:
 *                |         | |||   ||
 *                |         | |||   ||                  0x0002 3FFF << 2          =   0x0008 FFFC
 *                |         | |||   ||
 *                |         | |||   ||              The absolute port address is calculating by OR'ing this with the
 *                |         | |||   ||              base address:
 *                |         | |||   ||
 *                |         | |||   ||                  0x0008 FFFC | 0xFFF7 0000 =   0xFFFF FFFC
 *                |         | |||   ||
 *                |         | |||   ++-> reserved for future use
 *                |         | |||
 *                |         | ||+-> indicates that the port is a CAN port
 *                |         | ||
 *                |         | |+-> indicates that the port's registers are allocated in the system module register
 *                |         | |       space. This bit is used as extension of the port offset changing the base address
 *                |         | |       from 0xFFF7 0000 to 0xFFFF 0000
 *                |         | |
 *                |         | +-> indicates that this is an ADC port (input and output registers are in reversed order)
 *                |         |
 *                |         +-> offset of the pin in the port (only in channel ids, port ids do not use these bits)
 *                |
 *                +-> channel number for checking the port against the generated tables
 *
 *
 *********************************************************************************************************************/

/* mask to get the offset address of a port (relative to the register base address -> DIO_REGISTER_BASE) */
#define DIO_MASK_PORT_OFFSET    (0x00023FFFU)

/* mask to get the pin offset in a ChannelId */
#define DIO_MASK_PIN_OFFSET     (0x00F80000U)

/* used to identify whether a port is a CAN port or a regular GIO port */
#define DIO_SHIFT_PORT_CLASS    (16U)

/* used to identify whether a port is a ADC port or a regular GIO port */
#define DIO_SHIFT_INPUT_IDX     (18U)

/* used to identify the pin offset in a ChannelId */
#define DIO_SHIFT_PIN_OFFSET    (19U)

/* shift value to get to the index against which to check in the generated arrays, whether the passed channel or
 * port ID is valid
 */
#define DIO_SHIFT_CHECKIDX      (24U)

/*To Return 0 when Improper ID is passed to Read functions*/
#define DIO_RETURN_ZERO                 0U

/**********************************************************************************************************************
 *  LOCAL FUNCTION MACROS
 *********************************************************************************************************************/
/* retrieves the absolute port address from a port or channel ID as uint32 value */
/*SAFETYMCUSW 340 S MR:19.7 <APPROVED> "Reason - To get port address" */
#define DIO_GET_PORT_ADDRESS(DIO_ID)    ( DIO_REGISTER_BASE | (((DIO_ID) & (uint32)DIO_MASK_PORT_OFFSET) << 2U) )

/* retrieves the port class from a port of channel ID (used to identify a CAN port) */
/*SAFETYMCUSW 340 S MR:19.7 <APPROVED> "Reason - To get port class" */
#define DIO_GET_PORT_CLASS(DIO_ID)      ( ((DIO_ID) >> DIO_SHIFT_PORT_CLASS) & 1U )

/* In AWM I/O ports output and input registers are swapped, but this macro always retrieves the correct idx to the
 * input register, no matter what kind of port it is (this info is encoded in the PortId and ChannelId parameters,
 * see the design specification for details)
 */
/*SAFETYMCUSW 340 S MR:19.7 <APPROVED> "Reason - To get input index" */
#define DIO_GET_INPUT_IDX(DIO_ID)       ( ((DIO_ID) >> DIO_SHIFT_INPUT_IDX) & 1U )

/* the same mechanism as for DIO_GET_INPUT_IDX(), only for the output register index. */
/*SAFETYMCUSW 340 S MR:19.7 <APPROVED> "Reason - To get output index" */
#define DIO_GET_OUTPUT_IDX(DIO_ID)      ( DIO_GET_INPUT_IDX(DIO_ID) ^ 1U )

/* retrieves the pin offset in the port from a ChannelId */
/*SAFETYMCUSW 340 S MR:19.7 <APPROVED> "Reason - To get pin offset" */
#define DIO_GET_PIN_OFFSET(CHANNEL_ID)  ( ((CHANNEL_ID) & (uint32)DIO_MASK_PIN_OFFSET) >> DIO_SHIFT_PIN_OFFSET )

/* retrieves the channel or port number used as index to check the validity of a port or channel Id in the
 * generated arrays
 */
/*SAFETYMCUSW 340 S MR:19.7 <APPROVED> "Reason - To check id" */
#define DIO_GET_CHECKIDX(DIO_ID)        ( (DIO_ID) >> DIO_SHIFT_CHECKIDX )

#if (DIO_DEV_ERROR_DETECT == STD_ON)
/* development error reporting is enabled, allow configuration of Det's include file and function call */
/*SAFETYMCUSW 580 S MR:19.1 <APPROVED> "Reason - Start of code section after declarations and Macros" */
#define Dio_ReportDet(Service, Error) /*<DIO_REPORT_DET/>*/ Det_ReportError((uint16)(DIO_MODULE_ID),\
													   (uint8)(DIO_INSTANCE_ID), (uint8)(Service), (uint8)(Error))
#else
/* development error reporting is disabled, don't use Det's reporting function */
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - Start of code section after declarations and Macros" */
#define Dio_ReportDet(Service, Error)
#endif

#define Dio_EnterCritical()         /*<DIO_CFG_ENTER_CRITICAL/>*/ SchM_Enter_Dio_DIO_EXCLUSIVE_AREA_0()
#define Dio_ExitCritical()           /*<DIO_CFG_EXIT_CRITICAL/>*/ SchM_Exit_Dio_DIO_EXCLUSIVE_AREA_0()
  
/**********************************************************************************************************************
 *  LOCAL DATA TYPES AND STRUCTURES
 *********************************************************************************************************************/
typedef struct
{
   uint32 DataInOut[2U];
   uint32 DataSetClear[2U];
} Dio_GioRegisterType;

/* type definition for accessing port registers */
typedef P2VAR(uint32, AUTOMATIC, DIO_VAR) Dio_32BitRefType;

typedef P2VAR(Dio_GioRegisterType, AUTOMATIC, DIO_VAR) Dio_GioRegisterRefType;

/**********************************************************************************************************************
 *  LOCAL FUNCTION PROTOTYPES
 *********************************************************************************************************************/
#if ((DIO_WRITE_CHANNEL_EVENT_ID != DIO_DEM_NO_EVENT) && (STD_ON == DIO_CFG_SUPPORT_GIO))
static FUNC(Dio_StatusType, DIO_CODE) Dio_IOCheck(Dio_ChannelType ChannelId, Dio_LevelType Level);
#endif
#if (((DIO_WRITE_CHANNEL_EVENT_ID != DIO_DEM_NO_EVENT) || (DIO_WRITE_PORT_EVENT_ID != DIO_DEM_NO_EVENT))\
		&& (STD_ON == DIO_CFG_SUPPORT_GIO))
static FUNC(uint32, DIO_CODE) DIO_GioGetDirection(Dio_GioRegisterRefType PortRef);
#endif
#if (STD_ON == DIO_CFG_SUPPORT_GIO)
	static FUNC(Dio_LevelType, DIO_CODE) Dio_GioReadChannel(Dio_ChannelType ChannelId, \
	   const Dio_GioRegisterRefType PortRef);
	static FUNC(void,   DIO_CODE) Dio_GioWriteChannel(uint32 ChannelId, Dio_GioRegisterRefType PortRef, \
	   Dio_LevelType Level);
	static FUNC(uint32, DIO_CODE) Dio_GioReadPort(uint32 PortId, const Dio_GioRegisterRefType PortRef);
	static FUNC(void,   DIO_CODE) Dio_GioWritePort(uint32 PortId, Dio_GioRegisterRefType PortRef, uint32 Level);
#endif
#if (STD_ON == DIO_CFG_SUPPORT_CAN)
	static FUNC(Dio_LevelType, DIO_CODE) Dio_CanReadChannel(const Dio_32BitRefType PortRef);
	static FUNC(void,   DIO_CODE) Dio_CanWriteChannel( Dio_32BitRefType PortRef, Dio_LevelType Level);
	static FUNC(uint32, DIO_CODE) Dio_CanReadPort( const Dio_32BitRefType PortRef);
	static FUNC(void,   DIO_CODE) Dio_CanWritePort( Dio_32BitRefType PortRef, uint32 Level);
#endif

/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - Start of code section after declarations and Macros" */
#define DIO_START_SEC_CODE
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#include "MemMap.h"


/**********************************************************************************************************************
 *  LOCAL FUNCTIONS
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *  GLOBAL FUNCTIONS
 *********************************************************************************************************************/
/* SourceId : DIO_SourceId_061 */
/* DesignId : Dio_DesignId_16 */
/* Requirements : AR_DIO_SR96 */
#if (STD_ON == DIO_VERSION_INFO_API)
/**********************************************************************************************************************
 * Dio_GetVersionInfo
 *********************************************************************************************************************/
/*! \brief      Version Information Service
 *
 *              This service writes the version information of this module into the data structure referenced by the
 *              parameter. If this parameter references NULL_PTR, a development error is reported to Det. This service
 *              is only available if the pre-compile configuration parameter DIO_VERSION_INFO_API is enabled.
 *
 *  \param[out] versioninfo         data structure where the version info shall be written to
 *********************************************************************************************************************/
/* SourceId : DIO_SourceId_059 */
/* DesignId : Dio_DesignId_16  */
/* Requirements : AR_DIO_SR93 */
FUNC(void, DIO_CODE)  Dio_GetVersionInfo(P2VAR(Std_VersionInfoType, AUTOMATIC, DIO_APPL_DATA) VersionInfo )
{
#if (STD_ON == DIO_DEV_ERROR_DETECT)
   /*SAFETYMCUSW 440 S MR:10.1 <APPROVED> "Reason -  Typecasted at compiler, Platform_types.h"*/
   if (NULL_PTR == VersionInfo)
   {
	  /* SourceId : DIO_SourceId_47 */
	  /* DesignId : Dio_DesignId_16 */
	  /* Requirements : AR_DIO_SR45, AR_DIO_SR97 */
      (void)Dio_ReportDet(DIO_SID_GET_VERSION_INFO, DIO_E_PARAM_POINTER);
   }
   else
   {
      /* parameter versioninfo is valid */
#endif

   VersionInfo->vendorID         = (uint16) DIO_VENDOR_ID;
   VersionInfo->moduleID         = (uint16) DIO_MODULE_ID;
   VersionInfo->sw_major_version = (uint8)  DIO_SW_MAJOR_VERSION;
   VersionInfo->sw_minor_version = (uint8)  DIO_SW_MINOR_VERSION;
   VersionInfo->sw_patch_version = (uint8)  DIO_SW_PATCH_VERSION;

#if (STD_ON == DIO_DEV_ERROR_DETECT)
   }
#endif
} /* End of Dio_GetVersionInfo() */
#endif /*(STD_ON == DIO_VERSION_INFO_API)*/

/**********************************************************************************************************************
 * Dio_ReadChannel
 *********************************************************************************************************************/
/*! \brief      Read out a DIO channel
 *
 *              This function reads out the value of the referenced DIO channel (port pin).
 *
 *  \param[in]  ChannelId       ChannelId representing the port pin to read from
 *
 *  \return     Level of the DIO channel
 *
 *  \context    The function can be called on interrupt and task level.
 *********************************************************************************************************************/
/* SourceId : DIO_SourceId_021 */
/* DesignId : Dio_DesignId_10  */
/* Requirements : AR_DIO_SR34, AR_DIO_SR71 */
FUNC(Dio_LevelType, DIO_CODE) Dio_ReadChannel(Dio_ChannelType ChannelId)
{

   uint32 ChannelInfo = 1U;
   uint32 PortClass;
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - Port reference structure inspected" */
   Dio_GioRegisterRefType PortRef;

   /* SourceId : DIO_SourceId_014 */
   /* DesignId : Dio_DesignId_10  */
   /* Requirements : AR_DIO_SR33 */
   Dio_LevelType Return_Value = (Dio_LevelType) DIO_RETURN_ZERO;
   
   /* SourceId : DIO_SourceId_040 */
   /* DesignId : Dio_DesignId_10  */
   /* Requirements : AR_DIO_SR41 */
#if (STD_ON == DIO_DEV_ERROR_DETECT)
   if( MAX_NO_OF_CHANNELS <= ChannelId )
   {
      (void)Dio_ReportDet(DIO_SID_READ_CHANNEL, DIO_E_PARAM_INVALID_CHANNEL_ID);
   }
   else
#endif
   {
      ChannelInfo = Dio_ChannelCheckTable[ChannelId];
	  /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - Port reference structure inspected" */
      PortRef = (Dio_GioRegisterRefType) DIO_GET_PORT_ADDRESS(ChannelInfo);
   
  
   /* in case both GIO and CAN ports is supported by configuration, the necessary function is selected by
    * the CanPin field in the Channel-parameter. If only one of GIO or CAN ports is supported, the other
    * function is removed by compiler switches
    */
		PortClass = DIO_GET_PORT_CLASS(ChannelInfo);
		/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason - Inspected, comparing TRUE or FALSE"*/
		if (PortClass == 0U)
		{
#if (STD_ON == DIO_CFG_SUPPORT_GIO)
			Return_Value = Dio_GioReadChannel(ChannelId, PortRef);/*Normal GIO*/
#endif
		}
		else
		{
#if (STD_ON == DIO_CFG_SUPPORT_CAN)
			/*SAFETYMCUSW 95 S MR:11.1 <APPROVED> "Reason - To access the CAN port which is of type uint32" */
			/*SAFETYMCUSW 94 S MR:11.1 <APPROVED> "Reason - To access the CAN port which is of type uint32" */
			/*SAFETYMCUSW 94 S MR:11.1, 11.2, 11.4 <APPROVED> "Reason - Casting is required here "*/
			/*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
			Return_Value = Dio_CanReadChannel((Dio_32BitRefType)PortRef);/*Can*/
#endif
		}

   }
	return Return_Value;
}
/**********************************************************************************************************************
 * Dio_GioReadChannel
**********************************************************************************************************************/
/*! \brief      Read out a GIO channel
                This function reads out the value of the referenced GIO channel (port pin).
 *  \param[in]  ChannelId       ChannelId representing the port pin to read from
 *  \return     Level of the GIO channel
 *  \context    This function is called from Dio_ReadChannel
 *********************************************************************************************************************/

#if (STD_ON == DIO_CFG_SUPPORT_GIO)
   static FUNC(Dio_LevelType, DIO_CODE)Dio_GioReadChannel(Dio_ChannelType ChannelId, \
      const Dio_GioRegisterRefType PortRef)
{
    uint32 ChannelInfo = Dio_ChannelCheckTable[ChannelId];
    Dio_LevelType Return_Value = 0U;

	uint32 PortPin    = DIO_GET_PIN_OFFSET(ChannelInfo);
	uint32 InSelector = DIO_GET_INPUT_IDX(ChannelInfo);

	/* ADEVT ports have GIODIN and GIODOUT in reversed order, hence the InSelector selects
	* the correct register for reading
	*/
	Return_Value = (Dio_LevelType)(( (uint32) PortRef->DataInOut[InSelector] >> PortPin ) & 1U);
   return Return_Value;
}
#endif /*(STD_ON == DIO_CFG_SUPPORT_GIO)*/
/**********************************************************************************************************************
 * Dio_CanReadChannel
 *********************************************************************************************************************/
/*! \brief      Read out a CAN channel
 *              This function reads out the value of the referenced CAN channel (port pin).
 *  \param[in]  PortRef - Absolute address of the CAN port
 *  \Return     Level of the CAN channel 
 *  \context    This function is called from Dio_ReadChannel
 *********************************************************************************************************************/

#if (STD_ON == DIO_CFG_SUPPORT_CAN)
   static FUNC(Dio_LevelType, DIO_CODE) Dio_CanReadChannel(const Dio_32BitRefType PortRef)
   {
	   Dio_LevelType Return_Value = 0U;
      /* a can port only has one I/O pin, where the data input register is located at bit position 0 */
	   Return_Value = (Dio_LevelType)(*PortRef & 1U);
	   return Return_Value;
}
#endif /*(STD_ON == DIO_CFG_SUPPORT_CAN)*/

/**********************************************************************************************************************
 * Dio_WriteChannel
 *********************************************************************************************************************/
/*! \brief      Write a value to a DIO channel
 *
 *              This function writes the value to the referenced DIO channel (port pin).
 *
 *  \param[in]  ChannelId       ChannelId representing the port pin to write to
 *  \param[in]  Level           Level to apply to the channel
 *
 *  \context    The function can be called on interrupt and task level.
 *********************************************************************************************************************/
/* SourceId : DIO_SourceId_011 */
/* DesignId : Dio_DesignId_11  */
/* Requirements : AR_DIO_SR28, AR_DIO_SR72 */
FUNC(void, DIO_CODE) Dio_WriteChannel(Dio_ChannelType ChannelId, Dio_LevelType Level)
{
   uint32 ChannelInfo = 1U;
   uint32 PortClass;
   /*SAFETYMCUSW 95 S MR:11.1 <APPROVED> "Reason - To access Gio Registers of type Dio_GioRegisterRefType "*/
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - Port reference structure inspected" */
   Dio_GioRegisterRefType PortRef;
#if (STD_ON == DIO_DEV_ERROR_DETECT)
   /* SourceId : DIO_SourceId_041 */
   /* DesignId : Dio_DesignId_11  */
   /* Requirements : AR_DIO_SR41 */
   if( MAX_NO_OF_CHANNELS <= ChannelId )
   {
      /* ChannelId is NOT valid */
      (void)Dio_ReportDet(DIO_SID_WRITE_CHANNEL, DIO_E_PARAM_INVALID_CHANNEL_ID);
   }
   /* SourceId : DIO_SourceId_010 */
   /* DesignId : Dio_DesignId_11  */
   /* Requirements : AR_DIO_SR27 */
   else
#endif
   {
        ChannelInfo = Dio_ChannelCheckTable[ChannelId];
        /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - Port reference structure inspected" */
        PortRef = (Dio_GioRegisterRefType) DIO_GET_PORT_ADDRESS(ChannelInfo);
	
		/* in case both GIO and CAN ports is supported by configuration, the necessary function is selected by
		* the CanPin field in the Channel-parameter. If only one of GIO or CAN ports is supported, the other
		* function is removed by compiler switches
		*/
		PortClass = DIO_GET_PORT_CLASS(ChannelInfo);
		/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason - Inspected, comparing TRUE or FALSE"*/
		if(PortClass == 0U) /*Normal GIO*/
		{
#if (STD_ON == DIO_CFG_SUPPORT_GIO)
			Dio_GioWriteChannel(ChannelId, PortRef,Level);
#endif
		}
		else
		{
#if (STD_ON == DIO_CFG_SUPPORT_CAN)
			/*SAFETYMCUSW 95 S MR:11.1 <APPROVED> "Reason -To access the CAN port of type uint32"*/
			/*SAFETYMCUSW 94 S MR:11.1 <APPROVED> "Reason -To access the CAN port of type uint32"*/
			/*SAFETYMCUSW 94 S MR:11.1, 11.2, 11.4 <APPROVED> "Reason - Casting is required here "*/
			/*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
			Dio_CanWriteChannel((Dio_32BitRefType)PortRef,Level);
#endif
		}
   }
}
/**********************************************************************************************************************
 * Dio_GioWriteChannel - Writes the value of level to referenced ChannelID
 *********************************************************************************************************************/
/*! \brief      Write a value to a GIO channel
 *              This function writes the value to the referenced GIO channel (port pin).
 *  \param[in]  ChannelId       ChannelId representing the port pin to write to
 *  \param[in]  Level           Level to apply to the channel
 *  \context    The function can be called from Dio_DioWriteChannel.
 *********************************************************************************************************************/

#if (STD_ON == DIO_CFG_SUPPORT_GIO)
static FUNC(void, DIO_CODE) Dio_GioWriteChannel(uint32 ChannelId, Dio_GioRegisterRefType PortRef, Dio_LevelType Level)
{
	  uint32 ChannelInfo = Dio_ChannelCheckTable[ChannelId];
      uint32 PortPin = DIO_GET_PIN_OFFSET(ChannelInfo);
      /* SourceId : DIO_SourceId_031 */
      /* DesignId : Dio_DesignId_22  */
      /* Requirements : AR_DIO_SR12 */
      Dio_EnterCritical();
      /* Level ^ 1      -->> SET-Register is located at index 0, CLEAR-Register is located at index 1
       *                -->> STD_HIGH is 1 (1 should be set at index 0 to set the bit)
       *                -->> STD_LOW  is 0 (1 should be set at index 1 to clear the bit)
       */
      /*SAFETYMCUSW 95 S MR:11.1 <APPROVED> "Reason - To access Gio Registers of type Dio_GioRegisterRefType"*/
      /*SAFETYMCUSW 94 S MR:11.1 <APPROVED> "Reason - Needed to access PortRef"*/
      ((Dio_GioRegisterRefType) PortRef)->DataSetClear[Level ^ 1u] = (uint32) 1u << PortPin;
      /* SourceId : DIO_SourceId_032 */
      /* DesignId : Dio_DesignId_22  */
      /* Requirements : AR_DIO_SR12 */
      Dio_ExitCritical();

#if (DIO_WRITE_CHANNEL_EVENT_ID != DIO_DEM_NO_EVENT)
      /*If the channel is not configured as input, IO check*/
      if((DIO_GioGetDirection(PortRef) & (1U<<PortPin)) != 0U){
    	  if(E_NOT_OK == Dio_IOCheck(ChannelId,Level)){
    		  Dem_ReportErrorStatus((Dem_EventIdType)DIO_WRITE_CHANNEL_EVENT_ID, (uint8)DEM_EVENT_STATUS_FAILED);
    	  }
      }
#endif
}
#endif /*(STD_ON == DIO_CFG_SUPPORT_GIO)*/
/**********************************************************************************************************************
 * Dio_CanWriteChannel
 *********************************************************************************************************************/
/*! \brief      Write a value to a CAN channel
 *              This function writes the value to the referenced CAN channel (port pin).
 *  \param[in]  ChannelId       ChannelId representing the port pin to write to
 *  \param[in]  Level           Level to apply to the channel
 *  \context    The function can be called from Dio_DioWriteChannel.
 *********************************************************************************************************************/

#if (STD_ON == DIO_CFG_SUPPORT_CAN)
static FUNC(void, DIO_CODE) Dio_CanWriteChannel( Dio_32BitRefType PortRef, Dio_LevelType Level)
{
	/* SourceId : DIO_SourceId_006 */
	/* DesignId : Dio_DesignId_26  */
	/* Requirements : AR_DIO_SR12 */
	Dio_EnterCritical();
	/* a can port only has one I/O pin, where the data output register is located at bit position 1 */
	*PortRef = (*PortRef & 0xFFFFFFFDU) | ((Level << 1U) & 2U);
	/* SourceId : DIO_SourceId_024 */
	/* DesignId : Dio_DesignId_26  */
	/* Requirements : AR_DIO_SR12 */
	Dio_ExitCritical();
	/* Safety feature*/
#if (DIO_WRITE_CHANNEL_EVENT_ID != DIO_DEM_NO_EVENT)
	/* If CAN channel configured as output only, check IO value */
	if((((*PortRef) >> 2U) & 1U) != 0U){
		if(Level != Dio_CanReadChannel(PortRef)){
			Dem_ReportErrorStatus((Dem_EventIdType)DIO_WRITE_CHANNEL_EVENT_ID, (uint8)DEM_EVENT_STATUS_FAILED);
		}
	}
#endif
}
#endif

/**********************************************************************************************************************
 * Dio_ReadPort
 *********************************************************************************************************************/
/*! \brief      Read out a DIO port
 *
 *              This function reads out the value of the referenced DIO port.
 *
 *  \param[in]  PortId - PortId representing the port to read from
 *
 *  \return     Level of the DIO port
 *
 *  \context    The function can be called on interrupt and task level.
 *********************************************************************************************************************/
/* SourceId : DIO_SourceId_035 */
/* DesignId : Dio_DesignId_12  */
/* Requirements : AR_DIO_SR35, AR_DIO_SR76, AR_DIO_SR78 */
FUNC(Dio_PortLevelType, DIO_CODE) Dio_ReadPort(Dio_PortType PortId)
{
   /* SourceId : DIO_SourceId_016 */
   /* DesignId : Dio_DesignId_12  */
   /* Requirements : AR_DIO_SR33  */
   Dio_PortLevelType Return_Value = DIO_RETURN_ZERO;
   uint32 PortClass;
   /*SAFETYMCUSW 95 S MR:11.1 <APPROVED> "Reason - To access Gio Registers of type Dio_GioRegisterRefType "*/
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - Port reference structure inspected" */
   Dio_GioRegisterRefType PortRef;
   uint32 PortInfo = 1U;

   /* SourceId : DIO_SourceId_042 */
   /* DesignId : Dio_DesignId_12  */
   /* Requirements : AR_DIO_SR42  */
   
#if (STD_ON == DIO_DEV_ERROR_DETECT)
   if( MAX_NO_OF_PORTS <= PortId )
   {
	   /* PortId is NOT valid */
      (void)Dio_ReportDet(DIO_SID_READ_PORT, DIO_E_PARAM_INVALID_PORT_ID);
   }
   else
#endif
   {
         PortInfo = Dio_PortCheckTable[PortId];
         /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - Port reference structure inspected" */
         PortRef = (Dio_GioRegisterRefType) DIO_GET_PORT_ADDRESS(PortInfo);

		/* in case both GIO and CAN ports is supported by configuration, the necessary function is selected by
		* the CanPin field in the Channel-parameter. If only one of GIO or CAN ports is supported, the other
		* function is removed by compiler switches
		*/
		PortClass = DIO_GET_PORT_CLASS(PortInfo);
		/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason - Inspected, comparing TRUE or FALSE"*/
		if(PortClass == 0U) /*Normal GIO*/
		{
#if (STD_ON == DIO_CFG_SUPPORT_GIO)
			Return_Value = (Dio_PortLevelType) Dio_GioReadPort(PortId, PortRef);
#endif
		}
		else
		{
#if (STD_ON == DIO_CFG_SUPPORT_CAN)
			/*SAFETYMCUSW 95 S MR:11.1 <APPROVED> "Reason - To access the CAN port type uint32"*/
			/*SAFETYMCUSW 94 S MR:11.1 <APPROVED> "Reason - To access the CAN port type uint32"*/
			/*SAFETYMCUSW 94 S MR:11.1, 11.2, 11.4 <APPROVED> "Reason - Casting is required here "*/
			/*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
			Return_Value = (Dio_PortLevelType) Dio_CanReadPort((Dio_32BitRefType)PortRef);
#endif
		}

	}
	return Return_Value;
}

/**********************************************************************************************************************
 * Dio_GioReadPort
 *********************************************************************************************************************/
/*! \brief      Read out a GIO port
 *              This function reads out the value of the referenced DIO port.
 *  \param[in]  PortId - PortId representing the port to read from
 *  \param[in]  PortRef - Address of the referenced Port
 *  \return     Level of the GIO port
 *  \context    The function is called from Dio_ReadPort.
 *********************************************************************************************************************/

#if (STD_ON == DIO_CFG_SUPPORT_GIO)
   static FUNC(uint32, DIO_CODE) Dio_GioReadPort(uint32 PortId, const Dio_GioRegisterRefType PortRef)
{
    uint32 PortInfo = Dio_PortCheckTable[PortId];
    uint32 Return_Value = 0U;
    uint32 InSelector = DIO_GET_INPUT_IDX(PortInfo);
    /* ADEVT ports have GIODIN and GIODOUT in reversed order, hence the InSelector selects
    * the correct register for reading
    */
    Return_Value = PortRef->DataInOut[InSelector];
	return Return_Value;
}
#endif /*(DIO_CFG_SUPPORT_GIO == STD_ON)*/
/**********************************************************************************************************************
 * Dio_CanReadPort
 *********************************************************************************************************************/
/*! \brief      Read out a CAN port
 *              This function reads out the value of the referenced CAN port.
 *  \param[in]  PortRef - Address of the referenced CAN Port
 *  \return     Level of the CAN port
 *  \context    The function is called from Dio_ReadPort.
 *********************************************************************************************************************/
#if (STD_ON == DIO_CFG_SUPPORT_CAN)
   static FUNC(uint32, DIO_CODE) Dio_CanReadPort(const Dio_32BitRefType PortRef)
   {
    uint32 Return_Value = 0U;
	Return_Value = *PortRef & 1U;
	/* a can port only has one I/O pin, where the data input register is located at bit position 0 */
	return Return_Value;
}
#endif /*(STD_ON == DIO_CFG_SUPPORT_CAN)*/

/**********************************************************************************************************************
 * Dio_WritePort
 *********************************************************************************************************************/
/*! \brief      Write a value to a DIO port
 *
 *              This function writes the value to the referenced DIO port.
 *
 *  \param[in]  PortId          PortId representing the port pin to write to
 *  \param[in]  Level           Level to apply to the port
 *
 *  \context    The function can be called on interrupt and task level.
 *********************************************************************************************************************/
/* SourceId : DIO_SourceId_012 */
/* DesignId : Dio_DesignId_13  */
/* Requirements : AR_DIO_SR29, AR_DIO_SR79,AR_DIO_SR83 */
FUNC(void, DIO_CODE) Dio_WritePort(Dio_PortType PortId, Dio_PortLevelType Level)
{
   uint32 PortInfo = 1U;
   /*SAFETYMCUSW 95 S MR:11.1 <APPROVED> "Reason - To access Gio Registers of type Dio_GioRegisterRefType "*/
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - Port reference structure inspected" */
   Dio_GioRegisterRefType PortRef;
   uint32 PortClass;
#if (STD_ON == DIO_DEV_ERROR_DETECT)
   /* SourceId : DIO_SourceId_043 */
   /* DesignId : Dio_DesignId_13  */
   /* Requirements : AR_DIO_SR42 */
   if( MAX_NO_OF_PORTS <= PortId )
   {
	   /* PortId is NOT valid */
	   /* SourceId : DIO_SourceId_023 */
       /* DesignId : Dio_DesignId_13  */
       /* Requirements : AR_DIO_SR27 */
      (void)Dio_ReportDet(DIO_SID_WRITE_PORT, DIO_E_PARAM_INVALID_PORT_ID);
   }
   else
#endif
   {
	    PortInfo = Dio_PortCheckTable[PortId];
        /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - Port reference structure inspected" */
        PortRef = (Dio_GioRegisterRefType) DIO_GET_PORT_ADDRESS(PortInfo);
	    /* in case both GIO and CAN ports is supported by configuration, the necessary function is selected by
		* the CanPin field in the Channel-parameter. If only one of GIO or CAN ports is supported, the other
		* function is removed by compiler switches
		*/
		PortClass = DIO_GET_PORT_CLASS(PortInfo);
		/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason - Inspected, comparing TRUE or FALSE"*/
		if(PortClass == 0U) /*Normal GIO*/
		{
#if (STD_ON == DIO_CFG_SUPPORT_GIO)
			Dio_GioWritePort(PortId, PortRef, Level);
#endif
		}
		else
		{
#if (STD_ON == DIO_CFG_SUPPORT_CAN)
			/*SAFETYMCUSW 95 S MR:11.1 <APPROVED> "Reason - To access the CAN port of type uint32 "*/
			/*SAFETYMCUSW 94 S MR:11.1 <APPROVED> "Reason - To access the CAN port of type uint32 "*/
			Dio_CanWritePort((Dio_32BitRefType)PortRef, Level);
#endif
		}
	}
}
/**********************************************************************************************************************
 * Dio_GioWritePort
 *********************************************************************************************************************/
/*! \brief      Write a value to a GIO port
 *              This function writes the value to the referenced GIO port.
 *  \param[in]  PortId          PortId representing the port pin to write to
 *  \param[in]  Level           Level to apply to the port
 *  \param[in]  PortRef         Address of the referenced Port.
 *  \context    The function can be called on interrupt and task level.
 *********************************************************************************************************************/
#if (STD_ON == DIO_CFG_SUPPORT_GIO)
static FUNC(void, DIO_CODE) Dio_GioWritePort(uint32 PortId, Dio_GioRegisterRefType PortRef, uint32 Level)
{
	  uint32 PortInfo = Dio_PortCheckTable[PortId];
      uint32 outSelector = DIO_GET_OUTPUT_IDX(PortInfo);
#if (DIO_WRITE_PORT_EVENT_ID != DIO_DEM_NO_EVENT)
	uint32 direction = DIO_GioGetDirection(PortRef);
#endif
	 /* ADEVT ports have GIODIN and GIODOUT in reversed order, hence the outSelector selects
	  * the correct register for writing
	  */
	 /* SourceId : DIO_SourceId_033 */
     /* DesignId : Dio_DesignId_27 */
	 /* Requirements : AR_DIO_SR12 */
	 Dio_EnterCritical();
	 PortRef->DataInOut[outSelector] = Level;
	 /* SourceId : DIO_SourceId_034 */
	 /* DesignId : Dio_DesignId_27 */
	 /* Requirements : AR_DIO_SR12 */
	 Dio_ExitCritical();

#if (DIO_WRITE_PORT_EVENT_ID != DIO_DEM_NO_EVENT)
	/*If a channel is not configured as input only, do IO check*/
	if((Level & direction) != Dio_GioReadPort(PortId,PortRef)){
	  Dem_ReportErrorStatus((Dem_EventIdType)DIO_WRITE_PORT_EVENT_ID, (uint8)DEM_EVENT_STATUS_FAILED);
	}
#endif
}
#endif /*(STD_ON == DIO_CFG_SUPPORT_GIO)*/
/**********************************************************************************************************************
 * Dio_CanWritePort
 *********************************************************************************************************************/
/*! \brief      Write a value to a CAN port
 *              This function writes the value to the referenced GIO port.
 *  \param[in]  Level           Level to apply to the port
 *  \param[in]  PortRef         Address of the referenced Port.
 *  \context    The function is called from Dio_WritePort.
 *********************************************************************************************************************/
#if (STD_ON == DIO_CFG_SUPPORT_CAN)
   static FUNC(void, DIO_CODE) Dio_CanWritePort(Dio_32BitRefType PortRef, uint32 Level)
   {
   /* SourceId : DIO_SourceId_027 */
   /* DesignId : Dio_DesignId_28 */
   /* Requirements : AR_DIO_SR12 */
   Dio_EnterCritical();
   /* a can port only has one I/O pin, where the data output register is located at bit position 1 */
   *PortRef = (*PortRef & 0xFFFFFFFDU) | ((Level << 1U) & 2U);
   /* SourceId : DIO_SourceId_028 */
   /* DesignId : Dio_DesignId_28 */
   /* Requirements : AR_DIO_SR12 */
   Dio_ExitCritical();
   /* Safety feature */
#if (DIO_WRITE_PORT_EVENT_ID != DIO_DEM_NO_EVENT)
	/* If CAN channel configured as output only, check IO value */
	if((((*PortRef) >> 2U) & 1U) != 0U){
		if(Level != Dio_CanReadChannel(PortRef)){
		  Dem_ReportErrorStatus((Dem_EventIdType)DIO_WRITE_PORT_EVENT_ID, (uint8)DEM_EVENT_STATUS_FAILED);
		}
	}
#endif
}
#endif /*(DIO_CFG_SUPPORT_CAN == STD_ON)*/

/**********************************************************************************************************************
 * Dio_ReadChannelGroup
 *********************************************************************************************************************/
/*! \brief      Reads a value from a DIO channel group
 *
 *              This function reads the value of a port and shifts/masks out the information not relevant in that
 *              a channel group.
 *
 *  \param[in]  ChannelGroupIdPtr   reference to the channel group (created by configuration)
 *
 *  \return      value of the according channel group (shifted to read from offset 0)
 *
 *  \context    The function can be called on interrupt and task level.
 *********************************************************************************************************************/
/* SourceId : DIO_SourceId_036 */
/* DesignId : Dio_DesignId_14  */
/* Requirements : AR_DIO_SR36, AR_DIO_SR84, AR_DIO_SR85 */
FUNC(Dio_PortLevelType, DIO_CODE) Dio_ReadChannelGroup(Dio_ChannelGroupRefType ChannelGroupIdPtr)
{
   Dio_PortLevelType Return_Value = DIO_RETURN_ZERO;
#if (STD_ON == DIO_DEV_ERROR_DETECT)
   uint32 PortId;

   /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason -  Comes from compiler"*/
   uint8 Dev_Error_Flag = FALSE;
   /* SourceId : DIO_SourceId_045 */
   /* DesignId : Dio_DesignId_14 */
   /* Requirements : AR_DIO_SR43 */
   /*SAFETYMCUSW 440 S MR:10.1 <APPROVED> "Reason -  Typecasted at compiler, Platform_types.h"*/
   if (NULL_PTR == ChannelGroupIdPtr)
   {
      /* null pointer is referenced by the parameter */
      (void)Dio_ReportDet(DIO_SID_READ_CHL_GROUP, DIO_E_PARAM_INVALID_GROUP);
      /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason -  Comes from compiler"*/
      Dev_Error_Flag = TRUE;
      /* SourceId : DIO_SourceId_015 */
      /* DesignId : Dio_DesignId_14 */
      /* Requirements : AR_DIO_SR33 */
   }
   else
   {
      PortId = ChannelGroupIdPtr->port;
      if (Dio_PortCheckTable[DIO_GET_CHECKIDX(PortId)] != PortId)
      {
         /* PortId is NOT valid */
         (void)Dio_ReportDet(DIO_SID_READ_CHL_GROUP, DIO_E_PARAM_INVALID_GROUP);
         /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason -  Comes from compiler"*/
         Dev_Error_Flag = TRUE;
      }
   }
   /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason -  Comes from compiler"*/
   /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason - Inspected, comparing TRUE or FALSE"*/
   if(FALSE == Dev_Error_Flag)
#endif
   {
      Return_Value   = Dio_ReadPort(DIO_GET_CHECKIDX(ChannelGroupIdPtr->port));
      /* SourceId : DIO_SourceId_056 */
      /* DesignId : Dio_DesignId_14 */
      /* Requirements : AR_DIO_SR86 */
      Return_Value  &= ChannelGroupIdPtr->mask;
      /* SourceId : DIO_SourceId_057 */
      /* DesignId : Dio_DesignId_14 */
	  /* Requirements : AR_DIO_SR87 */
      Return_Value >>= ChannelGroupIdPtr->offset;
   }
   return Return_Value;
}

/**********************************************************************************************************************
 * Dio_WriteChannelGroup
 *********************************************************************************************************************/
/*! \brief      writes a value to a DIO channel group
 *
 *              This function shifts/masks out the information not relevant in that channel group and
 *              writes the value to a port.
 *
 *  \param[in]  ChannelGroupIdPtr   reference to the channel group (created by configuration)
 *  \param[in]  Level               level to write to the port group
 *
 *  \context    The function can be called on interrupt and task level.
 *********************************************************************************************************************/
/* SourceId : DIO_SourceId_013 */
/* DesignId : Dio_DesignId_15  */
/* Requirements : AR_DIO_SR31, AR_DIO_SR88, AR_DIO_SR89 */
FUNC(void, DIO_CODE) Dio_WriteChannelGroup(Dio_ChannelGroupRefType ChannelGroupIdPtr, Dio_PortLevelType Level)
{
   uint32 PortValue;
   uint32 newValue;
   uint8 Groupoffset = 0U;

#if (STD_ON == DIO_DEV_ERROR_DETECT)
   /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason -  Comes from compiler"*/
   uint8 Dev_Error_Flag = FALSE;
   Dio_PortType PortId;

   /* SourceId : DIO_SourceId_044 */
   /* DesignId : Dio_DesignId_15  */
   /* Requirements : AR_DIO_SR43 */
   /*SAFETYMCUSW 440 S MR:10.1 <APPROVED> "Reason -  Typecasted at compiler, Platform_types.h"*/
   if (NULL_PTR == ChannelGroupIdPtr)
   {
      /* null pointer is referenced by the parameter */
      (void)Dio_ReportDet(DIO_SID_WRITE_CHL_GROUP, DIO_E_PARAM_INVALID_GROUP);
      /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason -  Comes from compiler"*/
      Dev_Error_Flag = TRUE;
   }
   else
   {
      PortId = ChannelGroupIdPtr->port;
      if (Dio_PortCheckTable[DIO_GET_CHECKIDX(PortId)] != PortId)
      {
         /* PortId is NOT valid */
         (void)Dio_ReportDet(DIO_SID_WRITE_CHL_GROUP, DIO_E_PARAM_INVALID_GROUP);
         /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason -  Comes from compiler"*/
         Dev_Error_Flag = TRUE;
      }
   }

   /* SourceId : DIO_SourceId_022 */
   /* DesignId : Dio_DesignId_15  */
   /* Requirements : AR_DIO_SR27 */
   /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason -  Comes from compiler"*/
   /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason - Inspected, comparing TRUE or FALSE"*/
   if(FALSE == Dev_Error_Flag)
#endif
   {
      Groupoffset = ChannelGroupIdPtr->offset;
      /* SourceId : DIO_SourceId_058 */
      /* DesignId : Dio_DesignId_15  */
      /* Requirements : AR_DIO_SR91, AR_DIO_SR91 */
      newValue  = ((Level << Groupoffset) & ChannelGroupIdPtr->mask);
      PortValue = Dio_ReadPort(DIO_GET_CHECKIDX(ChannelGroupIdPtr->port));

      /* clear old value of this channel group and apply new levels */
      PortValue = (PortValue) & (~ChannelGroupIdPtr->mask);
      PortValue = (PortValue | newValue);
      Dio_WritePort(DIO_GET_CHECKIDX(ChannelGroupIdPtr->port), PortValue);
   }
}

#if (STD_ON == DIO_FLIP_CHANNEL_API)
/**********************************************************************************************************************
 * Dio_FlipChannel
 *********************************************************************************************************************/
/*! \brief      Filps a value of a DIO channel
 *
 *              This function flips the value of the referenced DIO channel (port pin).
 *              It will write 1 to a channel if the original value is 0 and vice versa.
 *
 *  \param[in]  ChannelId       ChannelId representing the port pin to flip
 *  \return     Level of the DIO channel
 *
 *  \context    The function can be called on interrupt and task level.
 *********************************************************************************************************************/
/* SourceId : DIO_SourceId_063 */
/* DesignId : Dio_DesignId_18  */
/* Requirements : AR_DIO_SR101 */
FUNC(Dio_LevelType, DIO_CODE) Dio_FlipChannel(Dio_ChannelType ChannelId)
{
   Dio_LevelType Return_Value = DIO_RETURN_ZERO;
   Dio_LevelType Flip_Value = DIO_RETURN_ZERO;

#if (STD_ON == DIO_DEV_ERROR_DETECT)
   /* SourceId : DIO_SourceId_037 */
   /* DesignId : Dio_DesignId_18  */
   /* Requirements : AR_DIO_SR27 */
   if(MAX_NO_OF_CHANNELS <= ChannelId )
   {
      /* ChannelId is NOT valid */
      (void)Dio_ReportDet(DIO_SID_FLIP_CHANNEL, DIO_E_PARAM_INVALID_CHANNEL_ID);
   }
   else
#endif
   {
      /*Read the channel value*/
      Flip_Value = Dio_ReadChannel(ChannelId);
      /*Check if the level is logic HIGH, store the inverted level*/
      if(STD_HIGH == Flip_Value)
      {
    	 /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason -  Comes from compiler"*/
         Flip_Value = (Dio_LevelType)STD_LOW;
      }
      else
      {
    	 /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason -  Comes from compiler"*/
         Flip_Value = (Dio_LevelType)STD_HIGH;
      }
      /*Write back the inverted level value*/
      /* SourceId : DIO_SourceId_064 */
      /* DesignId : Dio_DesignId_18  */
      /* Requirements : AR_DIO_SR102 */
      Dio_WriteChannel(ChannelId,Flip_Value);
      /*Update the return value*/
      Return_Value = Dio_ReadChannel(ChannelId);
   }
  return Return_Value;
}
#endif /*(STD_ON == DIO_FLIP_CHANNEL_API)*/

#if ((DIO_WRITE_CHANNEL_EVENT_ID != DIO_DEM_NO_EVENT)\
                     && (STD_ON == DIO_CFG_SUPPORT_GIO))
/**********************************************************************************************************************
 * Dio_IOCheck
 *********************************************************************************************************************/
/*! \brief      Checks if the received level value is same as written value
 *
 *  \param[in]  ChannelId       ChannelId representing the port pin to flip
 *  \return     Level of the DIO channel
 *
 *  \context    The function can be called from application.
 *********************************************************************************************************************/
/* SourceId : DIO_SourceId_069 */
/* DesignId : Dio_DesignId_19  */
/* Requirements : AR_DIO_SR120 */
static FUNC(Dio_StatusType, DIO_CODE) Dio_IOCheck(Dio_ChannelType ChannelId, Dio_LevelType Level)
{
   Dio_LevelType New_Level = DIO_RETURN_ZERO;
   /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason -  Comes from compiler"*/
   Dio_StatusType Status = E_OK;

   New_Level = Dio_ReadChannel(ChannelId);
   if(Level != New_Level)
   {
	   /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason -  Comes from compiler"*/
	   Status = E_NOT_OK;
   }
   return Status;
}
#endif
/**********************************************************************************************************************
 * Dio_Init
 *********************************************************************************************************************/
/*! \brief      Dummy Init Function.
 *
 *              All required initialization already being performed by Port driver.
 *
 *  \param[in]  ConfigPtr       Pointer to post-build configuration data.
 *
 *  \context
 *********************************************************************************************************************/
/* SourceId : DIO_SourceId_055 */
/* DesignId : Dio_DesignId_17  */
/* Requirements : AR_DIO_SR68, AR_DIO_SR98 */
FUNC(void, DIO_CODE) Dio_Init(P2CONST( Dio_ConfigType, AUTOMATIC, DIO_PBCFG) ConfigPtr )
{
   /* SourceId : DIO_SourceId_062 */
   /* DesignId : Dio_DesignId_17  */
   /* Requirements : AR_DIO_SR100 */
   /*SAFETYMCUSW 440 S MR:10.1 <APPROVED> "Reason -  Typecasted at compiler, Platform_types.h"*/
   if (NULL_PTR == ConfigPtr)
   {
#if (STD_ON == DIO_DEV_ERROR_DETECT)
      /* ChannelId is NOT valid */
      (void)Dio_ReportDet(DIO_SID_INIT, DIO_E_PARAM_CONFIG);
#endif
   }

}
#if (((DIO_WRITE_CHANNEL_EVENT_ID != DIO_DEM_NO_EVENT) || (DIO_WRITE_PORT_EVENT_ID != DIO_DEM_NO_EVENT))\
		&& (STD_ON == DIO_CFG_SUPPORT_GIO))
/**********************************************************************************************************************
* DIO_GioGetDirection - Gets the direction register value for the port
*********************************************************************************************************************/
static FUNC(uint32, DIO_CODE) DIO_GioGetDirection(Dio_GioRegisterRefType PortRef){
	/*SAFETYMCUSW 95 S MR:11.1 <APPROVED> "Reason - To access direction of the port"*/
	/*SAFETYMCUSW 94 S MR:11.1 <APPROVED> "Reason - To access direction of the port"*/
	/*SAFETYMCUSW 94 S MR:11.1, 11.2, 11.4 <APPROVED> "Reason - Casting is required here "*/
	/*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
	uint32* direction = (uint32*)PortRef;
	direction -= 1U;
	/* The above statement gives the Direction Register */
	return *direction;
}
#endif
/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#define DIO_STOP_SEC_CODE
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#include "MemMap.h"

/**********************************************************************************************************************
 *  END OF FILE: Dio.c
 *********************************************************************************************************************/
