⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kpd_scan_functions.c

📁 是一个手机功能的模拟程序
💻 C
字号:
/**
 * @file	kpd_scan_functions.c
 *
 * Implementation of hardware keypad interface functions.
 * These functions implement the keypad interface with the windows.
 *
 * @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 "board.cfg"

#include "nucleus.h" /* used for HISR */

#include "kpd_scan_functions.h"
#include "kpd_cfg.h"
#include "kpd_physical_key_def.h"
#include "kpd_messages_i.h"
#include "kpd_env.h"

#include "rvf_api.h"
#include "rvm_use_id_list.h"
#include "rvf_env.h"

#include "mem.h"
#include "armio.h"
#include "iq.h"

//glowing,2004-06-16,import from M188
INT8 g_norejectkeyflag = 0;

#if (CHIPSET == 12)
  #define KBR_CTRL_REG              (MEM_KEYBOARD + 0x00) /* KBR control reg */
  #define KBR_DEBOUNCING_TIME       (MEM_KEYBOARD + 0x02) /* KBR debouncing time reg */
  #define KBR_STATE_MACHINE_STATUS  (MEM_KEYBOARD + 0x0E) /* KBR state machine status reg */
  #define KBR_IN                    (MEM_KEYBOARD + 0x10) /* KBR inputs (rows) */
  #define KBR_OUT                   (MEM_KEYBOARD + 0x12) /* KBR outputs (columns) */
#endif


#if (CHIPSET == 12)
  #define KP_ROW_IN   KBR_IN
  #define KP_COL_OUT  KBR_OUT
#else
  #define KP_ROW_IN   ARMIO_KBR_IN
  #define KP_COL_OUT  ARMIO_KBR_OUT
#endif


#if (BOARD == 7)
   #define KP_ROWS      5
   #define KP_COLS      4

   const T_KPD_PHYSICAL_KEY_ID keypad_layout[KP_ROWS][KP_COLS]=
   {                           
   /* Layout of B-Sample */
   {KPD_PKEY_SOFT_LEFT,  KPD_PKEY_UP,   KPD_PKEY_DOWN, KPD_PKEY_SOFT_RIGHT},
   {KPD_PKEY_1,          KPD_PKEY_2,    KPD_PKEY_3,    KPD_PKEY_GREEN},
   {KPD_PKEY_4,          KPD_PKEY_5,    KPD_PKEY_6,    KPD_PKEY_NULL},
   {KPD_PKEY_7,          KPD_PKEY_8,    KPD_PKEY_9,    KPD_PKEY_NULL},
   {KPD_PKEY_STAR,       KPD_PKEY_0,    KPD_PKEY_DIESE,KPD_PKEY_NULL},
   };
#elif ((BOARD == 8) || (BOARD == 9))
   #define KP_ROWS      5
   #define KP_COLS      4
   const T_KPD_PHYSICAL_KEY_ID keypad_layout[KP_ROWS][KP_COLS]=
   {                           
   /* Layout of C-Sample */
   {KPD_PKEY_UP,    KPD_PKEY_GREEN,KPD_PKEY_SOFT_RIGHT,KPD_PKEY_DOWN},
   {KPD_PKEY_1,     KPD_PKEY_2,    KPD_PKEY_3,         KPD_PKEY_SOFT_LEFT},
   {KPD_PKEY_4,     KPD_PKEY_5,    KPD_PKEY_6,         KPD_PKEY_NULL},
   {KPD_PKEY_7,     KPD_PKEY_8,    KPD_PKEY_9,         KPD_PKEY_NULL},
   {KPD_PKEY_STAR,  KPD_PKEY_0,    KPD_PKEY_DIESE,     KPD_PKEY_NULL},
   };
