/**
  ******************************************************************************
  * @file    stm32wbxx_hal_ipcc.c
  * @author  MCD Application Team
  * @brief   IPCC HAL module driver.
  *          This file provides firmware functions to manage the following
  *          functionalities of the Inter-Processor communication controller
  *          peripherals (IPCC).
  *           + Initialization and de-initialization functions
  *           + Configuration, notification and interrupts handling
  *           + Peripheral State and Error functions
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2019 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  @verbatim
  ==============================================================================
                        ##### How to use this driver #####
  ==============================================================================
    [..]
      The IPCC HAL driver can be used as follows:

      (#) Declare a IPCC_HandleTypeDef handle structure, for example: IPCC_HandleTypeDef hipcc;
      (#) Initialize the IPCC low level resources by implementing the HAL_IPCC_MspInit() API:
        (##) Enable the IPCC interface clock
        (##) NVIC configuration if you need to use interrupt process
            (+++) Configure the IPCC interrupt priority
            (+++) Enable the NVIC IPCC IRQ

      (#) Initialize the IPCC registers by calling the HAL_IPCC_Init() API which trig
          HAL_IPCC_MspInit().

      (#) Implement the interrupt callbacks for transmission and reception to use the driver in interrupt mode

      (#) Associate those callback to the corresponding channel and direction using HAL_IPCC_ConfigChannel().
          This is the interrupt mode.
          If no callback are configured for a given channel and direction, it is up to the user to poll the
          status of the communication (polling mode).

      (#) Notify the other MCU when a message is available in a chosen channel
          or when a message has been retrieved from a chosen channel by calling
          the HAL_IPCC_NotifyCPU() API.

@endverbatim
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32wbxx_hal.h"

#if defined(IPCC)
/** @addtogroup STM32WBxx_HAL_Driver
  * @{
  */

/** @addtogroup IPCC
  * @{
  */

#ifdef HAL_IPCC_MODULE_ENABLED

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/** @defgroup IPCC_Private_Constants IPCC Private Constants
  * @{
  */
#define IPCC_ALL_RX_BUF 0x0000003FU /*!< Mask for all RX buffers. */
#define IPCC_ALL_TX_BUF 0x003F0000U /*!< Mask for all TX buffers. */
#define CHANNEL_INDEX_MASK 0x0000000FU /*!< Mask the channel index to avoid overflow */
/**
  * @}
  */

/* Private macros ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/** @defgroup IPCC_Private_Functions IPCC Private Functions
  * @{
  */
void IPCC_MaskInterrupt(uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir);
void IPCC_UnmaskInterrupt(uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir);
void IPCC_SetDefaultCallbacks(IPCC_HandleTypeDef *hipcc);
void IPCC_Reset_Register(IPCC_CommonTypeDef *Instance);
/**
  * @}
  */

/** @addtogroup IPCC_Exported_Functions
  * @{
  */

/** @addtogroup IPCC_Exported_Functions_Group1
  *  @brief    Initialization and de-initialization functions
  *
@verbatim
 ===============================================================================
             ##### Initialization and de-initialization functions  #####
 ===============================================================================
    [..]  This subsection provides a set of functions allowing to initialize and
          deinitialize the IPCC peripheral:

      (+) User must Implement HAL_IPCC_MspInit() function in which he configures
          all related peripherals resources (CLOCK and NVIC ).

      (+) Call the function HAL_IPCC_Init() to configure the IPCC register.

      (+) Call the function HAL_PKA_DeInit() to restore the default configuration
          of the selected IPCC peripheral.

@endverbatim
  * @{
  */

/**
  * @brief  Initialize the IPCC peripheral.
  * @param  hipcc IPCC handle
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_IPCC_Init(IPCC_HandleTypeDef *hipcc)
{
  HAL_StatusTypeDef err = HAL_OK;

  /* Check the IPCC handle allocation */
  if (hipcc != NULL)
  {
    /* Check the parameters */
    assert_param(IS_IPCC_ALL_INSTANCE(hipcc->Instance));

    IPCC_CommonTypeDef *currentInstance = IPCC_C1;

    if (hipcc->State == HAL_IPCC_STATE_RESET)
    {
      /* Init the low level hardware : CLOCK, NVIC */
      HAL_IPCC_MspInit(hipcc);
    }

    /* Reset all registers of the current cpu to default state */
    IPCC_Reset_Register(currentInstance);

    /* Activate the interrupts */
    currentInstance->CR |= (IPCC_CR_RXOIE | IPCC_CR_TXFIE);

    /* Clear callback pointers */
    IPCC_SetDefaultCallbacks(hipcc);

    /* Reset all callback notification request */
    hipcc->callbackRequest = 0;

    hipcc->State = HAL_IPCC_STATE_READY;
  }
  else
  {
    err = HAL_ERROR;
  }

  return err;
}

