/**************************************************************************//**
 * @file     pan_kscan.h
 * @version  V1.00
 * $Revision: 3$
 * $Date: 20/04/02 14:50 $ 
 * @brief    Panchip series key scan driver header file
 *
 * @note
 * Copyright (C) 2020 Panchip Technology Corp. All rights reserved.
 *****************************************************************************/ 
#ifndef __PAN_KSCAN_H__
#define __PAN_KSCAN_H__

#ifdef __cplusplus
extern "C"
{
#endif

#define KS_PERIPHRAL_ENABLE                 (0X00000001)
#define KS_WAKEUP_ENABLE                    (0X00000002)
#define KS_WAKEUP_AND_PERIPH_ENABLE         (0X00000003)

#define KS_INTERVAL_TIME_CLK_1              (0X0)
#define KS_INTERVAL_TIME_CLK_2              (0X1)
#define KS_INTERVAL_TIME_CLK_4              (0X2)
#define KS_INTERVAL_TIME_CLK_8              (0X3)
#define KS_INTERVAL_TIME_CLK_16             (0X4)
#define KS_INTERVAL_TIME_CLK_32             (0X5)
#define KS_INTERVAL_TIME_CLK_64             (0X6)
#define KS_INTERVAL_TIME_CLK_128            (0X7)
#define KS_INTERVAL_TIME_CLK_256            (0X8)
#define KS_INTERVAL_TIME_CLK_512            (0X9)
#define KS_INTERVAL_TIME_CLK_1024           (0XA)
#define KS_INTERVAL_TIME_CLK_2048           (0XB)
#define KS_INTERVAL_TIME_CLK_4K             (0XC)
#define KS_INTERVAL_TIME_CLK_8K             (0XD)
#define KS_INTERVAL_TIME_CLK_16K            (0XE)
#define KS_INTERVAL_TIME_CLK_32K            (0XF)



/**
  * @brief  This function is set keyscan enable bit
  * @param  ks: where ks is a keyscan peripheral base address
  * @param  NewState: new state of the keyscan peripheral
  * @param  func: function select
                        KS_PERIPHRAL_ENABLE                               
                        KS_WAKEUP_ENABLE           
                        KS_WAKEUP_AND_PERIPH_ENABLE
  * @retval NONE
  */
__STATIC_INLINE void KS_Enable(KSCAN_T *ks,FunctionalState NewState,uint32_t func)
{
    (NewState != DISABLE)?((ks)->KS_EN |= func):((ks)->KS_EN &= ~func);
}


/**
  * @brief  This function is set keyscan input/output enable function
  * @param  ks: where ks is a keyscan peripheral base address
  * @param  NewState: new state of the keyscan peripheral
  * @param  func: function select,input range 0~3f
  * @retval NONE
  */
__STATIC_INLINE void KS_InputEnable(KSCAN_T *ks,FunctionalState NewState,uint32_t func)
{
    (NewState != DISABLE)?((ks)->KS_IO_CFG |= func):((ks)->KS_IO_CFG &= ~func);
}

__STATIC_INLINE void KS_OutputEnable(KSCAN_T *ks,FunctionalState NewState,uint32_t func)
{
    (NewState != DISABLE)?((ks)->KS_IO_CFG |= (func << 6)):((ks)->KS_IO_CFG &= ~(func << 6));
}

/**
  * @brief  This function is used to check keyscan status
  * @param  ks: where ks is a keyscan peripheral base address
  * @param  NewState: new state of the keyscan peripheral
  * @retval NONE
  */
__STATIC_INLINE void KS_IntEnable(KSCAN_T *ks,FunctionalState NewState)
{
    (NewState != DISABLE)?((ks)->KS_INT_CFG |= KS_INT_ENABLE_Msk):((ks)->KS_INT_CFG &= ~KS_INT_ENABLE_Msk);
}

/**
  * @brief  This function is used to check keyscan status
  * @param  ks: where ks is a keyscan peripheral base address
  * @param  func: status select
  *                              KS_INT_FLAG_Msk
  *                              KS_FLAG_Msk
  * @retval NONE
  */
__STATIC_INLINE bool KS_StatusCheck(KSCAN_T *ks,uint32_t func)
{
    return ((ks)->KS_INT_CFG & func)?(true):(false);
}

__STATIC_INLINE void KS_ClearFlag(KSCAN_T *ks,uint32_t func)
{
    (ks)->KS_INT_CFG |= func;
}
/**
  * @brief  This function is used to set keyscan polarity
  * @param  ks: where ks is a keyscan peripheral base address
  * @param  func: polarity select
  *                              KS_POLARITY_HIGH
  * @retval NONE
  */
__STATIC_INLINE void KS_SetKeyscanPolarity(KSCAN_T *ks,FunctionalState NewState)
{
    (NewState != DISABLE)?((ks)->KS_CFG |= KS_POLARITY_VALID_HIGH_Msk):((ks)->KS_CFG &= ~KS_POLARITY_VALID_HIGH_Msk);
}

/**
  * @brief  This function is used to clear all key status enable
  * @param  ks: where ks is a keyscan peripheral base address
  * @param  NewState: new state of the keyscan peripheral
  * @retval NONE
  */
__STATIC_INLINE void KS_ClearKeyscanStatus(KSCAN_T *ks,FunctionalState NewState)
{
    (NewState != DISABLE)?((ks)->KS_CFG |= KS_STATUS_CLEAR_Msk):((ks)->KS_CFG &= ~KS_STATUS_CLEAR_Msk);
}

/**
  * @brief  This function is used to set keyscan interval time
  * @param  ks: where ks is a keyscan peripheral base address
  * @param  func: interval time select
  *                              KS_INTERVAL_TIME_CLK_1   
  *                              KS_INTERVAL_TIME_CLK_2   
  *                              KS_INTERVAL_TIME_CLK_4   
  *                              KS_INTERVAL_TIME_CLK_8   
  *                              KS_INTERVAL_TIME_CLK_16  
  *                              KS_INTERVAL_TIME_CLK_32  
  *                              KS_INTERVAL_TIME_CLK_64  
  *                              KS_INTERVAL_TIME_CLK_128 
  *                              KS_INTERVAL_TIME_CLK_256 
  *                              KS_INTERVAL_TIME_CLK_512 
  *                              KS_INTERVAL_TIME_CLK_1024
  *                              KS_INTERVAL_TIME_CLK_2048
  *                              KS_INTERVAL_TIME_CLK_4K  
  *                              KS_INTERVAL_TIME_CLK_8K  
  *                              KS_INTERVAL_TIME_CLK_16K 
  *                              KS_INTERVAL_TIME_CLK_32K 
  * @retval NONE
  */
__STATIC_INLINE void KS_SetFrameInterval(KSCAN_T *ks,uint32_t func)
{
    (ks)->KS_CFG = ((ks)->KS_CFG & ~KS_SCAN_INTERVAL_Msk) | (func << KS_SCAN_INTERVAL_Pos);
}
__STATIC_INLINE uint32_t KS_GetFrameInterval(KSCAN_T *ks)
{
    return (((ks)->KS_CFG & KS_SCAN_INTERVAL_Msk) >> KS_SCAN_INTERVAL_Pos);
}

__STATIC_INLINE void KS_SetRowInterval(KSCAN_T *ks,uint32_t func)
{
    (ks)->KS_CFG = ((ks)->KS_CFG & ~KS_ROW_INTERVAL_Msk) | (func << KS_ROW_INTERVAL_Pos);
}
__STATIC_INLINE uint32_t KS_GetRowInterval(KSCAN_T *ks)
{
    return (((ks)->KS_CFG & KS_ROW_INTERVAL_Msk) >> KS_ROW_INTERVAL_Pos);
}

__STATIC_INLINE void KS_SetDebounceTime(KSCAN_T *ks,uint32_t func)
{
    (ks)->KS_CFG = ((ks)->KS_CFG & ~KS_DEBOUNCE_TIME_Msk) | (func << KS_DEBOUNCE_TIME_Pos);
}
__STATIC_INLINE uint32_t KS_GetDebounceTime(KSCAN_T *ks)
{
    return (((ks)->KS_CFG & KS_DEBOUNCE_TIME_Msk) >> KS_DEBOUNCE_TIME_Pos);
}

__STATIC_INLINE void KS_WaitScanFinish(KSCAN_T *ks,bool enable)
{
    (enable) ? (ks->KS_EN |= KS_DLY_DISABLE_Msk) : (ks->KS_EN &= ~KS_DLY_DISABLE_Msk);
}

uint32_t KS_ReadKeyRowInfo(KSCAN_T *ks,uint8_t rowIdx);
bool KS_IsKeyPressed(KSCAN_T *ks,uint8_t rowIdx,uint8_t colIdx);

#ifdef __cplusplus
}
#endif

#endif //__PAN_KSCAN_H__

/*** (C) COPYRIGHT 2020 Panchip Technology Corp. ***/
