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

📄 keypad.c

📁 TI公司TMS320VC5509的外设驱动程序
💻 C
字号:
/*
 *  Copyright (C) 2001, Spectrum Digital, Inc.  All Rights Reserved.
 */
 
#include "5509.h"
#include "util.h"

#define I2C_POT1 (I2C_ADS7823 + 2)
#define I2C_POT2 (I2C_ADS7823 + 1)

#define NUMSWITCHES       12
#define SWITCH_ERROR      0x10
#define SWITCH_OFF        0x300

#define SWITCH_NOCHANGE   0
#define SWITCH_CHANGE     1

#define AIN_KEY           1
#define AIN_JOG           0

typedef struct {
    int adcval;
    int keymapping;
} SWITCH_LIST_ENTRY;

SWITCH_LIST_ENTRY keylist[] = {
    {0x150, 0x01},    // Switch 01
    {0x0f2, 0x02},    // Switch 02
    {0x17c, 0x03},    // Switch 03
    {0x0bf, 0x04},    // Switch 04
    {0x1b9, 0x05},    // Switch 05
    {0x07b, 0x06},    // Switch 06
    {0x200, 0x07},    // Switch 07
    {0x03d, 0x08},    // Switch 08
    {0x23a, 0x09},    // Switch 09
    {0x000, 0x00}
};

SWITCH_LIST_ENTRY joglist[] = {
    {0x07b, 0x0A},    // Switch 0A (Jog down)
    {0x150, 0x0B},    // Switch 0B (Jog up)
    {0x200, 0x0C},    // Switch 0C (Jog in)
    {0x000, 0x00}
};

unsigned short keymatrix[17] = {
    0x00, 0x71, 0x72, 0x73, 0x74, 0x75, 0x66, 0x60,
    0x50, 0x56, 0x07, 0x27, 0x17, 0x00, 0x00, 0x00,
    0x00};

unsigned char open_key[] = {0x1c, 0x22, 0x41, 0x41, 0x41, 0x22, 0x1c};
unsigned char closed_key[] = {0x1c, 0x2a, 0x5d, 0x5d, 0x5d, 0x2a, 0x1c};
unsigned char arrow[] = {0x08, 0x08, 0x3e, 0x1c, 0x08, 0x00};
unsigned char exitsymbol[] = {0x14, 0x08, 0x14};
unsigned short potbuf[16];
unsigned int switch_history[8];
int switch_accumulator, switch_pos, switch_prevkey, switch_currkey, switch_channel;

int Pot_Read(int potnum)
{
    unsigned short acc, sample, *bufptr, i2caddr;
    int i;

    // Make sure potnum is valid
    if ((potnum == 1) || (potnum == 2))
        i2caddr = I2C_ADS7823 + (3 - potnum);
    else
        return 0xfff;    

    // Send command 
    potbuf[0] = 0; //  Command byte
    I2C_Write(i2caddr, 1, potbuf);
            
    // Read 4 samples
    I2C_Read(i2caddr, 8, potbuf);
    
    // Average the 4 samples
    bufptr = potbuf;
    acc = 0;
    for (i = 0; i < 4; i++)
    {
        sample = (*bufptr++ & 0xf) << 8;
        sample += *bufptr++ & 0xff;
        acc += sample;
    }
    
    return (acc >> 2);
}

void Pot_Init()
{
    I2C_Init();
}
#if(0)
unsigned short Key_Test()
{
    unsigned short keydata[16];
    int pot1, pot2, pot3;
    
    LCD_Init();
    Key_Init();
    while(1)
    {
        Key_ReadPot(1, keydata);
        pot1 = (keydata[0] << 8) + keydata[1];
        Key_ReadPot(2, keydata);
        pot2 = (keydata[0] << 8) + keydata[1];
        Key_ReadPot(3, keydata);
        pot3 = (keydata[0] << 8) + keydata[1];

        LCD_HexPos(0, 0, pot1);
        LCD_HexPos(0, 1, pot2);
        LCD_HexPos(0, 2, pot3);
        SWDelayMsec(100);
    }
    
    while(1);
    return 0;
}
#endif

