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

📄 keypad.c

📁 GM5621原代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    {
      IrLWord <<= 1;
    } 

    if( (B_IrClockCounter < IR_LOGIC1_MAX) && (B_IrClockCounter > IR_LOGIC1_MIN))
    {
        IrLWord <<= 1;
        IrLWord |= 0x0001;
    }

   #if IR_DEVICE_LENGTH
    if(IrIndex == IR_DEVICE_LENGTH)
    {
      IrAddress = IrLWord;
    }
    #endif
    
    if(IrIndex == IR_DATA_LENGTH)
    {
      IRKey = IrLWord;
      IrIndex = 0;
      IrLWord = 0;
    }

    if(IrIndex > IR_DATA_LENGTH)
    {
      IrIndex = 0;
      IrLWord = 0;
    }


    WRITE_PCB_REG(T1CNT, 0);                    // Clear counter
    WRITE_PCB_REG(T1CON, (EN|INH|INT|CONT));
    CLEAR_PCB_REG_BITS(IMASK, TMR);

    B_IrClockCounter = 0;
   WRITE_PCB_REG(EOI, INT2_VTYPE);        // Clear interrupt
}


//******************************************************************************
//
// FUNCTION:    interrupt IRTimerInt(void)
// USAGE:       Timer1 interrupt service routine.
//
// INPUT:       None
// OUTPUT:      None
// GLOBALS:    None
// USED_REGS:  T1CON, EOI
//
//******************************************************************************
void far interrupt IRTimerInt(void)
{  
   B_IrClockCounter++;
    W_IrPacketCounter++;
   if(W_IrPacketCounter > IR_AUTOREPEAT_RESET)
    {
      // Clear key
       IRKey = 0;
        // disable timer interrupt
        WRITE_PCB_REG(T1CON, (INH|INT|CONT));
        B_IrClockCounter = 0;
        W_IrPacketCounter = 0;
    }
   CLEAR_PCB_REG_BITS(T1CON, MC);
   WRITE_PCB_REG(EOI, TIMER1_VTYPE);
}
#else //  USE_RC5

//******************************************************************************
//
// FUNCTION:    IRInit(DWORD D_CpuClock)
// USAGE:       Initialization of infrared reciever.
//          Use Mcu timer1 and external interrupt.
//
// INPUT:       D_CpuClock - CPU clock speed
// OUTPUT:      None
// GLOBALS:    None
// USED_REGS:  IRQ_CONFIG, I2CON, IMASK, T1CMPA
//
//******************************************************************************
// RC5RC
void far IRInit(DWORD D_CpuClock)
{
   //Setup Int2 interrupt register
    gm_SetRegBitsWord(IRQ_CONFIG, GPIO_IRQ_IN_EN);
    WRITE_PCB_REG(I2CON, 0);


   SET_VECTOR(INT2_VECTOR, IREdgeInterrupt);
   CLEAR_PCB_REG_BITS(IMASK, I2);

   //Setup Timer1 time out values
   {
        W_IRPeriodTIme = (WORD)(D_CpuClock/4499L); // Generate 0.889ms timeout
        SET_VECTOR(TIMER1_VECTOR, IRTimerInt);
   }
}

//******************************************************************************
//
// FUNCTION:    interrupt IREdgeInterrupt(void)
// USAGE:       Rising edge interrupt service routine
//
// INPUT:       None
// OUTPUT:      None
// GLOBALS:    None
// USED_REGS:  T1CNT, T1CON, IMASK, EOI
//
//******************************************************************************
void far interrupt IREdgeInterrupt(void)
{
    IrIndex = 0;
    IrLWord = 0;
    B_EdgeState = 0;
    W_IrPacketCounter = 0;

   WRITE_PCB_REG(T1CNT, 0);      // Clear counter value
    WRITE_PCB_REG(T1CMPA, W_IRPeriodTIme + (W_IRPeriodTIme >> 1));   // Configure timer1 value

    WRITE_PCB_REG(T1CON, (EN|INH|INT|CONT));
    CLEAR_PCB_REG_BITS(IMASK, TMR);
    
   SET_PCB_REG_BITS(IMASK, I2);  // Mask this interrupt
    gm_ClearRegBitsWord(IRQ_CONFIG, GPIO_IRQ_IN_EN);  // enable GPIO input
        
   WRITE_PCB_REG(EOI, INT2_VTYPE);        // Clear interrupt
}