#elif ((BOARD == 40) || (BOARD == 41) || (BOARD == 42) || (BOARD == 43))
   #define KP_ROWS      5
   #define KP_COLS      5
   const T_KPD_PHYSICAL_KEY_ID keypad_layout[KP_ROWS][KP_COLS]=
   {                           
   /* Layout of D-Sample;    KPD_PKEY_RED is power key ,specially deal with */
   //{KPD_PKEY_GREEN, KPD_PKEY_VOL_DOWN, KPD_PKEY_VOL_UP,KPD_PKEY_SOFT_LEFT,  KPD_PKEY_LEFT},
   //{KPD_PKEY_1,     KPD_PKEY_2,        KPD_PKEY_3,     KPD_PKEY_REC,        KPD_PKEY_RIGHT},
   //{KPD_PKEY_4,     KPD_PKEY_5,        KPD_PKEY_6,     KPD_PKEY_SOFT_RIGHT, KPD_PKEY_UP},
   //{KPD_PKEY_7,     KPD_PKEY_8,        KPD_PKEY_9,     KPD_PKEY_NAV_CENTER,       KPD_PKEY_NULL},
  // {KPD_PKEY_STAR,  KPD_PKEY_0,        KPD_PKEY_DIESE, KPD_PKEY_DOWN,    KPD_PKEY_NULL   },

   //this handset keypad define 
//glowing,2004-06-28, modify the keypad layout
#if 0 //the following is the keypad layout for M188
   {KPD_PKEY_GREEN, KPD_PKEY_SOFT_LEFT,KPD_PKEY_SOFT_RIGHT, KPD_PKEY_DOWN,  KPD_PKEY_REC },
   {KPD_PKEY_1,     KPD_PKEY_2,        KPD_PKEY_3,  KPD_PKEY_UP  ,  KPD_PKEY_VOL_UP     },
   {KPD_PKEY_4,     KPD_PKEY_5,        KPD_PKEY_6,KPD_PKEY_LEFT    , KPD_PKEY_VOL_DOWN},
   {KPD_PKEY_7,     KPD_PKEY_8,        KPD_PKEY_9,      KPD_PKEY_RIGHT,       KPD_PKEY_NULL},
   {KPD_PKEY_STAR,  KPD_PKEY_0,        KPD_PKEY_DIESE, KPD_PKEY_NAV_CENTER,    KPD_PKEY_NULL   },
#else //the following is the keypad layout for M288
   {KPD_PKEY_GREEN, KPD_PKEY_SOFT_LEFT,KPD_PKEY_SOFT_RIGHT, KPD_PKEY_DOWN, KPD_PKEY_VOL_UP },
   {KPD_PKEY_1,     KPD_PKEY_2,        KPD_PKEY_3,  KPD_PKEY_UP  ,  KPD_PKEY_VOL_DOWN    },
   {KPD_PKEY_4,     KPD_PKEY_5,        KPD_PKEY_6,KPD_PKEY_LEFT  , KPD_PKEY_NULL},
   {KPD_PKEY_7,     KPD_PKEY_8,        KPD_PKEY_9,      KPD_PKEY_RIGHT,       KPD_PKEY_REC},
   {KPD_PKEY_STAR,  KPD_PKEY_0,        KPD_PKEY_DIESE, KPD_PKEY_NAV_CENTER,    KPD_PKEY_NULL   },
#endif
//glowing,2004-06-28, end of modify
   };
#endif

#define KP_ACTIVATE(i)  (~(1<<i))
#define KP_IS_ACTIVE(rows,i)  ((rows & (1<<i)) == 0)
#define KP_ALL_OFF  0x1F
#define KP_ALL_ON   0

extern T_KPD_ENV_CTRL_BLK* kpd_env_ctrl_blk;

typedef struct {  NU_HISR  hisr;
                  char     hisr_stack[512];
               } T_HISR_INFOS;

static T_HISR_INFOS hisr_infos = {0};


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


#if (CHIPSET == 12)

/**  kpd_init_ctrl_reg : Initialize the Control register
 */
void kpd_init_ctrl_reg(const UINT8 software_nreset, 
                       const T_KPD_Nsoftware_mode nsoftware_mode, 
                       const T_KPD_PTV ptv,
                       const T_KPD_EnableDetection long_key_process_en,
                       const T_KPD_EnableDetection time_out_empty_en,
                       const T_KPD_EnableDetection time_out_long_key_en, 
                       const T_KPD_EnableDetection repeat_mode_en)
{
  volatile UINT16 status_reg;
  status_reg = *(volatile UINT16*) KBR_STATE_MACHINE_STATUS;

  if ( (status_reg != KPD_TEST_TIMER_DEBOUNCING) && (status_reg != KPD_TEST_TIMER_LONG_KEY) &&
       (status_reg != KPD_TEST_TIMER_TIME_OUT)   && (status_reg != KPD_TEST_TIMER_REPEAT_KEY) )
  {
    
    /* The PTV can be programmed since the timer is not running */
    
    *(volatile UINT16*) KBR_CTRL_REG = (software_nreset |
                                        nsoftware_mode       << 1 |
                                        ptv                  << 2 |
                                        long_key_process_en  << 5 |
                                        time_out_empty_en    << 6 |
                                        time_out_long_key_en << 7 |
                                        repeat_mode_en       << 8);
  }
  else
  {
    
    /* The PTV must not be programmed when the timer is running */

    SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 0, 1, software_nreset);
    SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 1, 1, nsoftware_mode);
    SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 5, 1, long_key_process_en);
    SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 6, 1, time_out_empty_en);
    SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 7, 1, time_out_long_key_en);
    SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 8, 1, repeat_mode_en);
  }
}


/**  kpd_software_reset : reset software  
 */