/**
  * @brief  DeInitialize the IPCC peripheral.
  * @param  hipcc IPCC handle
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_IPCC_DeInit(IPCC_HandleTypeDef *hipcc)
{
  HAL_StatusTypeDef err = HAL_OK;

  /* Check the IPCC handle allocation */
  if (hipcc != NULL)
  {
    assert_param(IS_IPCC_ALL_INSTANCE(hipcc->Instance));
    IPCC_CommonTypeDef *currentInstance = IPCC_C1;

    /* Set the state to busy */
    hipcc->State = HAL_IPCC_STATE_BUSY;

    /* Reset all registers of the current cpu to default state */
    IPCC_Reset_Register(currentInstance);

    /* Clear callback pointers */
    IPCC_SetDefaultCallbacks(hipcc);

    /* Reset all callback notification request */
    hipcc->callbackRequest = 0;

    /* DeInit the low level hardware : CLOCK, NVIC */
    HAL_IPCC_MspDeInit(hipcc);

    hipcc->State = HAL_IPCC_STATE_RESET;
  }
  else
  {
    err = HAL_ERROR;
  }

  return err;
}

/**
  * @brief Initialize the IPCC MSP.
  * @param  hipcc IPCC handle
  * @retval None
  */
__weak void HAL_IPCC_MspInit(IPCC_HandleTypeDef *hipcc)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hipcc);

  /* NOTE : This function should not be modified. When the callback is needed
            the HAL_IPCC_MspInit should be implemented in the user file
   */
}

/**
  * @brief IPCC MSP DeInit
  * @param  hipcc IPCC handle
  * @retval None
  */
__weak void HAL_IPCC_MspDeInit(IPCC_HandleTypeDef *hipcc)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hipcc);

  /* NOTE : This function should not be modified. When the callback is needed
            the HAL_IPCC_MspDeInit should be implemented in the user file
   */
}

/**
  * @}
  */


/** @addtogroup IPCC_Exported_Functions_Group2
  *  @brief    Configuration, notification and Irq handling functions.
  *
@verbatim
 ===============================================================================
              ##### IO operation functions #####
 ===============================================================================
    [..]  This section provides functions to allow two MCU to communicate.

    (#) For a given channel (from 0 to IPCC_CHANNEL_NUMBER), for a given direction
        IPCC_CHANNEL_DIR_TX or IPCC_CHANNEL_DIR_RX, you can choose to communicate
        in polling mode or in interrupt mode using IPCC.
        By default, the IPCC HAL driver handle the communication in polling mode.
        By setting a callback for a channel/direction, this communication use
        the interrupt mode.

    (#) Polling mode:
       (++) To transmit information, use HAL_IPCC_NotifyCPU() with
            IPCC_CHANNEL_DIR_TX. To know when the other processor has handled
            the notification, poll the communication using HAL_IPCC_NotifyCPU
            with IPCC_CHANNEL_DIR_TX.

       (++) To receive information, poll the status of the communication with
            HAL_IPCC_GetChannelStatus with IPCC_CHANNEL_DIR_RX. To notify the other
            processor that the information has been received, use HAL_IPCC_NotifyCPU
            with IPCC_CHANNEL_DIR_RX.

    (#) Interrupt mode:
       (++) Configure a callback for the channel and the direction using HAL_IPCC_ConfigChannel().
            This callback will be triggered under interrupt.

       (++) To transmit information, use HAL_IPCC_NotifyCPU() with
            IPCC_CHANNEL_DIR_TX. The callback configured with HAL_IPCC_ConfigChannel() and
            IPCC_CHANNEL_DIR_TX will be triggered once the communication has been handled by the
            other processor.

       (++) To receive information, the callback configured with HAL_IPCC_ConfigChannel() and
            IPCC_CHANNEL_DIR_RX will be triggered on reception of a communication.To notify the other
            processor that the information has been received, use HAL_IPCC_NotifyCPU
            with IPCC_CHANNEL_DIR_RX.

       (++) HAL_IPCC_TX_IRQHandler must be added to the IPCC TX IRQHandler

       (++) HAL_IPCC_RX_IRQHandler must be added to the IPCC RX IRQHandler
@endverbatim
  * @{
  */