//******************************************************************************
//
// FUNCTION:    interrupt IRTimerInt(void)
// USAGE:       Timer1 interrupt service routine.
//
// INPUT:       None
// OUTPUT:      None
// GLOBALS:    None
// USED_REGS:  T1CON, EOI
//
//******************************************************************************
void far interrupt IRTimerInt(void)
{
   BYTE B_Input;
    WRITE_PCB_REG(T1CMPA, W_IRPeriodTIme);   // Configure timer1 value

        
    B_Input = gm_ReadRegWord(GPINPUT1) & INPUT_BIT_MASK;
    if(IrIndex == 0)
        B_EdgeState = B_Input;

    if(IrIndex < IR_DATA_LENGTH)
    {
        if(IrIndex & 0x01)
        {
            if(B_EdgeState != B_Input)
            {
                IrLWord <<= 1;
                if(B_Input)
                    IrLWord |= 0x0001;
            }
        }
        IrIndex++;
        B_EdgeState = B_Input;
    }
    else
    {
        if(IrLWord & 0x1000)
        {
         if((IrLWord & 0x07ff) == 0)
               IrLWord = ZERRO_KEY_CODE;
            IRKey = IrLWord & 0x07ff;
           W_IrPacketCounter = IR_DATA_LENGTH  + 1;
        }
        IrLWord = 0;
        IrIndex = 0;
        gm_SetRegBitsWord(IRQ_CONFIG, GPIO_IRQ_IN_EN);   // enable GPIO input
        CLEAR_PCB_REG_BITS(IMASK, I2); // Mask this interrupt
    }

    W_IrPacketCounter++;
    if(W_IrPacketCounter > IR_AUTOREPEAT_RESET)
    {
        IRKey = 0;
        IrLWord = 0;
        IrIndex = 0;
        // disable timer interrupt
        WRITE_PCB_REG(T1CON, (INH|INT|CONT));
    }

   CLEAR_PCB_REG_BITS(T1CON, MC);
   WRITE_PCB_REG(EOI, TIMER1_VTYPE);
    
}

#endif   // IR_DRIVER != USE_RC5


//******************************************************************************
//
// FUNCTION:   static KEY_INDEX TranslateIrKey(void)
// USAGE:      Comparing Ir value with table code by the method binary search
//
// INPUT:      none
// OUTPUT:      KEY_INDEX - id pushed key
//          If none of the key is pressed, return value Key_None
// GLOBALS:    Number_Of_IRValues - number of members in array IRValues[]
//          IRValues - translating Ir code to id key.
// USED_REGS:   None
//
//******************************************************************************
static gmt_KEY_INDEX TranslateIrKey(void)
{
   BYTE     B_Result;
    SWORD      B_Offset;
   SWORD       B_Min = 0;
   SWORD       B_Max = NUMBER_OF_IRValues - 1;
   BYTE     B_Value = IRKey;
    

   // ScanRemoteKey to see if a new value was found.
   if (B_Value)
   {
      #if DEBUG_IR_CODE
         msg("Ir Code =0x%x", B_Value);
      #endif
      while(B_Min <= B_Max)
      {
         // For IR the codes must match exactly, so do a binary search only
         // returning the value when the codes are exactly equal.
         B_Offset = ((WORD)B_Max + B_Min) / 2;
         B_Result = IRValues[B_Offset].Code;
         if (B_Result == B_Value)
         {
            return(IRValues[B_Offset].KeyIndex);
         }
            else
         {
            if (B_Result > B_Value)
               B_Max = B_Offset - 1;
                else
                  B_Min = B_Offset + 1;
         }
      }
   }
   return Key_None;   
}
#endif





