/*!
 * @file        bmp561_eint.c
 *
 * @brief       This file provides all the EINT firmware functions
 *
 * @version     V1.0.0
 *
 * @date        2025-01-01
 *
 * @attention
 *
 *  Copyright (C) 2025 Geehy Semiconductor
 *
 *  You may not use this file except in compliance with the
 *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
 *
 *  The program is only for reference, which is distributed in the hope
 *  that it will be useful and instructional for customers to develop
 *  their software. Unless required by applicable law or agreed to in
 *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
 *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
 *  and limitations under the License.
 */

#include "bmp561_eint.h"
#include "bmp561_sysctrl.h"

/** @addtogroup Peripherals_Library Standard Peripheral Library
  @{
*/

/** @addtogroup EINT_Driver EINT Driver
  @{
*/

/** @addtogroup EINT_Functions Functions
  @{
*/

/*!
 * @brief     Resets the EINT peripheral registers to their default reset values.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void EINT_Reset(void)
{
    SYSCTRL_Unlock();
    SYSCTRL_EnableAPBPeriphReset(SYSCTRL_APB_EINT);
    SYSCTRL_DisableAPBPeriphReset(SYSCTRL_APB_EINT);
    SYSCTRL_Lock();
}

/*!
 * @brief     Enables EINT module, include filter, detection circuit and division circuit.
 *
 * @param     line: specifies the EINT lines.
 *                  This parameter can be one of the following values:
 *                  @arg EINT_PORT_0: EINT0
 *                  @arg EINT_PORT_1: EINT1
 *                  @arg EINT_PORT_2: EINT2
 *
 * @retval    None
 *
 */
void EINT_EnableModule(EINT_PORT_T line)
{
    EINT->CTRL |= (uint32_t)(0x01 << (9 * line + 8));
}

/*!
 * @brief     Disables EINT module, include filter, detection circuit and division circuit.
 *
 * @param     line: specifies the EINT lines.
 *                  This parameter can be one of the following values:
 *                  @arg EINT_PORT_0: EINT0
 *                  @arg EINT_PORT_1: EINT1
 *                  @arg EINT_PORT_2: EINT2
 *
 * @retval    None
 *
 */
void EINT_DisableModule(EINT_PORT_T line)
{
    EINT->CTRL &= ~((uint32_t)(0x01 << (9 * line + 8)));
}

/*!
 * @brief     Enables EINT software trigger.
 *
 * @param     line: specifies the EINT lines.
 *                  This parameter can be one of the following values:
 *                  @arg EINT_PORT_0: EINT0
 *                  @arg EINT_PORT_1: EINT1
 *                  @arg EINT_PORT_2: EINT2
 *
 * @retval    None
 *
 */
void EINT_EnableSoftTrig(EINT_PORT_T line)
{
    EINT->CTRL |= (uint32_t)(0x01 << (9 * line));
}

/*!
 * @brief     Disables EINT software trigger.
 *
 * @param     line: specifies the EINT lines.
 *                  This parameter can be one of the following values:
 *                  @arg EINT_PORT_0: EINT0
 *                  @arg EINT_PORT_1: EINT1
 *                  @arg EINT_PORT_2: EINT2
 *
 * @retval    None
 *
 */
void EINT_DisableSoftTrig(EINT_PORT_T line)
{
    EINT->CTRL &= ~((uint32_t)(0x01 << (9 * line)));
}

/*!
 * @brief     Configures EINT trigger type.
 *
 * @param     line: specifies the EINT lines.
 *                  This parameter can be one of the following values:
 *                  @arg EINT_PORT_0: EINT0
 *                  @arg EINT_PORT_1: EINT1
 *                  @arg EINT_PORT_2: EINT2
 *
 * @param     trigger: specifies the trigger source.
 *                     This parameter can be one of the following values:
 *                     @arg EINT_TRIGGER_HIGH   : High level
 *                     @arg EINT_TRIGGER_LOW    : Low level
 *                     @arg EINT_TRIGGER_RISING : Rising edge
 *                     @arg EINT_TRIGGER_FALLING: Falling edge
 *                     @arg EINT_TRIGGER_DOUBLE : Rising and falling edge
 *
 * @retval    None
 *
 */
void EINT_ConfigTrig(EINT_PORT_T line, EINT_TRIGGER_T trigger)
{
    EINT->CTRL &= ~((uint32_t)(0x07 << (9 * line + 1)));
    EINT->CTRL |= (uint32_t)(trigger << (9 * line + 1));
}