/**
  * @brief  Activate the callback notification on receive/transmit interrupt
  * @param  hipcc IPCC handle
  * @param  ChannelIndex Channel number
  *          This parameter can be one of the following values:
  *            @arg IPCC_CHANNEL_1: IPCC Channel 1
  *            @arg IPCC_CHANNEL_2: IPCC Channel 2
  *            @arg IPCC_CHANNEL_3: IPCC Channel 3
  *            @arg IPCC_CHANNEL_4: IPCC Channel 4
  *            @arg IPCC_CHANNEL_5: IPCC Channel 5
  *            @arg IPCC_CHANNEL_6: IPCC Channel 6
  * @param  ChannelDir Channel direction
  * @param  cb Interrupt callback
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_IPCC_ActivateNotification(IPCC_HandleTypeDef *hipcc,
                                                uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir,
                                                ChannelCb cb)
{
  HAL_StatusTypeDef err = HAL_OK;

  /* Check the IPCC handle allocation */
  if (hipcc != NULL)
  {
    /* Check the parameters */
    assert_param(IS_IPCC_ALL_INSTANCE(hipcc->Instance));

    /* Check IPCC state */
    if (hipcc->State == HAL_IPCC_STATE_READY)
    {
      /* Set callback and register masking information */
      if (ChannelDir == IPCC_CHANNEL_DIR_TX)
      {
        hipcc->ChannelCallbackTx[ChannelIndex] = cb;
        hipcc->callbackRequest |= (IPCC_MR_CH1FM_Msk << (ChannelIndex & CHANNEL_INDEX_MASK));
      }
      else
      {
        hipcc->ChannelCallbackRx[ChannelIndex] = cb;
        hipcc->callbackRequest |= (IPCC_MR_CH1OM_Msk << (ChannelIndex & CHANNEL_INDEX_MASK));
      }

      /* Unmask only the channels in reception (Transmission channel mask/unmask is done in HAL_IPCC_NotifyCPU) */
      if (ChannelDir == IPCC_CHANNEL_DIR_RX)
      {
        IPCC_UnmaskInterrupt(ChannelIndex, ChannelDir);
      }
    }
    else
    {
      err = HAL_ERROR;
    }
  }
  else
  {
    err = HAL_ERROR;
  }
  return err;
}

/**
  * @brief  Remove the callback notification on receive/transmit interrupt
  * @param  hipcc IPCC handle
  * @param  ChannelIndex Channel number
  *          This parameter can be one of the following values:
  *            @arg IPCC_CHANNEL_1: IPCC Channel 1
  *            @arg IPCC_CHANNEL_2: IPCC Channel 2
  *            @arg IPCC_CHANNEL_3: IPCC Channel 3
  *            @arg IPCC_CHANNEL_4: IPCC Channel 4
  *            @arg IPCC_CHANNEL_5: IPCC Channel 5
  *            @arg IPCC_CHANNEL_6: IPCC Channel 6
  * @param  ChannelDir Channel direction
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_IPCC_DeActivateNotification(IPCC_HandleTypeDef *hipcc,
                                                  uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir)
{
  HAL_StatusTypeDef err = HAL_OK;

  /* Check the IPCC handle allocation */
  if (hipcc != NULL)
  {
    /* Check the parameters */
    assert_param(IS_IPCC_ALL_INSTANCE(hipcc->Instance));

    /* Check IPCC state */
    if (hipcc->State == HAL_IPCC_STATE_READY)
    {
      /* Set default callback and register masking information */
      if (ChannelDir == IPCC_CHANNEL_DIR_TX)
      {
        hipcc->ChannelCallbackTx[ChannelIndex] = HAL_IPCC_TxCallback;
        hipcc->callbackRequest &= ~(IPCC_MR_CH1FM_Msk << (ChannelIndex & CHANNEL_INDEX_MASK));
      }
      else
      {
        hipcc->ChannelCallbackRx[ChannelIndex] = HAL_IPCC_RxCallback;
        hipcc->callbackRequest &= ~(IPCC_MR_CH1OM_Msk << (ChannelIndex & CHANNEL_INDEX_MASK));
      }

      /* Mask the interrupt */
      IPCC_MaskInterrupt(ChannelIndex, ChannelDir);
    }
    else
    {
      err = HAL_ERROR;
    }
  }
  else
  {
    err = HAL_ERROR;
  }
  return err;
}