void kpd_software_reset(void)
{
  volatile UINT16 mem_reg;
  
  mem_reg = (*(volatile UINT16*) KBR_CTRL_REG) & 0xFFFE;
  *(volatile UINT16*) KBR_CTRL_REG = mem_reg;

}


/**  kpd_set_debouncing_time : Set the desired value of debouncing time
 */
void kpd_set_debouncing_time(const UINT8 debouncing_time)
{

   *(volatile UINT16*) KBR_DEBOUNCING_TIME = debouncing_time;
  
}

#endif /* #if (CHIPSET == 12) */



/**
 * function: hisr_entry
 */
static void hisr_entry(void)
{
   T_RVF_MB_STATUS mb_status;
   T_KPD_KEY_PRESSED_MSG* msg_key_pressed;
   T_KPD_PHYSICAL_KEY_ID key;



   /* Reserve memory for message */
   mb_status = rvf_get_buf (kpd_env_ctrl_blk->prim_id, sizeof(T_KPD_KEY_PRESSED_MSG), (void **) &msg_key_pressed);	

   if (mb_status != RVF_RED) /* Memory allocation success */
   {
      /* Fill the message */
      msg_key_pressed->hdr.msg_id = KPD_KEY_PRESSED_MSG;
      /* Virtual key id is not yet known */
      msg_key_pressed->value = KPD_PKEY_NULL;
      if (mb_status == RVF_GREEN)
         msg_key_pressed->key_to_process = TRUE;
      else
         msg_key_pressed->key_to_process = FALSE;


      /* Send message to the keypad task */
      rvf_send_msg(kpd_env_ctrl_blk->addr_id, msg_key_pressed);
   }
   else
   {
      KPD_SEND_TRACE("KPD: Not enough memory to send new key pressed", RV_TRACE_LEVEL_ERROR);
      kpd_acknowledge_key_pressed();
   }
}


/**
 * function: kpd_initialize_keypad_hardware
 */
void kpd_initialize_keypad_hardware(void)
{
   /* HISR creation */
   NU_Create_HISR(&hisr_infos.hisr,
                  "KPD_HISR",
                  hisr_entry,
                  2,
                  hisr_infos.hisr_stack,
                  sizeof(hisr_infos.hisr_stack));


#if (CHIPSET == 12)
  /* Init control register ; hardware decoding */
   kpd_init_ctrl_reg(1, HARDWARE_DECODING, KPD_CLK_DIV32,
                     KPD_DETECTION_DISABLED, KPD_DETECTION_DISABLED,
                     KPD_DETECTION_DISABLED, KPD_DETECTION_DISABLED);

   /* Debouncing time = 64ms */
   kpd_set_debouncing_time(0x3F);

#endif

   /* Activate all outputs */
   *(volatile UINT16*) KP_COL_OUT = KP_ALL_ON;

   /* Unmask keypad interrupt */
   #if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41))
     AI_UnmaskIT (ARMIO_MASKIT_KBD);
   #elif (CHIPSET == 12)
     IQ_Unmask (IQ_KEYBOARD);
   #else
     IQ_Unmask (IQ_ARMIO);
   #endif
}



/**
 * function: kpd_key_handler
 */
void kpd_key_handler(void)
{

   /* If keypad is not started, return immediately */
   if ( (kpd_env_ctrl_blk == 0) || (kpd_env_ctrl_blk->swe_is_initialized == FALSE) )
   {
      kpd_acknowledge_key_pressed();
   }
   else
   {
      /* Mask keypad interrupt until key is released */
#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41))
       AI_MaskIT (ARMIO_MASKIT_KBD);
#elif (CHIPSET == 12)
       IQ_Mask(IQ_KEYBOARD);
#else
       IQ_Mask(IQ_ARMIO);
#endif

      /* Activate HISR to process the key event */
      NU_Activate_HISR(&hisr_infos.hisr);
   }
}

/**
 * function: kpd_acknowledge_key_pressed
 */
void kpd_acknowledge_key_pressed(void)
{
   /* Unmask keypad interrupt */
  #if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41))
    AI_UnmaskIT (ARMIO_MASKIT_KBD);
  #elif (CHIPSET == 12)
    IQ_Unmask (IQ_KEYBOARD);
  #else
    IQ_Unmask (IQ_ARMIO);
  #endif
}


/*
 * delay
 *
 * Wait a while to let bus settle
 * Magic value found by trial and error
 * 
 */
static void delay(void)
{
   volatile int i;

   for (i=0;i<10;i++) ;
}

/**
 * function: kpd_scan_keypad
 */
