view src/cs/drivers/drv_app/kpd/kpd_handle_message.c @ 280:82665effff30

keypad boot init overhaul: handle initially held-down keys This change fixes two previous behavioural defects: 1) On Compal phones, the PWR key had to be released before the boot sequence would proceed at all - it was stuck in an endless IRQ loop at the point of Nucleus enabling interrupts, before anything else. 2) On both Compal and sane platforms including Luna, if some regular non-PWR key was held down at boot time, the boot sequence would proceed and complete normally, but all non-PWR keypad buttons would be dead for the remainder of that boot cycle. The fix is a generic solution - no Compal-specific hack ended up being needed for the special case of their idiotic PWON-to-ROW4 hw wiring.
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 24 Sep 2021 00:47:12 +0000
parents 4e78acac3d88
children
line wrap: on
line source

/**
 * @file   kpd_handle_msg.c
 *
 * Coding of the kpd_handle_msg function, which is called when the SWE
 * receives a new message.
 *
 * @author   Laurent Sollier (l-sollier@ti.com)
 * @version 0.1
 */

/*
 * History:
 *
 *   Date          Author       Modification
 *  ----------------------------------------
 *  10/12/2001     L Sollier    Create
 *
 *
 * (C) Copyright 2001 by Texas Instruments Incorporated, All Rights Reserved
 */

#include "kpd/kpd_messages_i.h"
#include "kpd/kpd_scan_functions.h"
#include "kpd/kpd_process_internal_msg.h"
#include "kpd/kpd_physical_key_def.h"

#include "rv/rv_general.h"
#include "rvf/rvf_api.h"
#include "rvm/rvm_use_id_list.h"

/**
 * @name Functions implementation
 *
 */
/*@{*/

/**
 * function: kpd_handle_msg
 */