/**
  * @brief  Get state of IPCC channel
  * @param  hipcc IPCC handle
  * @param  ChannelIndex Channel number
  *          This parameter can be one of the following values:
  *            @arg IPCC_CHANNEL_1: IPCC Channel 1
  *            @arg IPCC_CHANNEL_2: IPCC Channel 2
  *            @arg IPCC_CHANNEL_3: IPCC Channel 3
  *            @arg IPCC_CHANNEL_4: IPCC Channel 4
  *            @arg IPCC_CHANNEL_5: IPCC Channel 5
  *            @arg IPCC_CHANNEL_6: IPCC Channel 6
  * @param  ChannelDir Channel direction
  * @retval Channel status
  */
IPCC_CHANNELStatusTypeDef HAL_IPCC_GetChannelStatus(IPCC_HandleTypeDef const *const hipcc,
                                                    uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir)
{
  uint32_t channel_state;
  IPCC_CommonTypeDef *currentInstance = IPCC_C1;
  IPCC_CommonTypeDef *otherInstance = IPCC_C2;

  /* Check the parameters */
  assert_param(IS_IPCC_ALL_INSTANCE(hipcc->Instance));

  /* Read corresponding channel depending of the MCU and the direction */
  if (ChannelDir == IPCC_CHANNEL_DIR_TX)
  {
    channel_state = (currentInstance->SR) & (IPCC_SR_CH1F_Msk << (ChannelIndex & CHANNEL_INDEX_MASK));
  }
  else
  {
    channel_state = (otherInstance->SR) & (IPCC_SR_CH1F_Msk << (ChannelIndex & CHANNEL_INDEX_MASK));
  }

  return (channel_state == 0UL) ? IPCC_CHANNEL_STATUS_FREE : IPCC_CHANNEL_STATUS_OCCUPIED ;
}

/**
  * @brief  Notify remote processor
  * @param  hipcc IPCC handle
  * @param  ChannelIndex Channel number
  *          This parameter can be one of the following values:
  *            @arg IPCC_CHANNEL_1: IPCC Channel 1
  *            @arg IPCC_CHANNEL_2: IPCC Channel 2
  *            @arg IPCC_CHANNEL_3: IPCC Channel 3
  *            @arg IPCC_CHANNEL_4: IPCC Channel 4
  *            @arg IPCC_CHANNEL_5: IPCC Channel 5
  *            @arg IPCC_CHANNEL_6: IPCC Channel 6
  * @param  ChannelDir Channel direction
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_IPCC_NotifyCPU(IPCC_HandleTypeDef const *const hipcc,
                                     uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir)
{
  HAL_StatusTypeDef err = HAL_OK;
  uint32_t mask;
  IPCC_CommonTypeDef *currentInstance = IPCC_C1;

  /* Check the parameters */
  assert_param(IS_IPCC_ALL_INSTANCE(hipcc->Instance));

  /* Check if IPCC is initialized */
  if (hipcc->State == HAL_IPCC_STATE_READY)
  {
    /* For IPCC_CHANNEL_DIR_TX, set the status. For IPCC_CHANNEL_DIR_RX, clear the status */
    currentInstance->SCR |= ((ChannelDir == IPCC_CHANNEL_DIR_TX) ? IPCC_SCR_CH1S :
                             IPCC_SCR_CH1C)
                            << (ChannelIndex & CHANNEL_INDEX_MASK);

    /* Unmask interrupt if the callback is requested */
    mask = ((ChannelDir == IPCC_CHANNEL_DIR_TX) ? IPCC_MR_CH1FM_Msk :
            IPCC_MR_CH1OM_Msk) << (ChannelIndex & CHANNEL_INDEX_MASK);
    if ((hipcc->callbackRequest & mask) == mask)
    {
      IPCC_UnmaskInterrupt(ChannelIndex, ChannelDir);
    }
  }
  else
  {
    err = HAL_ERROR;
  }

  return err;
}

/**
  * @}
  */

/** @addtogroup IPCC_IRQ_Handler_and_Callbacks
  * @{
  */

/**
  * @brief  This function handles IPCC Tx Free interrupt request.
  * @param  hipcc IPCC handle
  * @retval None
  */