T_KPD_PHYSICAL_KEY_ID kpd_scan_keypad(void)
{
   int row, col;
   volatile UINT16 rows;

   /* Activate all columns to find if any row is active */
   *(volatile UINT16*) KP_COL_OUT = KP_ALL_ON;
   delay();

   rows = (*(volatile UINT16*) KP_ROW_IN) & 0x1F;
   if (rows == KP_ALL_OFF)
      return KPD_PKEY_NULL;

   /* Deactivate all columns */
   *(volatile UINT16*) KP_COL_OUT = KP_ALL_OFF;

   /* Activate 1 column at a time */
   for (col = 0; col < KP_COLS; col++)
   {
      *(volatile UINT16*) KP_COL_OUT = (KP_ACTIVATE(col));
      delay();

      /* Find which row is active */
      rows = (*(volatile UINT16*) KP_ROW_IN) & 0x1F;

      if (rows != KP_ALL_OFF)
      {
         for (row = 0; row < KP_ROWS; row++)
         {
            /* first active row */
            if ( KP_IS_ACTIVE(rows,row))
            {
               /* Reactivate all columns */
               *(volatile UINT16*) KP_COL_OUT = KP_ALL_ON;
               /* DO NOT remove this comment. It allows to simply define the link physical layout
                  and physical key Id (for a new keypad) */
               //KPD_SEND_TRACE_PARAM("KPD: Keypad layout check ", keypad_layout[row][col], RV_TRACE_LEVEL_DEBUG_HIGH);
               return keypad_layout[row][col];
            }
         }
      }
   }

   /* No row was active - Reactivate all columns and return */
   *(volatile UINT16*) KP_COL_OUT = KP_ALL_ON;
   return KPD_PKEY_NULL;
}

//glowing,2004-06-12, 
MmiTraceInt(int i){
//#ifdef _DEBUG_HARDWARE_
  /*ljq modified it to control trace command 2003/1/9*/
 // if (RivieraTraceFlag)
 //    KPD_SEND_TRACE_PARAM("zym:MmiTraceInt", i, RV_TRACE_LEVEL_DEBUG_HIGH);
//#endif
}

//glowing,2004-06-17,import from M188

void GetTaskInfo(void){
	/* Define an array capable of holding 20 task pointers. */
	NU_TASK Task,*Pointer_Array[40];
	CHAR task_name[8];
	DATA_ELEMENT task_status;
	UNSIGNED scheduled_count;
	OPTION priority;
	OPTION preempt;
	UNSIGNED time_slice;
	VOID *stack_base;
	UNSIGNED stack_size,number,i;
	UNSIGNED minimum_stack;
	STATUS status;

	/* Obtain a list of currently active task pointers (Max of 20). */
	number = NU_Task_Pointers(&Pointer_Array[0],40);
	/* At this point, number contains the actual number of
	pointers in the list. */


	/* Obtain information about the task control block "Task".
	Assume "Task" has previously been created with the Nucleus
	PLUS NU_Create_Task service call. */
	for(i = 0; i < number ; i++){
		status = NU_Task_Information(Pointer_Array[i], task_name, &task_status,
		&scheduled_count, &priority, &preempt,
		&time_slice, &stack_base,
		&stack_size, &minimum_stack);
		/* If status is NU_SUCCESS, the other information is accurate. */

		if(status == NU_SUCCESS){
			if(task_status == 0){
				MmiTrace("Runing Task");
				MmiTrace(task_name);
			}

			if(task_status == 2){
				MmiTrace("Ready Task");
				MmiTrace(task_name);
			}
				
			//MmiTrace(task_name);
			//MmiTraceInt(task_status);
			//MmiTraceInt(priority);
			

		}
		else{
			MmiTrace("Failed");
		}
	}



}


void GetTimerInfo(void){

	/* Define an array capable of holding 20 timer pointers. */
	NU_TIMER *Pointer_Array[20];
	UNSIGNED number;

	NU_TIMER Timer;
	CHAR timer_name[8];
	OPTION enable;
	UNSIGNED expirations;
	UNSIGNED id,i;
	UNSIGNED initial_time;
	UNSIGNED reschedule_time;
	STATUS status;

	/* Obtain a list of currently active timer pointers
	(Maximum of 20). */
	number = NU_Timer_Pointers(&Pointer_Array[0], 20);
	/* At this point, number contains the actual number
	of pointers in the list. */

	for(i = 0; i < 20 ; i++){
		/* Obtain information about the timer control block "Timer".
		Assume "Timer" has previously been created with the
		Nucleus PLUS NU_Create_Timer service call. */
		status = NU_Timer_Information(Pointer_Array[i], timer_name, &enable, &expirations, &id, &initial_time,&reschedule_time);
		/* If status is NU_SUCCESS, the other information is accurate. */

		if(status == NU_SUCCESS){
			MmiTrace("Success");
			MmiTrace(timer_name);
		}
		else{
			MmiTrace("Failed");
		}
	}


}

//glowing,2004-06-17,end of import

/*@}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -