diff src/cs/drivers/drv_app/kpd/kpd_process_internal_msg.c @ 0:b6a5e36de839

src/cs: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:39:26 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cs/drivers/drv_app/kpd/kpd_process_internal_msg.c	Sun Jul 15 04:39:26 2018 +0000
@@ -0,0 +1,632 @@
+/**
+ * @file   kpd_process_internal_msg.c
+ *
+ * Implementation of Keypad functions.
+ * These functions implement the keypad processing for all the messages the
+ * keypad task can receive.
+ *
+ * @author   Laurent Sollier (l-sollier@ti.com)
+ * @version 0.1
+ */
+
+/*
+ * History:
+ *
+ *   Date          Author       Modification
+ *  ----------------------------------------
+ *  10/10/2001     L Sollier    Create
+ *
+ *
+ * (C) Copyright 2001 by Texas Instruments Incorporated, All Rights Reserved
+ */
+
+#include "kpd/kpd_api.h"
+#include "kpd/kpd_env.h"
+#include "kpd/kpd_i.h"
+#include "kpd/kpd_virtual_key_table_mgt.h"
+#include "kpd/kpd_physical_key_def.h"
+
+#include "rvf/rvf_api.h"
+#include "rvm/rvm_use_id_list.h"
+
+#include <string.h>
+
+/* External declaration */
+extern T_KPD_ENV_CTRL_BLK* kpd_env_ctrl_blk;
+
+
+/* Definition of the wait time in the loop */
+#ifdef _WINDOWS
+   #define WAIT_TIME_LOOP (50)
+#else
+   #define WAIT_TIME_LOOP (10)
+#endif
+
+
+/* This structure gathers informations about one physical key Id.
+   It define if subscriber is notified for this physical key */
+typedef struct {  UINT32   subscriber_mask;
+               }  T_PHYSICAL_KEY_MASK;
+
+
+/** Definition of a set of keys with repeat keys parameters. */
+typedef struct {  UINT8                nb_notified_keys;
+                  UINT16               long_press_time; /* in ms */
+                  UINT16               repeat_time; /* in ms */
+                  T_KPD_NOTIF_LEVEL    notif_level[KPD_NB_PHYSICAL_KEYS];
+               } T_PHYSICAL_KEY_PARAM_TABLE;
+
+
+/* This structure gather general informations about subscriber id */
+typedef struct {  T_RV_RETURN return_path;
+                  T_KPD_MODE mode;
+                  T_PHYSICAL_KEY_PARAM_TABLE notified_keys;
+               } T_SUBSCRIBER_INFOS;
+
+
+/* Informations for all the physical keys Id.
+   This variable is updated each time a client subscribe to the keypad driver,
+   unsubscribe, or change notification key level.
+   Warn that position of the physical key Id is implicit cause of the rule
+   used to define the vpm table */
+static T_PHYSICAL_KEY_MASK physical_key_mask[KPD_NB_PHYSICAL_KEYS] = {0};
+
+/* Informations for all the subscribers */
+static T_SUBSCRIBER_INFOS* subscriber_infos[KPD_MAX_SUBSCRIBER] = {0};
+
+
+
+/**
+ * @name Functions implementation
+ *
+ */
+/*@{*/
+
+/**
+ * function: kpd_return_path_already_defined
+ */
+static BOOL kpd_return_path_already_defined(T_RV_RETURN return_path)
+{
+   UINT8 i;
+   BOOL ret = FALSE;
+
+   for (i = 0; i < KPD_MAX_SUBSCRIBER; i++)
+      if ( subscriber_infos[i] != 0 )
+         if (subscriber_infos[i]->return_path.callback_func != 0)
+         {
+            if (subscriber_infos[i]->return_path.callback_func == return_path.callback_func)
+            {
+               ret = TRUE;
+               break;
+            }
+         }
+         else
+         {
+            if (subscriber_infos[i]->return_path.addr_id == return_path.addr_id)
+            {
+               ret = TRUE;
+               break;
+            }
+         }
+
+   return ret;
+}
+
+/**
+ * function: kpd_subscribe_i
+ */
+T_RV_RET kpd_subscribe_i(T_SUBSCRIBER_ID subscriber_id,
+                         T_KPD_MODE mode,
+                         T_KPD_VIRTUAL_KEY_TABLE* notified_keys,
+                         T_RV_RETURN return_path)
+{
+   INT8 i, position;
+   T_RVF_MB_STATUS mb_status;
+   T_RV_RET ret;
+
+   /* Check the validity of the key table */
+   ret = kpd_check_key_table(notified_keys, mode);
+
+   if (ret != RV_OK)
+   {
+      /* Remove subscriber id because id was reserved */
+      kpd_remove_subscriber(subscriber_id);
+
+      /* Send error message */
+      kpd_send_status_message(KPD_SUBSCRIBE_OP, KPD_ERR_KEYS_TABLE, return_path);
+   }
+   else
+   {
+      if (kpd_return_path_already_defined(return_path) == TRUE)
+      {
+         /* Remove subscriber id because id was reserved */
+         kpd_remove_subscriber(subscriber_id);
+
+         /* Send error message */
+         kpd_send_status_message(KPD_SUBSCRIBE_OP, KPD_ERR_RETURN_PATH_EXISTING, return_path);
+
+         ret = RV_INVALID_PARAMETER;
+      }
+      else
+      {      
+         /* Update subscriber informations */
+         /* ------------------------------ */
+
+         /* Reserve memory for subscriber informations */
+         mb_status = rvf_get_buf (kpd_env_ctrl_blk->prim_id,
+                                  sizeof(T_SUBSCRIBER_INFOS),
+                                  (void **) &subscriber_infos[subscriber_id]);
+
+         if (mb_status != RVF_RED) /* Memory allocation success */
+         {
+            /* Initialize structure */
+            memset(subscriber_infos[subscriber_id], 0, sizeof(T_SUBSCRIBER_INFOS));
+
+            /* Fill the subscriber structure */
+            subscriber_infos[subscriber_id]->mode = mode;
+            subscriber_infos[subscriber_id]->return_path = return_path;
+            subscriber_infos[subscriber_id]->notified_keys.nb_notified_keys = notified_keys->nb_notified_keys;
+            subscriber_infos[subscriber_id]->notified_keys.long_press_time = 0;
+            subscriber_infos[subscriber_id]->notified_keys.repeat_time = 0;
+            for (i = 0; i < notified_keys->nb_notified_keys; i++)
+            {
+               /* Retrieve physical key Id from virtual key_id */
+               kpd_retrieve_virtual_key_position(  notified_keys->notified_keys[i],
+                                                   mode,
+                                                   &position);
+
+               subscriber_infos[subscriber_id]->notified_keys.notif_level[position] = KPD_RELEASE_NOTIF;
+            }
+
+            /* Update link (ID <-> key) */
+            /* ------------------------ */
+            for (i = 0; i < notified_keys->nb_notified_keys; i++)
+            {
+               /* Retrieve position in vpm table */
+               kpd_retrieve_virtual_key_position(notified_keys->notified_keys[i],
+                                                 mode,
+                                                 &position);
+
+               /* Update subscriber mask for the physical key */
+               physical_key_mask[position].subscriber_mask |= (1<<subscriber_id);
+
+            }
+
+            /* Send success message to suscriber */
+            kpd_send_status_message(KPD_SUBSCRIBE_OP, KPD_PROCESS_OK, return_path);
+         }
+         else
+         {
+            KPD_SEND_TRACE("KPD: Memory allocation error", RV_TRACE_LEVEL_ERROR);
+
+            /* Remove subscriber id because id was reserved */
+            kpd_remove_subscriber(subscriber_id);
+
+            /* Send error message to suscriber */
+            kpd_send_status_message(KPD_SUBSCRIBE_OP, KPD_ERR_INTERNAL, return_path);
+         }
+      }
+   }
+
+   return RV_OK;
+}
+
+
+/**
+ * function: kpd_unsubscribe_i
+ */
+T_RV_RET kpd_unsubscribe_i(T_SUBSCRIBER_ID subscriber_id)
+{
+   UINT8 i;
+
+   /* Delete subscriber informations */
+   rvf_free_buf(subscriber_infos[subscriber_id]);
+   subscriber_infos[subscriber_id] = 0;
+
+   /* Delete link (ID <-> key) */
+   for (i = 0; i < KPD_NB_PHYSICAL_KEYS; i++)
+   {
+      physical_key_mask[i].subscriber_mask &= ~(1<<subscriber_id);
+   }
+
+   /* If the subscriber is the keypad owner, this privilege is unset */
+   if (kpd_is_owner_keypad(subscriber_id) == TRUE)
+      kpd_set_keypad_mode(MN_MODE);
+
+   return RV_OK;
+}
+
+
+/**
+ * function: kpd_define_key_notification_i
+ */
+T_RV_RET kpd_define_key_notification_i(T_SUBSCRIBER_ID subscriber_id,
+                                       T_KPD_VIRTUAL_KEY_TABLE* notif_key_table,
+                                       T_KPD_NOTIF_LEVEL notif_level,
+                                       UINT16 long_press_time,
+                                       UINT16 repeat_time)
+{
+   T_RV_RET ret = RV_OK;
+   UINT8 i;
+   INT8 position;
+
+   /* Check the validity of the key table */
+   ret = kpd_check_key_table(notif_key_table, subscriber_infos[subscriber_id]->mode);
+
+   if (ret != RV_OK)
+   {
+      /* Send error message */
+      kpd_send_status_message(KPD_REPEAT_KEYS_OP, KPD_ERR_KEYS_TABLE, subscriber_infos[subscriber_id]->return_path);
+
+   }
+   else
+   {
+      /* Update subscriber informations */
+      /* ------------------------------ */
+      subscriber_infos[subscriber_id]->notified_keys.long_press_time = long_press_time*100;
+      subscriber_infos[subscriber_id]->notified_keys.repeat_time = repeat_time*100;
+
+      for (i = 0; i < notif_key_table->nb_notified_keys; i++)
+      {
+         /* Retrieve physical key Id from virtual key_id */
+         kpd_retrieve_virtual_key_position(  notif_key_table->notified_keys[i],
+                                             subscriber_infos[subscriber_id]->mode,
+                                             &position);
+
+         /* Check if subscriber have asked notification for this key at subscription */
+         if ( physical_key_mask[position].subscriber_mask & (1<<subscriber_id) )
+            subscriber_infos[subscriber_id]->notified_keys.notif_level[position] = notif_level;
+      }
+
+      /* Send success message to suscriber */
+      kpd_send_status_message(KPD_REPEAT_KEYS_OP, KPD_PROCESS_OK, subscriber_infos[subscriber_id]->return_path);
+   }
+
+   return ret;
+}
+
+
+/**
+ * function: kpd_change_mode_i
+ */
+T_RV_RET kpd_change_mode_i(T_SUBSCRIBER_ID subscriber_id,
+                           T_KPD_VIRTUAL_KEY_TABLE* notified_keys,
+                           T_KPD_MODE new_mode)
+{
+   UINT8 i;
+   INT8 position;
+   T_RV_RET ret;
+
+   /* Check the validity of the key table */
+   ret = kpd_check_key_table(notified_keys, new_mode);
+
+   if (ret != RV_OK)
+   {
+      /* Send error message */
+      kpd_send_status_message(KPD_CHANGE_MODE_OP, KPD_ERR_KEYS_TABLE, subscriber_infos[subscriber_id]->return_path);
+   }
+   else
+   {
+      /* Delete link (ID <-> key) for old mode*/
+      for (i = 0; i < KPD_NB_PHYSICAL_KEYS; i++)
+      {
+         physical_key_mask[i].subscriber_mask &= ~(1<<subscriber_id);
+         subscriber_infos[subscriber_id]->notified_keys.notif_level[i] = KPD_NO_NOTIF;
+      }
+
+      /* Update subscriber structure */
+      subscriber_infos[subscriber_id]->mode = new_mode;
+      subscriber_infos[subscriber_id]->notified_keys.nb_notified_keys = notified_keys->nb_notified_keys;
+      subscriber_infos[subscriber_id]->notified_keys.long_press_time = 0;
+      subscriber_infos[subscriber_id]->notified_keys.repeat_time = 0;
+      for (i = 0; i < notified_keys->nb_notified_keys; i++)
+      {
+         /* Retrieve physical key Id from virtual key_id */
+         kpd_retrieve_virtual_key_position(  notified_keys->notified_keys[i],
+                                             new_mode,
+                                             &position);
+
+         subscriber_infos[subscriber_id]->notified_keys.notif_level[position] = KPD_RELEASE_NOTIF;
+ 
+         /* Update link (ID <-> key) for new mode */
+         physical_key_mask[position].subscriber_mask |= (1<<subscriber_id);
+      }
+
+      /* If the subscriber is the keypad owner, this privilege is unset */
+      if (kpd_is_owner_keypad(subscriber_id) == TRUE)
+         kpd_set_keypad_mode(MN_MODE);
+
+      /* Send success message to suscriber */
+      kpd_send_status_message(KPD_CHANGE_MODE_OP, KPD_PROCESS_OK, subscriber_infos[subscriber_id]->return_path);
+   }
+
+   return RV_OK;
+}
+
+/**
+ * function: kpd_own_keypad_i
+ */
+T_RV_RET kpd_own_keypad_i(T_SUBSCRIBER_ID subscriber_id,
+                          BOOL is_keypad_owner,
+                          T_KPD_VIRTUAL_KEY_TABLE* keys_owner)
+{
+   INT8 position;
+   UINT8 i;
+
+   if (is_keypad_owner == FALSE)
+   {
+      /* Check if subscriber Id own the keypad */
+      if (kpd_is_owner_keypad(subscriber_id))
+      {
+         kpd_set_keypad_mode(MN_MODE);
+
+         /* Send success message to suscriber */
+         kpd_send_status_message(KPD_OWN_KEYPAD_OP, KPD_PROCESS_OK, subscriber_infos[subscriber_id]->return_path);
+
+      }
+      else
+         kpd_send_status_message(KPD_OWN_KEYPAD_OP, KPD_ERR_ID_OWNER_KEYPAD, subscriber_infos[subscriber_id]->return_path);
+   }
+   else
+   {
+      /* Check if keypad driver is already in single-notified mode */
+      if (kpd_get_keypad_mode() == SN_MODE)
+      {
+         /* Send error message to suscriber */
+         kpd_send_status_message(KPD_OWN_KEYPAD_OP, KPD_ERR_SN_MODE, subscriber_infos[subscriber_id]->return_path);
+      }
+      else
+      {
+         /* Check if all the keys defined in keys_owner are notified to the subsciber */
+         for (i = 0; i < keys_owner->nb_notified_keys; i++)
+         {
+            /* Retrieve physical key Id from virtual key_id */
+            kpd_retrieve_virtual_key_position(  keys_owner->notified_keys[i],
+                                                subscriber_infos[subscriber_id]->mode,
+                                                &position);
+
+            if ( subscriber_infos[subscriber_id]->notified_keys.notif_level == KPD_NO_NOTIF )
+            {
+               /* Send error message to suscriber */
+               kpd_send_status_message(KPD_OWN_KEYPAD_OP, KPD_ERR_KEYS_TABLE, subscriber_infos[subscriber_id]->return_path);
+               return RV_INTERNAL_ERR;
+            }
+         }
+
+         /* Set keypad driver in single-notified mode */
+         kpd_set_keypad_mode(SN_MODE);
+
+         /* Set owner keypad Id */
+         kpd_set_owner_keypad_id(subscriber_id);
+
+         /* Set list of keys used by the keypad owner. Thsi list is is a sub-list
+            of the keys defined at subscription. For these keys, the keypad owner will
+            be the only notified. */
+         kpd_set_keys_in_sn_mode(keys_owner, subscriber_infos[subscriber_id]->mode);
+
+         /* Send success message to suscriber */
+         kpd_send_status_message(KPD_OWN_KEYPAD_OP, KPD_PROCESS_OK, subscriber_infos[subscriber_id]->return_path);
+      }
+   }
+
+   return RV_OK;
+}
+
+/**
+ * function: kpd_set_key_config_i
+ */
+T_RV_RET kpd_set_key_config_i(T_SUBSCRIBER_ID subscriber_id,
+                              T_KPD_VIRTUAL_KEY_TABLE* reference_keys,
+                              T_KPD_VIRTUAL_KEY_TABLE* new_keys)
+{
+#ifdef KPD_MODE_CONFIG
+   UINT8 i;
+
+   /* Check if some subscriber use the configurable mode */
+   for (i = 0; i < KPD_MAX_SUBSCRIBER; i++)
+   {
+      if ( (subscriber_infos[i] != 0) && (subscriber_infos[i]->mode == KPD_MODE_CONFIG) )
+      {
+         /* Send error message to suscriber */
+         kpd_send_status_message(KPD_SET_CONFIG_MODE_OP,
+                                 KPD_ERR_CONFIG_MODE_USED,
+                                 subscriber_infos[subscriber_id]->return_path);
+         return RV_OK;
+      }
+   }
+
+   /* Set keys in configurable mode */
+   kpd_define_new_config(reference_keys, new_keys);
+
+   /* Send success message to suscriber */
+   kpd_send_status_message(KPD_SET_CONFIG_MODE_OP,
+                           KPD_PROCESS_OK,
+                           subscriber_infos[subscriber_id]->return_path);
+
+#endif
+
+   return RV_OK;
+}
+
+
+/**
+ * function: kpd_process_key_pressed_i
+ */
+void kpd_process_key_pressed_i(T_KPD_PHYSICAL_KEY_ID physical_key_pressed_id)
+{
+   UINT8 i;
+   UINT32 loop_counter = 0;
+   UINT16 counter[KPD_MAX_SUBSCRIBER] = {0};
+   T_KPD_PHYSICAL_KEY_ID key_id = physical_key_pressed_id;
+
+   KPD_SEND_TRACE_PARAM("KPD: kpd_process_key_pressed_i ", key_id, RV_TRACE_LEVEL_DEBUG_LOW);
+
+   /* Notify subscribers of the key pressed */
+   for (i = 0; i < KPD_MAX_SUBSCRIBER; i++) /* To do : Loop on the real number of subscribers */
+   { /* To do : Test on the physical_key_mask (to ensure subscriber is subscribed for this key) */
+      if ( (subscriber_infos[i]!=0) && (subscriber_infos[i]->notified_keys.notif_level[key_id] & KPD_FIRST_PRESS_NOTIF) )
+      {
+         kpd_send_key_event_message(key_id, KPD_KEY_PRESSED,
+                                    KPD_FIRST_PRESS, subscriber_infos[i]->mode,
+                                    subscriber_infos[i]->return_path);
+      }
+   }
+
+   /* If key pressed is the PWR key, the message "Released key" is immediately sent */
+   if (key_id != KPD_SHORT_PRESS_PWR_KEY)
+   {
+      /* Loop infinitely until key is released */
+      do
+      {
+         rvf_delay(RVF_MS_TO_TICKS(WAIT_TIME_LOOP));
+         physical_key_pressed_id = kpd_scan_keypad();
+         loop_counter++;
+
+         /* Send message for repeat key */
+         for (i = 0; i < KPD_MAX_SUBSCRIBER; i++)
+         {
+            if ( (subscriber_infos[i]!=0) && (subscriber_infos[i]->notified_keys.notif_level[key_id] & (KPD_LONG_PRESS_NOTIF|KPD_INFINITE_REPEAT_NOTIF)) )
+            {
+               if ((counter[i] == 0) && (WAIT_TIME_LOOP*loop_counter >= subscriber_infos[i]->notified_keys.long_press_time) )
+               {
+                  kpd_send_key_event_message(key_id, KPD_KEY_PRESSED,
+                                             KPD_LONG_PRESS, subscriber_infos[i]->mode,
+                                             subscriber_infos[i]->return_path);
+                  counter[i] ++;
+               }
+               else if (subscriber_infos[i]->notified_keys.notif_level[key_id] & KPD_INFINITE_REPEAT_NOTIF)
+               {
+                  if (WAIT_TIME_LOOP*loop_counter >= (UINT32)((counter[i]*subscriber_infos[i]->notified_keys.repeat_time + subscriber_infos[i]->notified_keys.long_press_time)) )
+                  {
+                     kpd_send_key_event_message(key_id, KPD_KEY_PRESSED,
+                                                KPD_REPEAT_PRESS, subscriber_infos[i]->mode,
+                                                subscriber_infos[i]->return_path);
+                     counter[i] ++;
+                  }
+               }
+            }
+         }
+
+      } while (physical_key_pressed_id != KPD_PKEY_NULL);
+   }
+
+   /* Notify subscribers of the key released */
+   for (i = 0; i < KPD_MAX_SUBSCRIBER; i++)
+   {
+      if ( (subscriber_infos[i]!=0) && (subscriber_infos[i]->notified_keys.notif_level[key_id] & KPD_RELEASE_NOTIF) )
+      {
+         kpd_send_key_event_message(key_id, KPD_KEY_RELEASED,
+                                    KPD_INSIGNIFICANT_VALUE, subscriber_infos[i]->mode,
+                                    subscriber_infos[i]->return_path);
+      }
+   }
+
+   /* On board,this function unmask keypad interrupt
+      On Riviera tool, this function is empty        */
+   if (key_id != KPD_SHORT_PRESS_PWR_KEY)
+   {
+#if (CHIPSET == 12)
+      kpd_software_reset();
+      kpd_init_ctrl_reg(1, HARDWARE_DECODING, KPD_CLK_DIV32,
+                        KPD_DETECTION_DISABLED, KPD_DETECTION_DISABLED,
+                        KPD_DETECTION_DISABLED, KPD_DETECTION_DISABLED);
+#endif
+
+      kpd_acknowledge_key_pressed();
+   }
+}
+
+
+/**
+ * function: kpd_process_key_pressed_sn_mode_i
+ */
+void kpd_process_key_pressed_sn_mode_i(T_KPD_PHYSICAL_KEY_ID physical_key_pressed_id)
+{
+   T_SUBSCRIBER_ID owner_keypad_id = kpd_get_owner_keypad_id();
+   T_KPD_PHYSICAL_KEY_ID key_id = physical_key_pressed_id;
+   UINT32 loop_counter = 0;
+   UINT16 counter = 0;
+
+   if ( subscriber_infos[owner_keypad_id]->notified_keys.notif_level[key_id] & KPD_FIRST_PRESS_NOTIF )
+   {
+      /* Notify subscribers of the key pressed */
+       kpd_send_key_event_message(key_id, KPD_KEY_PRESSED,
+                                  KPD_FIRST_PRESS, subscriber_infos[owner_keypad_id]->mode,
+                                  subscriber_infos[owner_keypad_id]->return_path);
+   }
+
+   /* If key pressed is the PWR key, the message "Released key" is immediately sent */
+   if (key_id != KPD_SHORT_PRESS_PWR_KEY)
+   {
+      /* Loop infinitely until key is released */
+      do
+      {
+         rvf_delay(RVF_MS_TO_TICKS(WAIT_TIME_LOOP));
+         physical_key_pressed_id = kpd_scan_keypad();
+         loop_counter++;
+
+         /* Send message for repeat key */
+         if (subscriber_infos[owner_keypad_id]->notified_keys.notif_level[key_id] & (KPD_LONG_PRESS_NOTIF|KPD_INFINITE_REPEAT_NOTIF))
+         {
+            if ((counter == 0) && (WAIT_TIME_LOOP*loop_counter >= subscriber_infos[owner_keypad_id]->notified_keys.long_press_time) )
+            {
+               kpd_send_key_event_message(key_id, KPD_KEY_PRESSED,
+                                          KPD_LONG_PRESS, subscriber_infos[owner_keypad_id]->mode,
+                                          subscriber_infos[owner_keypad_id]->return_path);
+               counter ++;
+            }
+            else if (subscriber_infos[owner_keypad_id]->notified_keys.notif_level[key_id] & KPD_INFINITE_REPEAT_NOTIF)
+            {
+               if (WAIT_TIME_LOOP*loop_counter >= (UINT32)((counter*subscriber_infos[owner_keypad_id]->notified_keys.repeat_time + subscriber_infos[owner_keypad_id]->notified_keys.long_press_time)) )
+               {
+                  kpd_send_key_event_message(key_id, KPD_KEY_PRESSED,
+                                             KPD_REPEAT_PRESS, subscriber_infos[owner_keypad_id]->mode,
+                                             subscriber_infos[owner_keypad_id]->return_path);
+                  counter ++;
+               }
+            }
+         }
+
+      } while (physical_key_pressed_id != KPD_PKEY_NULL);
+   }
+
+   if ( subscriber_infos[owner_keypad_id]->notified_keys.notif_level[key_id] & KPD_RELEASE_NOTIF )
+   {
+      /* Notify subscribers of the key released */
+      kpd_send_key_event_message(key_id, KPD_KEY_RELEASED,
+                                 KPD_INSIGNIFICANT_VALUE, subscriber_infos[owner_keypad_id]->mode,
+                                 subscriber_infos[owner_keypad_id]->return_path);
+   }
+
+   /* On board,this function unmask keypad interrupt
+      On Riviera tool, this function authorize to send new messages to keypad task */
+   if (key_id != KPD_SHORT_PRESS_PWR_KEY)
+   {
+#if (CHIPSET == 12)
+      kpd_software_reset();
+      kpd_init_ctrl_reg(1, HARDWARE_DECODING, KPD_CLK_DIV32,
+                        KPD_DETECTION_DISABLED, KPD_DETECTION_DISABLED,
+                        KPD_DETECTION_DISABLED, KPD_DETECTION_DISABLED);
+#endif
+      kpd_acknowledge_key_pressed();
+   }
+}
+
+/**
+ * function: kpd_wait_for_key_release
+ */
+void kpd_wait_for_key_release(void)
+{
+   T_KPD_PHYSICAL_KEY_ID key_id;;
+
+   do
+   {
+      rvf_delay(RVF_MS_TO_TICKS(WAIT_TIME_LOOP));
+      key_id = kpd_scan_keypad();
+
+   } while (key_id != KPD_PKEY_NULL);
+
+   kpd_acknowledge_key_pressed();
+}
+
+/*@}*/