
/******************************************************************************
*@file  : spl_exti.c
*@brief : EXTI module driver.
******************************************************************************/

#include "acm32g103_spl_conf.h" 

//#ifdef SPL_EXTI_MODULE_ENABLED


/******************************************************************************
*@brief : Set configuration of a dedicated Exti line.
*@param : GPIOx: where x can be (A..F) to select the GPIO peripheral.
*                This parameter is only possible for line 0 to 15.
*@param : Line:  Exti line number.
*                This parameter can be a combination of @ref EXTI_Line.
*@param : Mode:  The Exit Mode to be configured for a core.
                 This parameter can be a value of @ref EXTI_Mode .
*@return: HAL Status
******************************************************************************/
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
{
    uint32_t tempCR1;
    uint32_t tempCR2;
    uint32_t tempLine;
    uint32_t position;
    uint32_t source;
    
    /* Check the parameters */
    assert_param(IS_EXTI_ALL_LINE(EXTI_InitStruct->Line));
    assert_param(IS_EXTI_FUNCTIONAL_STATE(EXTI_InitStruct->Cmd));

	EXTI->IENR  &= ~EXTI_InitStruct->Line;
	EXTI->EENR  &= ~EXTI_InitStruct->Line;
	EXTI->RTENR &= ~EXTI_InitStruct->Line;
	EXTI->FTENR &= ~EXTI_InitStruct->Line;
	EXTI->PDR    =  EXTI_InitStruct->Line;
    
    if (EXTI_InitStruct->Cmd != DISABLE)
    {
        assert_param(IS_EXTI_MODE(EXTI_InitStruct->Mode));
        assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->Trigger));
        
        /* Line0 ~ 15 trigger from GPIO */
        tempLine = EXTI_InitStruct->Line & EXTI_GPIO_LINE_MASK;
        if (tempLine)
        {
            /* Check the parameters */
            assert_param(IS_EXTI_GPIOX(EXTI_InitStruct->GPIOx));
            
            /* Configure EXTI source select */
            if (EXTI_InitStruct->GPIOx == GPIOA)
                source = EXTI_GPIOA;
            else if (EXTI_InitStruct->GPIOx == GPIOB)
                source = EXTI_GPIOB;
            else if (EXTI_InitStruct->GPIOx == GPIOC)
                source = EXTI_GPIOC;
            else if (EXTI_InitStruct->GPIOx == GPIOD)
                source = EXTI_GPIOD;
            else if (EXTI_InitStruct->GPIOx == GPIOE)
                source = EXTI_GPIOE;
            else if (EXTI_InitStruct->GPIOx == GPIOF)
                source = EXTI_GPIOF;
			else
				source = 0;
            
            tempCR1 = EXTI->CR1;
            tempCR2 = EXTI->CR2;
            
            position = 0;
            while (tempLine >> position)
            {
                if (tempLine & (0x1U << position))
                {
                    if (position < 8U) 
                    {
                        /* Line0 ~ 7 */
                        tempCR1 &= ~(0x0FUL << (position << 2U));
                        tempCR1 |= source << (position << 2U);
                    }
                    else 
                    {
                        /* Line8 ~ 15 */
                        tempCR2 &= ~(0x0FUL << ((position - 8U) << 2U));
                        tempCR2 |= source << ((position - 8U) << 2U);
                    }
                }
                position++;
            }
            
            EXTI->CR1 = tempCR1;
            EXTI->CR2 = tempCR2;
        }
    
        if (EXTI_InitStruct->Trigger == EXTI_TRIGGER_RISING)
        {
            /* Interrupt rising and falling edge mode */
            EXTI->RTENR |=  EXTI_InitStruct->Line;
        }
        else if (EXTI_InitStruct->Trigger == EXTI_TRIGGER_FALLING)
        {
            /* Interrupt rising and falling edge mode */
            EXTI->FTENR |=  EXTI_InitStruct->Line;
        }
        else
        {
            /* Interrupt rising and falling edge mode */
            EXTI->FTENR |=  EXTI_InitStruct->Line;
            EXTI->EENR |=  EXTI_InitStruct->Line;
        }
        
        if (EXTI_InitStruct->Mode == EXTI_MODE_IT)
        {
            /* Interrupt mode */
            EXTI->IENR  |=  EXTI_InitStruct->Line;
        }
        else
        {
            /* Event mode */
            EXTI->EENR  |=  EXTI_InitStruct->Line;
        }
    }
}