//******************************************************************************
//
// FUNCTION:    void far InitGpioKeyMap(void)
// USAGE:       Initialize key map table for gpio. Fill up the key mapping table base on the information in
//                 WB file, osd_Trtbl.c. The key mapping table will be used in key scanning.  
// INPUT:      None  
// OUTPUT:     None
// GLOBALS:    None
// USED_REGS:  None
//
//******************************************************************************
void InitGpioKeyMap(void)
{
#if USE_GPIO_KEYPAD
   //
   // Temporary variables for a loop index
   //
   WORD i;
   WORD W_Mask;
   //
   // Fill up the key mapping table base on the information in
   // WB file: osd_Trtbl.c.  The key mapping table will be used in 
   // key scanning.
   //   
   
   for (i = 0; i < NUMBER_OF_SCAN_KEY; i++)
   {  
      //
      // Individual GPIO Pins
      //
         W_Mask = Wa_KeyMapMask[KeyMapping[i].Bit];
         switch(KeyMapping[i].Port)
         {
            case 0:
               Sta_KeyMapTbl[i].W_GpioPortAddr = GPINPUT1;
               gm_WriteRegByte(GPIO_DIRCTRL1, gm_ReadRegByte(GPIO_DIRCTRL1) & ~W_Mask);  // GPIO1 pin as input
               break;
            case 1:
               Sta_KeyMapTbl[i].W_GpioPortAddr = GPINPUT2;
               gm_WriteRegByte(GPIO_DIRCTRL2, gm_ReadRegByte(GPIO_DIRCTRL2) & ~W_Mask);   // GPIO2 pin as input
               break;
            case 2:
               Sta_KeyMapTbl[i].W_GpioPortAddr = GPINPUT3;
               gm_WriteRegByte(GPIO_DIRCTRL3, gm_ReadRegByte(GPIO_DIRCTRL3) & ~W_Mask);   // GPIO3 pin as input
               break;
         }
      // store the associated pin position in the array Sta_KeyMapTbl
      Sta_KeyMapTbl[i].W_GpioPinPos = W_Mask;
   }
#endif
}

//******************************************************************************
//
// FUNCTION:   gmt_GPIO_KEY_VALUE far gm_ReadKeyPad(void)
// USAGE:       Scan Key from Gpio
// INPUT:      None
// OUTPUT:     Key Value
// GLOBALS:    None
// USED_REGS:  None
//
//******************************************************************************
#if USE_GPIO_KEYPAD
gmt_GPIO_KEY_VALUE far gm_ReadKeyPad(void)
{
   BYTE B_Key = 0;
   BYTE i;

   for (i = 0; i < NUMBER_OF_SCAN_KEY; i++)
   {
#if KeyPolarity
      if ((gm_ReadRegByte(Sta_KeyMapTbl[i].W_GpioPortAddr) & Sta_KeyMapTbl[i].W_GpioPinPos) != 0)
#else
      if ((gm_ReadRegByte(Sta_KeyMapTbl[i].W_GpioPortAddr) & Sta_KeyMapTbl[i].W_GpioPinPos) == 0)
#endif
      {
         B_Key |= Wa_KeyMapMask[i];
      }
   }
   return(B_Key);
}
#endif

//******************************************************************************
//
// FUNCTION:   static KEY_INDEX TranslateGPIOKey(none)
// USAGE:      Comparing GPIO key value with table code by the method binary tree
//
// INPUT:      none
// OUTPUT:      KEY_INDEX - id pushed key          
//          If none of the key is pressed, return value 0.
//          If invalid key is pressed, return value 255.
// GLOBALS:    Number_Of_KeyPadTranslation - number of members in array KeyPadTranslation[]
//          KeyPadTranslation - translating GPIO code to id key. 
// USED_REGS:   None
//
//******************************************************************************
#if USE_GPIO_KEYPAD
static gmt_KEY_INDEX TranslateGPIOKey(void)
{
   gmt_GPIO_KEY_VALUE      B_Result;
   SWORD                B_Offset;
   SWORD                B_Min = 0;
   SWORD                B_Max = NUMBER_OF_GPIOValues - 1;
   gmt_GPIO_KEY_VALUE      B_Value = gm_ReadKeyPad();


   if (B_Value)
   {
      while(B_Min <= B_Max)
      {
         B_Offset = ((WORD)B_Max + B_Min) / 2;
         B_Result = GPIOValues[B_Offset].KeyValue;
         if (B_Result == B_Value)
         {
            #if DEBUG_OSD_KEYPAD
               msg("TranslateGPIOKey:  B_Offset = %d ", B_Offset);
               msg("TranslateGPIOKey = 0x%x", GPIOValues[B_Offset].KeyIndex);
            #endif
            return(GPIOValues[B_Offset].KeyIndex);
         } else
         {
            if (B_Result > B_Value)
            {
               B_Max = B_Offset - 1;
            } else
            {
               B_Min = B_Offset + 1;
            }
         }
      }
      #if DEBUG_OSD_KEYPAD
         msg("TranslateGPIOKey = Invalid Key ", GPIOValues[B_Offset].KeyIndex);
      #endif
      return 255; // invalid key
   }
   return 0; // key none
}
#endif // USE_GPIO_KEYPAD  

