 /*
 * Copyright (c) 2013 - 2016, Freescale Semiconductor, Inc.
 * Copyright 2016-2017 NXP
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef _NT_PROXI_PRV_H_
#define _NT_PROXI_PRV_H_

/**
 * \defgroup proxi_private Proxi Control
 * \ingroup controls_private
 *
 * Proxi control enables the detection of a finger or object presence in the 
 * near field of the electrode, so that the approaching finger/hand can be detected
 * without direct electrode touch needed. Moreover, the proximity position and 
 * direction of the movement can be evaluated for each proximity electrode. 
 * It is represented by the nt_control structure.
 *
 * The Proxi control uses a single or a set of discrete electrodes to enable the calculation of finger
 * proximity position within a near field area. If more electrodes are enabled for Proximity control,
 * the proxi detection algorithm processes each electrode separately and localizes the electrode
 * with the highest delta signal to detect the maximum proximity electrode from the group 
 * for single signal requirement to process for whole group. Signals from each electrode
 * is then used for evaluation of the proximity position, movement and its direction.
 * The electrode index with maximum proximity is stored to buffer each max. proximity
 * electrode index change. The history of max proximity changes consists of same number of steps as
 * number of proximity electrodes. The history stored in buffer can be used for simple gesture 
 * evaluation so that the buffered history is compared with stored histories (stored gesture) and 
 * in case of sameness the gesture is recognized. Using this feature not only vertical movement but 
 * the horizontal movement can be recognized as well. The gesture can be stored from captured finger 
 * movement by modifying gesture number variable which store the last buffer gesture to gesture array.
 * Another way to store gesture is to write the gestures directly Proxi configuration as the array. 
 * Such gestures will be copied from flash to ram memory in the Init function. 
 *
 * The Proxi control provides Position, Direction, and Displacement values of each proximity electrodes 
 * and buffered history of the max proximity changes in time. It can generate event callbacks when
 * finger Movement, Initial-touch, Release is detected for each electrode and if gesture is recognized.
 * The image below show proxi electrode functionality.
 * \image html proxi.png "Proxi Electrode"
 * \image latex proxi.png "Proxi Electrode"
 *
 * \{
 */
 
#include "nt_controls.h"
#include "nt_types.h"
#include "nt_setup.h"    

#ifndef NT_PROXI_ELECTRODE 
    #define NT_PROXI_ELECTRODE 1
    #warning "The NT_PROXI_ELECTRODE macro was not defined! Please define in nt_setup.h otherwise default value 1 will be used" 
#endif     
#ifndef NT_PROXI_GESTURES 
    #define NT_PROXI_GESTURES 0
    #warning "The NT_PROXI_GESTURES macro was not defined! Please define in nt_setup.h otherwise default value 0 will be used" 
#endif   
     
/* forward declaration */
struct nt_control_proxi;
static inline void _nt_control_proxi_set_flag(uint32_t *electrode, uint32_t flags);
static inline void _nt_control_proxi_clear_flag(uint32_t *electrode, uint32_t flags);
static inline uint32_t _nt_control_proxi_get_flag(uint32_t *electrode, uint32_t flags);

/** 
 * Proxi Proximity flags. 
 */
enum nt_control_prox_flags 
{
    NT_PROXI_DIRECTION_FLAG        = 1 << NT_FLAGS_SPECIFIC_SHIFT(0), /*!< Proxi direction flag. */
    NT_PROXI_MOVEMENT_FLAG         = 1 << NT_FLAGS_SPECIFIC_SHIFT(1), /*!< Proxi movement flag.*/
    NT_PROXI_TOUCH_FLAG            = 1 << NT_FLAGS_SPECIFIC_SHIFT(2), /*!< Proxi touch flag. */
    NT_PROXI_RELEASE_FLAG          = 1 << NT_FLAGS_SPECIFIC_SHIFT(3), /*!< Proxi release flag. */
};

/**
 *  The Proxi RAM structure used to store volatile parameters of the control.
 *
 *  You must allocate this structure and put a pointer into the nt_control_proxi
 *  structure when it is being registered in the system.
 */
struct nt_control_proxi_data {
    nt_control_proxi_callback callback;                       /*!< Proxi callback handler. */
    int32_t                   proxi_max[NT_PROXI_ELECTRODE];  /*!< Max. proximity for each electrode */       
    int32_t                   proxi_k_1[NT_PROXI_ELECTRODE];  /*!< Proximity value from previous step for each electrode */      
    uint32_t                  proxi_flags[NT_PROXI_ELECTRODE];/*!< State flags for each electrode */
    uint32_t                  index_k_1;                      /*!< Previous maximum proximity key index */
    int32_t                   proximity;                      /*!< Maximum proximity value of the index electrode */
    uint32_t                  index;                          /*!< Proximity active key index with maximum proximity */                    
    #if NT_PROXI_GESTURES > 0
    uint32_t                  gesture[NT_PROXI_GESTURES];     /*!< Stored gesture array */                   
    uint32_t                  buffer;                         /*!< Buffer to store index key with maximum proximity each step to hex symbol from right to left */
    uint8_t                   buffer_index;                   /*!< Position in buffer for read or write buffer hex symbol access */
    uint8_t                   selected_gesture;               /*!< Selected gesture number for storing gesture */    
    uint8_t                   recognized_gesture;             /*!< Recognized gesture number to indicate*/
    uint8_t                   gesture_memory;                 /*!< Variable select the memory for stored gesture. RAM will be used used if selected_gesture > 0 was made */  
    #endif /* NT_PROXI_GESTURES > 0 */ 
};

/**
 * \internal
 * \brief Set assigned flag for specific electrodes.
 * \param electrode The electrode number to specify flags array index.
 * \param flag The flag to be set.
 * \return none
 *
 * This function set the specified flag in the specific electrode.
 */
static inline void _nt_control_proxi_set_flag(uint32_t *electrode, uint32_t flags)
{
    *electrode |= flags;
}

/**
 * \internal
 * \brief Clear assigned flag for specific electrodes.
 * \param electrode The electrode number to specify flags array index.
 * \param flag The flag to be cleared.
 * \return none
 *
 * This function clear the specified flag in the specific electrode.
 */
static inline void _nt_control_proxi_clear_flag(uint32_t *electrode, uint32_t flags)
{
    *electrode &= ~flags;
}

/**
 * \internal
 * \brief Get assigned flag from specific electrodes.
 * \param electrode The electrode number to specify flags array index.
 * \param flag The flag to be set.
 * \return flag value
 *
 * This function read the specified flag in the specific electrode.
 */
static inline uint32_t _nt_control_proxi_get_flag(uint32_t *electrode, uint32_t flags)
{
    return (*electrode & flags);
}

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

/** \} end of proxi_private group */


#endif /* _NT_PROXI_PRV_H_ */