T_RV_RET kpd_handle_msg(T_RV_HDR   *msg_p)
{   
   if (msg_p != NULL)
   {
      switch (msg_p->msg_id)
      {
         case KPD_SUBSCRIBE_MSG:
         {
            T_KPD_SUBSCRIBE_MSG* msg_subscribe_p= (T_KPD_SUBSCRIBE_MSG*) msg_p;

            KPD_SEND_TRACE_PARAM("KPD: 'Subscription' message received,Id:",
                                 msg_subscribe_p->subscription_info.subscriber_id,
                                 RV_TRACE_LEVEL_DEBUG_LOW);

            kpd_subscribe_i(msg_subscribe_p->subscription_info.subscriber_id,
                            msg_subscribe_p->subscription_info.mode,
                            &msg_subscribe_p->subscription_info.notified_keys,
                            msg_subscribe_p->subscription_info.return_path);
            break;
         }
         case KPD_UNSUBSCRIBE_MSG:
         {
            T_KPD_UNSUBSCRIBE_MSG* msg_unsubscribe_p= (T_KPD_UNSUBSCRIBE_MSG*) msg_p;

            KPD_SEND_TRACE_PARAM("KPD: 'Unsubscription' message received,Id:",
                                 msg_unsubscribe_p->subscriber_id,
                                 RV_TRACE_LEVEL_DEBUG_LOW);

            kpd_unsubscribe_i(msg_unsubscribe_p->subscriber_id);
            break;
         }
         case KPD_NOTIF_KEYS_MSG:
         {
            T_KPD_NOTIF_KEYS_MSG* msg_notif_keys_p= (T_KPD_NOTIF_KEYS_MSG*) msg_p;

            KPD_SEND_TRACE("KPD: 'Notification keys level' message received",
                           RV_TRACE_LEVEL_DEBUG_LOW);

            kpd_define_key_notification_i(msg_notif_keys_p->subscriber_id,
                                          &msg_notif_keys_p->notif_key_table,
                                          msg_notif_keys_p->notif_level,
                                          msg_notif_keys_p->long_press_time,
                                          msg_notif_keys_p->repeat_time);
            break;
         }
         case KPD_CHANGE_MODE_MSG:
         {
            T_KPD_CHANGE_MODE_MSG* msg_change_mode_p= (T_KPD_CHANGE_MODE_MSG*) msg_p;

            KPD_SEND_TRACE("KPD: 'Change mode' message received:",
                           RV_TRACE_LEVEL_DEBUG_LOW);

            kpd_change_mode_i(msg_change_mode_p->subscriber_id,
                              &msg_change_mode_p->notified_keys,
                              msg_change_mode_p->new_mode);

            break;
         }
         case KPD_OWN_KEYPAD_MSG:
         {
            T_KPD_OWN_KEYPAD_MSG* msg_own_keypad_p= (T_KPD_OWN_KEYPAD_MSG*) msg_p;

            KPD_SEND_TRACE("KPD: 'Own keypad' message received",
                           RV_TRACE_LEVEL_DEBUG_LOW);

            kpd_own_keypad_i(msg_own_keypad_p->subscriber_id,
                             msg_own_keypad_p->is_keypad_owner,
                             &msg_own_keypad_p->keys_owner);

            break;
         }
         case KPD_SET_CONFIG_MODE_MSG:
         {
            T_KPD_SET_CONFIG_MODE_MSG* msg_change_mode_p= (T_KPD_SET_CONFIG_MODE_MSG*) msg_p;

            KPD_SEND_TRACE("KPD: 'Set config mode' message received",
                           RV_TRACE_LEVEL_DEBUG_LOW);

            kpd_set_key_config_i(msg_change_mode_p->subscriber_id,
                                 &msg_change_mode_p->reference_keys,
                                 &msg_change_mode_p->new_keys);

            break;
         }
         case KPD_KEY_PRESSED_MSG:
         {
            T_KPD_PHYSICAL_KEY_ID physical_key_pressed_id;
            T_KPD_KEY_PRESSED_MSG* msg_key_pressed= (T_KPD_KEY_PRESSED_MSG*) msg_p;

            KPD_SEND_TRACE_PARAM("KPD: Message key pressed received by keypad task",
                                 msg_key_pressed->value,
                                 RV_TRACE_LEVEL_DEBUG_LOW);
#ifdef _WINDOWS
            /* In case of Riviera Tool test and in order to avoid losing key event,
               key pressed Id is set in the message, and unset only when keypad task
               have read the value */
            kpd_set_key_value(msg_key_pressed->value);
#endif
            /* If there is enough memory to process the key */
            if (msg_key_pressed->key_to_process)
            {
               /* if value = KPD_SHORT_PRESS_PWR_KEY, it's PWR SWE which sent the message,
                  physical key id cannot be retrieved by function kpd_scan_keypad */
               if (msg_key_pressed->value == KPD_SHORT_PRESS_PWR_KEY)
                  physical_key_pressed_id = KPD_SHORT_PRESS_PWR_KEY;
               else
               {
#if (CHIPSET == 12)
                  kpd_init_ctrl_reg(1, SOFTWARE_MODE_ENABLE, KPD_CLK_DIV32,
                                    KPD_DETECTION_DISABLED, KPD_DETECTION_DISABLED,
                                    KPD_DETECTION_DISABLED, KPD_DETECTION_DISABLED);
#endif
                  physical_key_pressed_id = kpd_scan_keypad();
               }

               /* The processing is different if keypad is in SN mode and the key is
                  in the table of keypad owner */
               if (kpd_is_key_in_sn_mode(physical_key_pressed_id) == TRUE)
               {
                  kpd_process_key_pressed_sn_mode_i(physical_key_pressed_id);
               }
               else
               {
                  kpd_process_key_pressed_i(physical_key_pressed_id);
               }
            }
            else
            {
               KPD_SEND_TRACE("KPD: Lost key event due to memory lack",
                              RV_TRACE_LEVEL_DEBUG_HIGH);
               kpd_wait_for_key_release();
            }
            break;
         }
         default: 
         {
            /* Unknow message has been received */
            KPD_SEND_TRACE("KPD: Message received unknown",
                           RV_TRACE_LEVEL_ERROR);
            break; 
         }
      }

      /* Free message */
      rvf_free_buf(msg_p);
   }

   return RV_OK;
}

/*@}*/