unsigned short Pot_Test()
{
    // Initialize devices for test
    LCD_Init();    
    Pot_Init();
    
    // Display field names
    LCD_TextPos(4, 3, "POT1 =");
    LCD_TextPos(4, 4, "POT2 =");    
    while(1)
    {
        LCD_HexPos(11, 3, Pot_Read(1));
        LCD_HexPos(11, 4, Pot_Read(2));
    }
}

int Switch_KeyMap(int adcreading, SWITCH_LIST_ENTRY *list)
{
    int diff;
    SWITCH_LIST_ENTRY *s;
    
    s = list;
    while (s -> keymapping != 0)
    {
        diff = s -> adcval - adcreading;
        if (diff < 0)
            diff = -diff;
        if (diff <= SWITCH_ERROR)
            return s -> keymapping;
        s++;
    }

    if (adcreading < SWITCH_OFF)
        return -1;
    else
        return 0;
}

int Switch_ReadRaw(switchno)
{
    PC55XX_ADC pADC = (PC55XX_ADC)C55XX_ADC_ADDR;
    
    // Trigger ADC conversion
    WriteMask(pADC -> adcr, 0x8000 + (switchno << 12), 0xf000);
    
    // Wait until complete
    while (ReadMask(pADC -> addr, ADDR_ADCBUSY)); 

    // Take reading
    return ReadMask(pADC -> addr, ADDR_ADCDATA_MASK);
}


/*
 *  Switch_Sample() - Return SWITCH_CHANGE if an event such as a switch press
 *      or release has been detected.  The currently pressed key number is
 *      stored in *keynum, the previous state is stored in *prevkey.  The
 *      function samples once each time it is called until 4 samples have
 *      been collected.  The fifth time through the samples are checked to
 *      see if a stable level has been reached and what the new state is.
 *      The calling function calls Switch_Sample until it returns
 *      SWITCH_CHANGE, which indicates that a switch event has occurred.
 *      Further calls will continue to sample the keypad but will return
 *      SWITCH_NOCHANGE if the switch state is the same.  Analog channel
 *      alternates when jog and switches are both idle, stays with same
 *      channel until switch is released.
 */
 
int Switch_Sample(int *keynum, int *prevkey)
{
    PC55XX_ADC pADC = (PC55XX_ADC)C55XX_ADC_ADDR;
    int diff, adcval, returnval, tmpval, i;

    // Accumulate 4 samples    
    if (switch_pos < 4)
    {
        // Reset accumulator with first sample
        if (switch_pos == 0)
            switch_accumulator = 0;
        
        // Add ADC value to accumulator
        adcval = Switch_ReadRaw(switch_channel);
        switch_history[switch_pos++] = adcval;
        switch_accumulator += adcval;

        // Report no switch pressed
        *keynum = switch_currkey;
        *prevkey = switch_currkey;
        return SWITCH_NOCHANGE;
    }
    
    // After the 4th sample, check for stable value
    if (switch_pos == 4)
    {
        // Average ADC values
        switch_pos = 0;
        adcval = switch_accumulator >> 2;
        diff = switch_history[3] - switch_history[0];
        if ((diff < -8) || (diff > 8))
        {
            // No reading, treat as if last key still pressed
            returnval = SWITCH_NOCHANGE;
        } else
        {                
            // Check key mapping
            if (switch_channel == AIN_KEY)
            {
                switch_currkey = Switch_KeyMap(adcval, keylist);               
            } else
            {
                tmpval = Switch_KeyMap(adcval, joglist);
                if (tmpval > 0)
                    for (i = 0; i < 1; i++);
                if ((switch_currkey == 0x0a) || (switch_currkey == 0x0b))
                {
                    if (tmpval == 0)
                        switch_currkey = 0;
                }
                else
                    switch_currkey = tmpval;
            }

            // Generate return value
            *prevkey = switch_prevkey;
            returnval = (switch_currkey != switch_prevkey) ? SWITCH_CHANGE : SWITCH_NOCHANGE;
            switch_prevkey = switch_currkey;
        }
        
        if (switch_currkey == 0)
            switch_channel = 1 - switch_channel;
        
        // Swap channels and return
        *keynum = switch_currkey;
        return returnval;
    }
}

