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

📄 button.c

📁 编译后直接运行的MP3播放器全部C语言源代码 一个包含FAT文件系统、系统引导 Boot、FLASH Driver等内容的
💻 C
字号:
/*************************************************************************** *             __________               __   ___. *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  / *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  < *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \ *                     \/            \/     \/    \/            \/ * $Id: button.c,v 1.43 2004/03/02 11:32:59 linusnielsen Exp $ * * Copyright (C) 2002 by Daniel Stenberg * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************//* * Archos Jukebox Recorder button functions */#include <stdlib.h>#include "config.h"#include "sh7034.h"#include "system.h"#include "button.h"#include "kernel.h"#include "backlight.h"#include "adc.h"#include "serial.h"#include "power.h"#include "system.h"struct event_queue button_queue;long last_keypress;static int lastbtn;#ifdef HAVE_RECORDER_KEYPADstatic bool flipped; /* bottons can be flipped to match the LCD flip */#endif/* how often we check to see if a button is pressed */#define POLL_FREQUENCY    HZ/20/* how long until repeat kicks in */#define REPEAT_START      6/* the speed repeat starts at */#define REPEAT_INTERVAL_START   4/* speed repeat finishes at */#define REPEAT_INTERVAL_FINISH  2/* Number of repeated keys before shutting off */#define POWEROFF_COUNT 8static int button_read(void);static void button_tick(void){    static int tick = 0;    static int count = 0;    static int repeat_speed = REPEAT_INTERVAL_START;    static int repeat_count = 0;    static bool repeat = false;    int diff;    int btn;    /* Post events for the remote control */    btn = remote_control_rx();    if(btn)    {        queue_post(&button_queue, btn, NULL);        backlight_on();    }           /* only poll every X ticks */    if ( ++tick >= POLL_FREQUENCY )    {        bool post = false;        btn = button_read();                /* Find out if a key has been released */        diff = btn ^ lastbtn;        if(diff && (btn & diff) == 0)        {            queue_post(&button_queue, BUTTON_REL | diff, NULL);        }                if ( btn )        {            /* normal keypress */            if ( btn != lastbtn )            {                post = true;                repeat = false;                repeat_speed = REPEAT_INTERVAL_START;                            }            else /* repeat? */            {                if ( repeat )                {                    count--;                    if (count == 0) {                        post = true;                        /* yes we have repeat */                        repeat_speed--;                        if (repeat_speed < REPEAT_INTERVAL_FINISH)                           repeat_speed = REPEAT_INTERVAL_FINISH;                        count = repeat_speed;                        repeat_count++;                                                /* Shutdown if we have a device which doesn't shut                           down easily with the OFF key */#ifdef HAVE_POWEROFF_ON_PB5                        if(btn == BUTTON_OFF && !charger_inserted() &&                            repeat_count > POWEROFF_COUNT)                            power_off();#endif                    }                }                else                {                    if (count++ > REPEAT_START)                    {                        post = true;                        repeat = true;                        repeat_count = 0;                        /* initial repeat */                        count = REPEAT_INTERVAL_START;                     }                }            }            if ( post )            {                if(repeat)                    queue_post(&button_queue, BUTTON_REPEAT | btn, NULL);                else                    queue_post(&button_queue, btn, NULL);                backlight_on();                last_keypress = current_tick;            }        }        else        {            repeat = false;            count = 0;        }                    lastbtn = btn & ~(BUTTON_REL | BUTTON_REPEAT);        tick = 0;    }            backlight_tick();}int button_get(bool block){    struct event ev;    if ( block || !queue_empty(&button_queue) ) {        queue_wait(&button_queue, &ev);        return ev.id;    }    return BUTTON_NONE;}int button_get_w_tmo(int ticks){    struct event ev;    queue_wait_w_tmo(&button_queue, &ev, ticks);    return (ev.id != SYS_TIMEOUT)? ev.id: BUTTON_NONE;}#ifdef HAVE_RECORDER_KEYPAD/* AJBR buttons are connected to the CPU as follows: * * ON and OFF are connected to separate port B input pins. * * F1, F2, F3, and UP are connected to the AN4 analog input, each through * a separate voltage divider.  The voltage on AN4 depends on which button * (or none, or a combination) is pressed. * * DOWN, PLAY, LEFT, and RIGHT are likewise connected to AN5. */ /* Button analog voltage levels */#ifdef HAVE_FMADC/* FM Recorder super-special levels */#define	LEVEL1		150#define	LEVEL2		385#define	LEVEL3		545#define	LEVEL4		700#else/* plain bog standard Recorder levels */#define	LEVEL1		250#define	LEVEL2		500#define	LEVEL3		700#define	LEVEL4		900#endif/* *Initialize buttons */void button_init(){#ifndef SIMULATOR    /* Set PB4 and PB8 as input pins */    PBCR1 &= 0xfffc; /* PB8MD = 00 */    PBCR2 &= 0xfcff; /* PB4MD = 00 */    PBIOR &= ~(PBDR_BTN_ON|PBDR_BTN_OFF); /* Inputs */#endif    queue_init(&button_queue);    lastbtn = 0;    tick_add_task(button_tick);    last_keypress = current_tick;    flipped = false;}/* * helper function to swap UP/DOWN, LEFT/RIGHT, F1/F3 */static int button_flip(int button){    int newbutton;    newbutton = button &         ~(BUTTON_UP | BUTTON_DOWN        | BUTTON_LEFT | BUTTON_RIGHT         | BUTTON_F1 | BUTTON_F3);    if (button & BUTTON_UP)        newbutton |= BUTTON_DOWN;    if (button & BUTTON_DOWN)        newbutton |= BUTTON_UP;    if (button & BUTTON_LEFT)        newbutton |= BUTTON_RIGHT;    if (button & BUTTON_RIGHT)        newbutton |= BUTTON_LEFT;    if (button & BUTTON_F1)        newbutton |= BUTTON_F3;    if (button & BUTTON_F3)        newbutton |= BUTTON_F1;    return newbutton;}/* * set the flip attribute * better only call this when the queue is empty */void button_set_flip(bool flip){    if (flip != flipped) /* not the current setting */    {        /* avoid race condition with the button_tick() */        int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);        lastbtn = button_flip(lastbtn);         flipped = flip;        set_irq_level(oldlevel);    }}/* * Get button pressed from hardware */static int button_read(void){    int btn = BUTTON_NONE;    /* Check port B pins for ON and OFF */    int data;#ifdef HAVE_FMADC    /* TODO: use proper defines here, and not the numerics in the       function argument */    if ( adc_read(3) < 512 )        btn |= BUTTON_ON;    if ( adc_read(2) > 512 )        btn |= BUTTON_OFF;#else    data = PBDR;    if ((data & PBDR_BTN_ON) == 0)        btn |= BUTTON_ON;    else if ((data & PBDR_BTN_OFF) == 0)        btn |= BUTTON_OFF;#endif    /* Check F1-3 and UP */    data = adc_read(ADC_BUTTON_ROW1);    if (data >= LEVEL4)        btn |= BUTTON_F3;    else if (data >= LEVEL3)        btn |= BUTTON_UP;    else if (data >= LEVEL2)        btn |= BUTTON_F2;    else if (data >= LEVEL1)        btn |= BUTTON_F1;    /* Some units have mushy keypads, so pressing UP also activates       the Left/Right buttons. Let's combat that by skipping the AN5       checks when UP is pressed. */    if(!(btn & BUTTON_UP))    {        /* Check DOWN, PLAY, LEFT, RIGHT */        data = adc_read(ADC_BUTTON_ROW2);        if (data >= LEVEL4)            btn |= BUTTON_DOWN;        else if (data >= LEVEL3) {#ifdef HAVE_FMADC            btn |= BUTTON_RIGHT;#else            btn |= BUTTON_PLAY;#endif        }        else if (data >= LEVEL2)            btn |= BUTTON_LEFT;        else if (data >= LEVEL1) {#ifdef HAVE_FMADC            btn |= BUTTON_PLAY;#else            btn |= BUTTON_RIGHT;#endif        }    }    if (btn && flipped)        return button_flip(btn); /* swap upside down */      return btn;}#elif HAVE_PLAYER_KEYPAD/* The player has two buttons on port pins:   STOP:  PA11   ON:    PA5   The rest are on analog inputs:      LEFT:  AN0   MENU:  AN1   RIGHT: AN2   PLAY:  AN3*/void button_init(void){    /* set port pins as input */    PAIOR &= ~0x820;    queue_init(&button_queue);    lastbtn = 0;    tick_add_task(button_tick);    last_keypress = current_tick;}static int button_read(void){    int porta = PADR;    int btn = BUTTON_NONE;    /* buttons are active low */    if(adc_read(0) < 0x180)        btn |= BUTTON_LEFT;    if(adc_read(1) < 0x180)        btn |= BUTTON_MENU;    if(adc_read(2) < 0x180)        btn |= BUTTON_RIGHT;    if(adc_read(3) < 0x180)        btn |= BUTTON_PLAY | BUTTON_UP;    if ( !(porta & 0x20) )        btn |= BUTTON_ON;    if ( !(porta & 0x800) )        btn |= BUTTON_STOP | BUTTON_DOWN;    return btn;}#elif HAVE_NEO_KEYPADstatic bool mStation = false;void button_init(void){    /* set port pins as input */    PAIOR &= ~0x4000;  //PA14 for stop button    queue_init(&button_queue);    lastbtn = 0;    tick_add_task(button_tick);    last_keypress = current_tick;}int button_read(void){    int btn=BUTTON_NONE;        btn|=((~PCDR)&0xFF);    /* mStation does not have a stop button and this floods the button queue       with stops if used on a mStation */    if (!mStation)        btn|=((~(PADR>>6))&0x100);    return btn;}/* This function adds a button press event to the button queue, and this   really isn't anything Neo-specific but might be subject for adding to   the generic button driver */int button_add(unsigned int button){    queue_post(&button_queue,button,NULL);    return 1;}#endif

⌨️ 快捷键说明

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