/*!
 * @brief     Configures EINT filter.
 *
 * @param     line: specifies the EINT lines.
 *                  This parameter can be one of the following values:
 *                  @arg EINT_PORT_0: EINT0
 *                  @arg EINT_PORT_1: EINT1
 *                  @arg EINT_PORT_2: EINT2
 *
 * @param     filter: specifies the filter.
 *                    This parameter can be one of the following values:
 *                    @arg EINT_FILTER_0: Filter 0 time
 *                    @arg EINT_FILTER_1: Filter 1 time
 *                    @arg EINT_FILTER_2: Filter 2 times
 *                    @arg EINT_FILTER_3: Filter 3 times
 *
 * @retval    None
 *
 */
void EINT_ConfigFilter(EINT_PORT_T line, EINT_FILTER_T filter)
{
    EINT->CTRL &= ~((uint32_t)(0x03 << (9 * line + 4)));
    EINT->CTRL |= (uint32_t)(filter << (9 * line + 4));
}

/*!
 * @brief     Configures EINT clock division.
 *
 * @param     line: specifies the EINT lines.
 *                  This parameter can be one of the following values:
 *                  @arg EINT_PORT_0: EINT0
 *                  @arg EINT_PORT_1: EINT1
 *                  @arg EINT_PORT_2: EINT2
 *
 * @param     div: specifies the clock division.
 *                 This parameter can be one of the following values:
 *                 @arg EINT_DIV_1: Bypass
 *                 @arg EINT_DIV_2: 1/2
 *                 @arg EINT_DIV_4: 1/4
 *                 @arg EINT_DIV_8: 1/8
 *
 * @retval    None
 *
 */
void EINT_ConfigClockDiv(EINT_PORT_T line, EINT_DIV_T div)
{
    EINT->CTRL &= ~((uint32_t)(0x03 << (9 * line + 6)));
    EINT->CTRL |= (uint32_t)(div << (9 * line + 6));
}

/*!
 * @brief     Enables interrupt on EINT line
 *
 * @param     line: specifies the EINT lines.
 *                  This parameter can be one of the following values:
 *                  @arg EINT_PORT_0: EINT0
 *                  @arg EINT_PORT_1: EINT1
 *                  @arg EINT_PORT_2: EINT2
 *
 * @retval    None
 *
 */
void EINT_EnableInterrupt(EINT_PORT_T line)
{
    EINT->IEN |= (uint32_t)(0x01 << line);
}

/*!
 * @brief     Disables interrupt on EINT line.
 *
 * @param     line: specifies the EINT lines.
 *                  This parameter can be one of the following values:
 *                  @arg EINT_PORT_0: EINT0
 *                  @arg EINT_PORT_1: EINT1
 *                  @arg EINT_PORT_2: EINT2
 *
 * @retval    None
 *
 */
void EINT_DisableInterrupt(EINT_PORT_T line)
{
    EINT->IEN &= ~((uint32_t)(0x01 << line));
}

/*!
 * @brief     Reads the specified EINT line interrupt status.
 *
 * @param     line: specifies the EINT lines.
 *                  This parameter can be one of the following values:
 *                  @arg EINT_PORT_0: EINT0
 *                  @arg EINT_PORT_1: EINT1
 *                  @arg EINT_PORT_2: EINT2
 *
 * @retval    status: The new state of interrupt status (SET or RESET)
 *
 */
uint8_t EINT_ReadInterruptStatus(EINT_PORT_T line)
{
    uint8_t status = RESET;

    if((EINT->SR & ((uint32_t)(0x01 << line))) != (uint32_t)RESET)
    {
        status = SET;
    }
    else
    {
        status = RESET;
    }
    return status;
}

/*!
 * @brief     Clears the EINT line interrupt pending bits.
 *
 * @param     line: specifies the EINT lines.
 *                  This parameter can be one of the following values:
 *                  @arg EINT_PORT_0: EINT0
 *                  @arg EINT_PORT_1: EINT1
 *                  @arg EINT_PORT_2: EINT2
 *
 * @retval    None
 *
 */
void EINT_ClearInterruptStatus(EINT_PORT_T line)
{
    EINT->SCR |= (uint32_t)(0x01 << line);
}

/**@} end of group EINT_Functions*/
/**@} end of group EINT_Driver*/
/**@} end of group Peripherals_Library*/