//******************************************************************************
//
// FUNCTION:   ADCDelay
// USAGE:      LOW_BW_ADC_STATUS always returns conversion complete, so this is
//             a delay function to give timer for LBADC conversion to complete.
//             NOTE:  we cant use a gm_Delay function because the LBADC can be
//             read in an interrupt where we can't use gm_DelayXX functions.
// INPUT:      void
// OUTPUT:     void
// GLOBALS:    none
// USED_REGS:  none
//
//******************************************************************************
static void __near ADCDelay(void)
{
// function calls alone take about 7us.
}

//******************************************************************************
//
// FUNCTION:   BYTE far ScanAdcKey (WORD B_Channel)
// USAGE:      First configure the low bandwidth ADC of keypad then retrieve the converted data
// INPUT:      B_Channel
// OUTPUT:     ADC key data
// GLOBALS:    none
// USED_REGS:  none
//
//******************************************************************************
#if LBADC_USED
BYTE far ScanAdcKey(BYTE B_Channel)
{
   BYTE B_Key = 0;
   BYTE B_Ctrl;
   
   //
   // 1) Configure LBW ADC channel 1, 2 and then 3 to handle keyboard key input
   // 2) Program the Low Bandwidth ADC control register to start conversion.
   //
   B_Ctrl = LBADC_EN | B_Channel | DIV_BY_1;
   gm_WriteRegByte (LOW_BW_ADC_CTRL, B_Ctrl);
   gm_WriteRegByte (LOW_BW_ADC_CTRL, B_Ctrl | LBADC_START_CONV);

    //
    // When conversion done, copy the conversion result to the BYTE pointer.
    //
    // LOW_BW_ADC_STATUS needs 3TCLKs to clear after a LBADC_START_CONV,
    // add delay to give time for LOW_BW_ADC_STATUS to read correctly.
    ADCDelay();
    while(((gm_ReadRegByte (LOW_BW_ADC_STATUS)) & BIT0)==0) continue;

    #if  AdcPolarity
        B_Key = ~((BYTE) gm_ReadRegByte (LOW_BW_ADC_RESULT));  // Read key data
    #else
        B_Key = (BYTE) gm_ReadRegByte (LOW_BW_ADC_RESULT);  // Read key data
    #endif


   //
   // Reset the Low Bandwidth ADC control register to idle.
   //
   gm_WriteRegByte (LOW_BW_ADC_CTRL, B_Ctrl);

   #if   DEBUG_SCAN_CODE
      if(B_PreKeyCode!=B_Key)
      {
         msg("ScanCode = 0x%x", B_Key);
         B_PreKeyCode = B_Key;
      }
   #endif

   return B_Key;

}
#endif //LBADC_USED


//******************************************************************************
//
// FUNCTION:   static SBYTE CheckADCCode(BYTE B_TableCode, BYTE B_Value)
// USAGE:      Comparing ADC value with table code
//
// INPUT:      B_TableCode, B_Value - ADC value
// OUTPUT:      0 = the table code equals ADC value
//          1 = the table code less ADC value      
//          -1 = the table code greater ADC value
// GLOBALS:    None
// USED_REGS:   None
//
//******************************************************************************
#if LBADC_USED
static SBYTE CheckADCCode(BYTE B_TableCode, BYTE B_Value)
{
   // If B_Value is within the ADC_DELTA range we return 0 because it matchs
   // otherwise we return 1 if table code is less than ADC and -1 if table

⌨️ 快捷键说明

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