From cfec25bb9e7df607f93cadf3e4d76b558c7db95d Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Mon, 30 Sep 2002 08:55:22 +0000 Subject: A lot more stable remote control handling git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2447 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/button.c | 24 +++++--- firmware/drivers/serial.c | 141 ++++++++++++++++++++++++++-------------------- firmware/drivers/serial.h | 1 + 3 files changed, 99 insertions(+), 67 deletions(-) (limited to 'firmware') diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c index d6a2151dbd..9953f1aa22 100644 --- a/firmware/drivers/button.c +++ b/firmware/drivers/button.c @@ -28,6 +28,7 @@ #include "kernel.h" #include "backlight.h" #include "adc.h" +#include "serial.h" struct event_queue button_queue; @@ -52,18 +53,27 @@ static int button_read(void); static void button_tick(void) { - static int tick=0; - static int count=0; - static int lastbtn=0; - static int repeat_speed=REPEAT_INTERVAL_START; - static bool repeat=false; + static int tick = 0; + static int count = 0; + static int lastbtn = 0; + static int repeat_speed = REPEAT_INTERVAL_START; + 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; - int btn = button_read(); + btn = button_read(); /* Find out if a key has been released */ diff = btn ^ lastbtn; @@ -91,7 +101,7 @@ static void button_tick(void) if (count == 0) { post = true; /* yes we have repeat */ - repeat_speed--; + repeat_speed--; if (repeat_speed < REPEAT_INTERVAL_FINISH) repeat_speed = REPEAT_INTERVAL_FINISH; count = repeat_speed; diff --git a/firmware/drivers/serial.c b/firmware/drivers/serial.c index 91e2a6911f..982b99fc2c 100644 --- a/firmware/drivers/serial.c +++ b/firmware/drivers/serial.c @@ -43,84 +43,105 @@ static void screen_dump(void); void serial_setup (void) { - char dummy; - dummy = SSR1; - SSR1 = 0; SMR1 = 0x00; SCR1 = 0; BRR1 = (FREQ/(32*9600))-1; + SSR1 &= 0; /* The status bits must be read before they are cleared, + so we do an AND operation */ - /* let the hardware settle */ + /* Let the hardware settle. The serial port needs to wait "at least + the interval required to transmit or receive one bit" before it + can be used. */ sleep(1); - SCR1 = 0x50; - - /* This enables the serial Rx interrupt*/ - IPRE = (IPRE & 0x0FFF) | 0x8000; /* Set to medium priority */ + SCR1 = 0x10; /* Enable the receiver, no interrupt */ } -static void process_byte(int byte) +/* This function returns the received remote control code only if it is + received without errors before or after the reception. + It therefore returns the received code on the second call after the + code has been received. */ +int remote_control_rx(void) { - int btn = 0; + static int last_valid_button = BUTTON_NONE; + static int last_was_error = false; + int btn; + int ret = BUTTON_NONE; + + /* Errors? Just clear'em. The receiver stops if we don't */ + if(SSR1 & (SCI_ORER | SCI_FER | SCI_PER)) { + SSR1 &= ~(SCI_ORER | SCI_FER | SCI_PER); + last_valid_button = BUTTON_NONE; + last_was_error = true; + return BUTTON_NONE; + } - switch (byte) - { - case STOP: + if(SSR1 & SCI_RDRF) { + /* Read byte and clear the Rx Full bit */ + btn = RDR1; + SSR1 &= ~SCI_RDRF; + + if(last_was_error) + { + last_valid_button = BUTTON_NONE; + ret = BUTTON_NONE; + } + else + { + switch (btn) + { + case STOP: #ifdef HAVE_RECORDER_KEYPAD - btn = BUTTON_OFF; + last_valid_button = BUTTON_OFF; #else - btn = BUTTON_STOP; + last_valid_button = BUTTON_STOP; #endif - break; - - case PLAY: - btn = BUTTON_PLAY; - break; - - case VOLUP: - btn = BUTTON_VOL_UP; - break; - - case VOLDN: - btn = BUTTON_VOL_DOWN; - break; - - case PREV: - btn = BUTTON_LEFT; - break; - - case NEXT: - btn = BUTTON_RIGHT; - break; - + break; + + case PLAY: + last_valid_button = BUTTON_PLAY; + break; + + case VOLUP: + last_valid_button = BUTTON_VOL_UP; + break; + + case VOLDN: + last_valid_button = BUTTON_VOL_DOWN; + break; + + case PREV: + last_valid_button = BUTTON_LEFT; + break; + + case NEXT: + last_valid_button = BUTTON_RIGHT; + break; + #ifdef SCREENDUMP - case SCRDMP: - screen_dump(); - break; + case SCRDMP: + screen_dump(); + break; #endif + default: + last_valid_button = BUTTON_NONE; + break; + } + } } - - if ( btn ) { - queue_post(&button_queue, btn, NULL); - backlight_on(); - queue_post(&button_queue, btn | BUTTON_REL, NULL); + else + { + /* This means that a valid remote control character was received + the last time we were called, with no receiver errors either before + or after. Then we can assume that there really is a remote control + attached, and return the button code. */ + ret = last_valid_button; + last_valid_button = BUTTON_NONE; } -} - -#pragma interrupt -void REI1 (void) -{ - SSR1 = SSR1 & ~0x10; /* Clear FER */ - SSR1 = SSR1 & ~0x40; /* Clear RDRF */ -} + + last_was_error = false; -#pragma interrupt -void RXI1 (void) -{ - unsigned char serial_byte; - serial_byte = RDR1; - SSR1 = SSR1 & ~0x40; /* Clear RDRF */ - process_byte(serial_byte); + return ret; } #ifdef SCREENDUMP diff --git a/firmware/drivers/serial.h b/firmware/drivers/serial.h index d13b785b9d..f2e5a945dd 100644 --- a/firmware/drivers/serial.h +++ b/firmware/drivers/serial.h @@ -21,5 +21,6 @@ #define __SERIAL_H__ extern void serial_setup (void); +extern int remote_control_rx(void); #endif -- cgit v1.2.3