/******************************************************************************
*@brief : Deinitializes the EXTI peripheral registers to their default reset values.
*@param : None
*@return: None
******************************************************************************/
void EXTI_DeInit(void)
{
	EXTI->IENR  = 0;
	EXTI->EENR  = 0;
	EXTI->RTENR = 0;
	EXTI->FTENR = 0;
	EXTI->PDR   = EXTI_ALL_LINE_MASK;
}

/******************************************************************************
*@brief : Fills each EXTI_InitStruct member with its reset value.
*@param : EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure which will
*                          be initialized.
*@return: None
******************************************************************************/
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct)
{
    EXTI_InitStruct->GPIOx = NULL;
    EXTI_InitStruct->Line = 0;
    EXTI_InitStruct->Mode = EXTI_MODE_IT;
    EXTI_InitStruct->Trigger = EXTI_TRIGGER_FALLING;
    EXTI_InitStruct->Cmd = DISABLE;
}


/******************************************************************************
*@brief : Generates a Software interrupt on selected EXTI line.
*@param : Line:  Exti line number.
*                This parameter can be a combination of @ref EXTI_Line.
*@return: None.
******************************************************************************/
void HAL_EXTI_GenerateSWI(uint32_t Line)
{
    /* Check the parameters */
    assert_param(IS_EXTI_ALL_LINE(Line));

    EXTI->SWIER &= ~Line;
    EXTI->SWIER |=  Line;
}

/******************************************************************************
*@brief : Checks whether the specified EXTI line flag is set or not.
*@param : Line:  Exti line number.
*                This parameter can be a value of @ref EXTI_Line.
*@return: interrupt pending bit status
*         This parameter can be a value of @ref FlagStatus.
*             @arg SET: interrupt is pending.
*             @arg RESET: interrupt is not pending.
******************************************************************************/
FlagStatus EXTI_GetFlagStatus(uint32_t Line)
{
    /* Check the parameters */
    assert_param(IS_EXTI_SINGLE_LINE(Line));

    if (EXTI->PDR & Line)
		return (SET);
	else
		return (RESET);
}

/******************************************************************************
*@brief : Clears the EXTI's line pending flags.
*@param : Line:  Exti line number.
*                This parameter can be a combination of @ref EXTI_Line.
*@return: None.
******************************************************************************/
void EXTI_ClearFlag(uint32_t Line)
{
    /* Check the parameters */
    assert_param(IS_EXTI_ALL_LINE(Line));

    /* Clear pending status */
    EXTI->PDR = Line;
}

/******************************************************************************
*@brief : Clears the EXTI's line pending flags.
*@return: None.
******************************************************************************/
void EXTI_ClearAllFlag(void)
{
    /* Clear pending status */
    EXTI->PDR = EXTI_ALL_LINE_MASK;   
}

/******************************************************************************
*@brief : Checks whether the specified EXTI line is asserted or not.
*@param : Line:  Exti line number.
*                This parameter can be a value of @ref EXTI_Line.
*@return: interrupt pending bit status
*         This parameter can be a value of @ref FlagStatus.
*             @arg SET: interrupt is pending.
*             @arg RESET: interrupt is not pending.
******************************************************************************/
FlagStatus EXTI_GetITStatus(uint32_t Line)
{
    /* Check the parameters */
    assert_param(IS_EXTI_SINGLE_LINE(Line));

    if (EXTI->PDR & Line)
		return (SET);
	else
		return (RESET);
}

/******************************************************************************
*@brief : Clears the EXTI's line pending bits.
*@param : Line:  Exti line number.
*                This parameter can be a value of @ref EXTI_Line.
*@return: None.
******************************************************************************/
void EXTI_ClearITPendingBit(uint32_t Line)
{
    /* Check the parameters */
    assert_param(IS_EXTI_ALL_LINE(Line));

    /* Clear pending status */
    EXTI->PDR = Line;  
}

/******************************************************************************
*@brief : Clears the EXTI's line pending bits.
*@return: None.
******************************************************************************/
void EXTI_ClearAllITPendingBit(void)
{
    /* Clear pending status */
    EXTI->PDR = EXTI_ALL_LINE_MASK;   
}



//#endif /* HAL_EXTI_MODULE_ENABLED */

/************************ (C) COPYRIGHT AISINOCHIP *****END OF FILE****/