void HAL_IPCC_TX_IRQHandler(IPCC_HandleTypeDef *const hipcc)
{
  uint32_t irqmask;
  uint32_t bit_pos;
  uint32_t ch_count = 0U;
  IPCC_CommonTypeDef *currentInstance = IPCC_C1;

  /* check the Tx free channels which are not masked */
  irqmask = ~(currentInstance->MR) & IPCC_ALL_TX_BUF;
  irqmask = irqmask & ~(currentInstance->SR << IPCC_MR_CH1FM_Pos);

  while (irqmask != 0UL)  /* if several bits are set, it loops to serve all of them */
  {
    bit_pos = 1UL << (IPCC_MR_CH1FM_Pos + (ch_count & CHANNEL_INDEX_MASK));

    if ((irqmask & bit_pos) != 0U)
    {
      /* mask the channel Free interrupt  */
      currentInstance->MR |= bit_pos;
      if (hipcc->ChannelCallbackTx[ch_count] != NULL)
      {
        hipcc->ChannelCallbackTx[ch_count](hipcc, ch_count, IPCC_CHANNEL_DIR_TX);
      }
      irqmask =  irqmask & ~(bit_pos);
    }
    ch_count++;
  }
}

/**
  * @brief  This function handles IPCC Rx Occupied interrupt request.
  * @param  hipcc : IPCC handle
  * @retval None
  */
void HAL_IPCC_RX_IRQHandler(IPCC_HandleTypeDef *const hipcc)
{
  uint32_t irqmask;
  uint32_t bit_pos;
  uint32_t ch_count = 0U;
  IPCC_CommonTypeDef *currentInstance = IPCC_C1;
  IPCC_CommonTypeDef *otherInstance = IPCC_C2;

  /* check the Rx occupied channels which are not masked */
  irqmask = ~(currentInstance->MR) & IPCC_ALL_RX_BUF;
  irqmask = irqmask & otherInstance->SR;

  while (irqmask != 0UL)  /* if several bits are set, it loops to serve all of them */
  {
    bit_pos = 1UL << (ch_count & CHANNEL_INDEX_MASK);

    if ((irqmask & bit_pos) != 0U)
    {
      /* mask the channel occupied interrupt */
      currentInstance->MR |= bit_pos;
      if (hipcc->ChannelCallbackRx[ch_count] != NULL)
      {
        hipcc->ChannelCallbackRx[ch_count](hipcc, ch_count, IPCC_CHANNEL_DIR_RX);
      }
      irqmask = irqmask & ~(bit_pos);
    }
    ch_count++;
  }
}

/**
  * @brief Rx occupied callback
  * @param hipcc IPCC handle
  * @param ChannelIndex Channel number
  *          This parameter can be one of the following values:
  *            @arg IPCC_CHANNEL_1: IPCC Channel 1
  *            @arg IPCC_CHANNEL_2: IPCC Channel 2
  *            @arg IPCC_CHANNEL_3: IPCC Channel 3
  *            @arg IPCC_CHANNEL_4: IPCC Channel 4
  *            @arg IPCC_CHANNEL_5: IPCC Channel 5
  *            @arg IPCC_CHANNEL_6: IPCC Channel 6
  * @param ChannelDir Channel direction
  */
__weak void HAL_IPCC_RxCallback(IPCC_HandleTypeDef *hipcc, uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hipcc);
  UNUSED(ChannelIndex);
  UNUSED(ChannelDir);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_IPCC_RxCallback can be implemented in the user file
   */
}

/**
  * @brief Tx free callback
  * @param hipcc IPCC handle
  * @param ChannelIndex Channel number
  *          This parameter can be one of the following values:
  *            @arg IPCC_CHANNEL_1: IPCC Channel 1
  *            @arg IPCC_CHANNEL_2: IPCC Channel 2
  *            @arg IPCC_CHANNEL_3: IPCC Channel 3
  *            @arg IPCC_CHANNEL_4: IPCC Channel 4
  *            @arg IPCC_CHANNEL_5: IPCC Channel 5
  *            @arg IPCC_CHANNEL_6: IPCC Channel 6
  * @param ChannelDir Channel direction
  */
__weak void HAL_IPCC_TxCallback(IPCC_HandleTypeDef *hipcc, uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hipcc);
  UNUSED(ChannelIndex);
  UNUSED(ChannelDir);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_IPCC_TxCallback can be implemented in the user file
   */
}

/**
  * @}
  */