unsigned short int Switch_Init()
{
    PC55XX_ADC pADC = (PC55XX_ADC)C55XX_ADC_ADDR;
    int adcval, i;

    // Set up the conversion clocks
    WriteField(pADC -> adccr, (dspclk.freq >> 2) - 1, ADCCR_SYSDIV_MASK);
    WriteMask(pADC -> adcdr,
        ADCDR_CONVDIV_2,
        ADCDR_CONVDIV_MASK);
        
    // Set up the sample and hold time
    WriteMask(pADC -> adcdr, ADCDR_SAMPDIV_255, ADCDR_SAMPDIV_MASK);
    
    // Set up switch history
    for (i = 0; i < 8; i++)
        switch_history[i] = 0;
    switch_accumulator = 0;
    switch_pos = 0;
    switch_prevkey = 0;
    switch_currkey = 0;
    switch_channel = AIN_JOG;
    
    return 0;
}

unsigned short int Switch_Debug()
{
    int currreading, prevreading;
    
    Switch_Init();
    LCD_Init();
    
    while(1)
    {
        // Wait for key press
        while ((currreading = Switch_ReadRaw(1)) > 0x3f8)
            LCD_HexPos(0, 0, currreading);

        // Wait for stable input
        prevreading = 0x3ff;
        while ((currreading = Switch_ReadRaw(1)) != prevreading)
        {
            prevreading = currreading;
            SWDelayUsec(1000);
        }
        LCD_HexPos(0, 1, currreading); 

        // Check key mapping
        LCD_HexPos(0, 2, Switch_KeyMap(currreading, keylist));
        
        // Wait for key release
        while ((currreading = Switch_ReadRaw(1)) <= 0x3f0)        
            LCD_HexPos(0, 3, currreading); 
    }
    
    return 0;
}

int hpos(int col)
{
    return 9 + ((col << 1) << 3);
}

void Switch_Display(int keynum, unsigned char *keyimage)
{
        LCD_RawPos(hpos(keymatrix[keynum] & 0xf), ((keymatrix[keynum] & 0xf0) >> 4), keyimage, 7);
}

unsigned short Switch_Test()
{
    int i, iter, keynum, keyaction, prevkey, changes, pot;

    // Initialize board resources
    LCD_Init();
    Switch_Init();
    Pot_Init();
    
    // Display keyboard
    for (i = 1; i <= NUMSWITCHES; i++)
        Switch_Display(i, open_key);

    // Display welcome message
    LCD_TextPos(0, 0, "Events");
    LCD_TextPos(0, 1, "POT1 =");
    LCD_TextPos(0, 2, "POT2 =");
    LCD_TextPos(6, 5, "PRESS KEY");
    LCD_RawPos(114, 5, exitsymbol, 3);

    changes = 0;
    iter = 0;
    while(1)
    {
        // Display event counter
        LCD_HexPos(7, 0, changes);
        
        // Display pots but only sample at 1/16 freq of switches
        if ((iter++ & 0x0f) == 0x00)
        {
            LCD_HexPos(7, 1, Pot_Read(1));
            LCD_HexPos(7, 2, Pot_Read(2));
        }
 
        // Wait for key press
        if (Switch_Sample(&keynum, &prevkey) == SWITCH_CHANGE)
        {
            if (prevkey > 0)
                Switch_Display(prevkey, open_key);
            if (keynum > 0)
                Switch_Display(keynum, closed_key);
                
            changes++;
        }

        // Exit if SW9 is pressed
        if (keynum == 9)
            break;
    }
    
    return 0;
}


⌨️ 快捷键说明

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