/** @addtogroup IPCC_Exported_Functions_Group3
  *  @brief   IPCC Peripheral State and Error functions
  *
@verbatim
  ==============================================================================
            ##### Peripheral State and Error functions #####
  ==============================================================================
    [..]
    This subsection permit to get in run-time the status of the peripheral
    and the data flow.

@endverbatim
  * @{
  */

/**
  * @brief Return the IPCC handle state.
  * @param  hipcc IPCC handle
  * @retval IPCC handle state
  */
HAL_IPCC_StateTypeDef HAL_IPCC_GetState(IPCC_HandleTypeDef const *const hipcc)
{
  return hipcc->State;
}

/**
  * @}
  */

/**
  * @}
  */

/** @addtogroup IPCC_Private_Functions
  * @{
  */

/**
  * @brief  Mask IPCC interrupts.
  * @param  ChannelIndex Channel number
  *          This parameter can be one of the following values:
  *            @arg IPCC_CHANNEL_1: IPCC Channel 1
  *            @arg IPCC_CHANNEL_2: IPCC Channel 2
  *            @arg IPCC_CHANNEL_3: IPCC Channel 3
  *            @arg IPCC_CHANNEL_4: IPCC Channel 4
  *            @arg IPCC_CHANNEL_5: IPCC Channel 5
  *            @arg IPCC_CHANNEL_6: IPCC Channel 6
  * @param  ChannelDir Channel direction
  */
void IPCC_MaskInterrupt(uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir)
{
  IPCC_CommonTypeDef *currentInstance = IPCC_C1;
  if (ChannelDir == IPCC_CHANNEL_DIR_TX)
  {
    /* Mask interrupt */
    currentInstance->MR |= (IPCC_MR_CH1FM_Msk << (ChannelIndex & CHANNEL_INDEX_MASK));
  }
  else
  {
    /* Mask interrupt */
    currentInstance->MR |= (IPCC_MR_CH1OM_Msk << (ChannelIndex & CHANNEL_INDEX_MASK));
  }
}
/**
  * @brief  Unmask IPCC interrupts.
  * @param  ChannelIndex Channel number
  *          This parameter can be one of the following values:
  *            @arg IPCC_CHANNEL_1: IPCC Channel 1
  *            @arg IPCC_CHANNEL_2: IPCC Channel 2
  *            @arg IPCC_CHANNEL_3: IPCC Channel 3
  *            @arg IPCC_CHANNEL_4: IPCC Channel 4
  *            @arg IPCC_CHANNEL_5: IPCC Channel 5
  *            @arg IPCC_CHANNEL_6: IPCC Channel 6
  * @param  ChannelDir Channel direction
  */
void IPCC_UnmaskInterrupt(uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir)
{
  IPCC_CommonTypeDef *currentInstance = IPCC_C1;
  if (ChannelDir == IPCC_CHANNEL_DIR_TX)
  {
    /* Unmask interrupt */
    currentInstance->MR &= ~(IPCC_MR_CH1FM_Msk << (ChannelIndex & CHANNEL_INDEX_MASK));
  }
  else
  {
    /* Unmask interrupt */
    currentInstance->MR &= ~(IPCC_MR_CH1OM_Msk << (ChannelIndex & CHANNEL_INDEX_MASK));
  }
}

/**
  * @brief Reset all callbacks of the handle to NULL.
  * @param  hipcc IPCC handle
  */
void IPCC_SetDefaultCallbacks(IPCC_HandleTypeDef *hipcc)
{
  uint32_t i;
  /* Set all callbacks to default */
  for (i = 0; i < IPCC_CHANNEL_NUMBER; i++)
  {
    hipcc->ChannelCallbackRx[i] = HAL_IPCC_RxCallback;
    hipcc->ChannelCallbackTx[i] = HAL_IPCC_TxCallback;
  }
}

/**
  * @brief Reset IPCC register to default value for the concerned instance.
  * @param  Instance pointer to register
  */
void IPCC_Reset_Register(IPCC_CommonTypeDef *Instance)
{
  /* Disable RX and TX interrupts */
  Instance->CR  = 0x00000000U;

  /* Mask RX and TX interrupts */
  Instance->MR  = (IPCC_ALL_TX_BUF | IPCC_ALL_RX_BUF);

  /* Clear RX status */
  Instance->SCR = IPCC_ALL_RX_BUF;
}

/**
  * @}
  */

#endif /* HAL_IPCC_MODULE_ENABLED */

/**
  * @}
  */

/**
  * @}
  */
#endif /* IPCC */

