📄 control.c
字号:
ramenable(); // enable ExtRAM
return (event);
}
#ifdef ROTTARY_CONTROL
/****************************************************************************************
* ROTARY SWITCH CONTROL FUNCTION *
****************************************************************************************/
// Rotary switch connected to PD0 and PD1 after disconnecting MAX202 chip from PD0 line.
// This configuration uses UART Receive interrupt for rotary switch control. After
// UART detecting hi to low edge at RXD pin, start receiving data. After 200us from first
// edge (at 9600 baud UART speed) UART generate UART_RECEIV interrupt, but with framming
// error because not valid stop bit is received. UDR have received data. This data is
// used for magic debounce, and reading of UDR clearing interrupt flag. Next time, the
// uart interrupt is disabled because may generate several interrupts within continued
// low state at RXD pin. If main loop detect HI state at RXD, enable interrupt agin.
#define ROTARY_UP EV_UP
#define ROTARY_DOWN EV_DOWN
#define ROT_PORT PORTD
#define ROT_PIN1 PD0
#define ROT_PIN2 PD1
u08 rotary_direction;
SIGNAL(SIG_UART0_RECV) // rotary switch interrupt from uart :-)
{
if((inp(UDR0) & 0xf0) == 0) // magic debounce and interrupt flag clearing
{
if (bit_is_set(ROT_PORT-2, ROT_PIN2)) // check second rotary pin (direction)
rotary_direction = ROTARY_UP;
else
rotary_direction = ROTARY_DOWN;
outp(0, UCSR0B); // disable receiver interrupt
}
}
void rotary_init(void)
{
sbi(ROT_PORT, ROT_PIN1);
sbi(ROT_PORT, ROT_PIN2); // enable pullups
cbi(ROT_PORT-1, ROT_PIN1);
cbi(ROT_PORT-1, ROT_PIN2); // rotary pins as inputs
outp(0, UBRRH);
outp(7 ,UBRR0); // for 57600 baud speed - about 200us byte time
outp(_BV(RXCIE) | _BV(RXEN) ,UCSR0B); // enable receiver and receiver interrupt
}
u08 get_rotary_event()
{
u08 event = EV_IDLE;
if(bit_is_set(ROT_PORT-2, ROT_PIN1))
outp(_BV(RXCIE) | _BV(RXEN) ,UCSR0B); // re enable receiver and receiver interrupt
if(rotary_direction)
{
event = rotary_direction;
rotary_direction = 0;
nKeyTime = 0;
}
return(event);
}
#endif // ROTTARY_CONTROL
#else // SATTELITE ON
/****************************************************************************************
* SATTELITE COMMUNICATION FUNSTIONS *
****************************************************************************************/
u08 linkholder;
u08 player_state = 0;
static u08 uart_chars1[]= SAT_CONTROL1; // Tokens table for Sattelite control1
static u08 uart_chars2[]= SAT_CONTROL2; // Tokens table for Sattelite control2
void Send_state(u08 state)
{
uart_pc1(SAT_CMD_MARKER);
uart_pc1(SAT_STATE);
if(state != 0xff)
{
if((state & 0x0F))
{
player_state &= 0xF0;
player_state |= (state & 0x0F);
}
if((state & 0xF0))
{
player_state &= 0x0F;
if(state != STATE_RETURN)
player_state |= (state & 0xF0);
}
}
uart_pc1(player_state);
}
u08 Sattelite_init()
{
u08 i = 0;
#ifdef LCD_NEGATIV
i++;
#endif
#ifdef ALT_BAR_STYLE
i+=2;
#endif
uart_pc1(SAT_CMD_MARKER);
uart_pc1(SAT_LCDTYPE);
uart_pc1(LCD_TYPE);
uart_pc1(LCD_LINE_LENGTH);
uart_pc1(LCD_LINES);
uart_pc1(GRAPHICS_LCD_CONTRAST);
uart_pc1(i);
uart_pc1(tolower(uart_chars1[EV_UP-1]));
uart_pc1(tolower(uart_chars1[EV_DOWN-1]));
uart_pc1(tolower(uart_chars1[EV_FFWD-1]));
uart_pc1(tolower(uart_chars1[EV_FREW-1]));
for(i=0; i<5; i++)
{
delayms(10);
if(uart_haschar())
{
if(uart_getchar() == '+')
return 0;
}
}
return 1;
}
void Vlcd_clrscr(void) // send clrscr command to Sattelite
{
uart_pc1(SAT_CMD_MARKER);
uart_pc1(SAT_CLRSCR);
delayms(5);
}
void lcd_clrline(u08 line)
{
uart_pc1(SAT_CMD_MARKER);
uart_pc1(SAT_CLRLINE);
uart_pc1(line);
}
void Vlcd_gotoxy(u08 x, u08 y)
{
uart_pc1(SAT_CMD_MARKER);
uart_pc1(SAT_GOTOXY);
uart_pc1(x);
uart_pc1(y);
}
void Vlcd_puts(char s[]) // print RAM string on Sattelite
{
u08 linelen=LCD_LINE_LENGTH;
while(*s && linelen--)
uart_putchar(*s++);
}
void Vlcd_progputs(char s[]) // print ROM string on Sattelite
{
u08 b, *p=s;
while (p && (b = PRG_RDB(p++)))
uart_putchar(b);
}
void Vlcd_bar(u08 val, u08 len)
{
uart_pc1(SAT_CMD_MARKER);
uart_pc1(SAT_BAR);
uart_pc1(val);
uart_pc1(len);
}
u08 Vlcd_logo(void) // display startup logo on Sattelite LCD
{
u08 i;
uart_pc1(SAT_CMD_MARKER);
uart_pc1(SAT_LOGO);
for(i=0; i<5; i++)
{
delayms(10);
if(uart_haschar())
return(uart_getchar());
}
return 1;
}
void Vlcd_invert(void) // start invert mode
{
uart_pc1(SAT_CMD_MARKER);
uart_pc1(SAT_INVERS);
}
void Vlcd_normal(void) // end invert mode
{
uart_pc1(SAT_CMD_MARKER);
uart_pc1(SAT_NORMAL);
}
void Vlcd_wrdata(u08 data)
{
uart_pc1(SAT_CMD_MARKER);
uart_pc1(SAT_RAWDAT);
uart_pc1(data);
}
u08 ir_active;
u16 ir_code;
u16 get_rec80(u08 std)
{
static u08 old_std = 128;
if(old_std != std)
{
uart_pc1(SAT_CMD_MARKER);
uart_pc1(SAT_IRSTAND);
uart_pc1(std);
old_std = std;
ir_code = 0;
}
ir_active = 0;
return(ir_code);
}
u08 rec80_active(void)
{
return(ir_active);
}
#endif // #ifdef SATTELITE
/****************************************************************************************
* MAIN PLAYER CONTROL FUNSTIONS *
****************************************************************************************/
extern u08 ir_standard;
#ifdef NUMERICAL_KEYS
u08 number_key;
#endif
void control_handler(void)
{
event_e event = EV_IDLE;
u08 i;
#ifdef ENABLE_UART
u08 c;
static u08 uart_chars[]= UART_CHARS; // Tokens table for UART control
if (uart_haschar()) // Check UART event
{
c = uart_getchar(); // get char
for(i=0; i < sizeof(uart_chars); i++)
{
if(c == uart_chars[i]) // check tokens tabele
{
event = i+1; // found
break;
}
}
}
#endif
#ifdef SATTELITE
u08 c;
extern void lcd_frame(void);
extern u08 isPlaying;
if (uart_haschar()) // Check UART event
{
c = uart_getchar(); // get char
if(c == '-') // sattelite reinit request
{
Sattelite_init();
Send_state(0xff); // send last state
if(isPlaying)
lcd_frame();
else
event = EV_STOP;
}
else if(c == '$') // sattelite STOP request
event = EV_STOP;
else if(c == 'Z') // sattelite remote code present
{
ir_code = uart_getchar() * 256; // function code H
ir_code += uart_getchar(); // function code L
ir_active = 1;
}
else if(c == 'z') // sattelite remote code present
{
ir_code = 0;
ir_active = 2;
}
else for(i=0; i < sizeof(uart_chars1); i++) // sattelite standard events processing
{
if(c == uart_chars1[i] || c == uart_chars2[i]) // check tokens tabeles
{
event = i+1; // found
nKeyTime = 0;
break;
}
}
}
extern u08 scroll_time;
if(scroll_time % 10 == 0)
linkholder = 0;
if(scroll_time % 10 == 9 && !linkholder) // send link-up holder command
{
uart_pc1(SAT_CMD_MARKER);
uart_pc1(SAT_LINKHOLDER);
linkholder = 1;
}
#endif
static event_e OldEvent = EV_IDLE;
static u16 Lcod;
if ((ir_standard != 255) && rec80_active()) // Check IR event
{
u16 code = get_rec80(ir_standard);
if (!(Lcod == code && nKeyTime <= DOUBLE_TRAP)) // Trap for some IR transmitters that fast repeat
{
#ifdef NUMERICAL_KEYS
for (i = 0; i < (2 * (EV_LASTEVENT+10)); i+=2)
#else
for (i = 0; i < (2 * EV_LASTEVENT); i+=2) // search with all memorized codes
#endif
if (eeprom_rw(EEPROM_RemCodes + i) == code) // if valid keycode found
{
OldEvent = i/2 + 1; // Save event number
#ifdef ENABLE_AUTOREPEAT
RET_LAST:
#endif
nKeyTime = 0;
Lcod = code; // For trap function
#ifdef NUMERICAL_KEYS
if (OldEvent > EV_LASTEVENT) // if numerical key pressed
{
number_key = OldEvent - EV_LASTEVENT - 1; // save number (0-9)
OldEvent = EV_NUMBER; // set event as EV_NUMBER,
} // number is stored in number_key variable
#endif
event = OldEvent;
break;
}
#ifdef ENABLE_AUTOREPEAT
if ((nKeyTime >= 2) && (OldEvent == EV_UP || OldEvent == EV_DOWN ||
OldEvent == EV_FFWD || OldEvent == EV_FREW))
goto RET_LAST; // Autorepeat feature on some keys
#endif
}
}
else
{
if (nKeyTime > 10)
OldEvent = EV_IDLE;
}
#ifndef SATTELITE
if (event == EV_IDLE)
event = get_key_event(); // Check keyboard
#ifdef ROTTARY_CONTROL // local rotary switch
if (event == EV_IDLE)
event = get_rotary_event(); // Check Rotary Switch
#endif
#endif // ifndef SATTELITE
if (event != EV_IDLE)
set_event(event); // Add event to queue
}
/****************************************************************************************
* SETUP REMOTE CODES FUNSTIONS *
****************************************************************************************/
static u16 ee_adr;
extern u08 time_flag;
void get_rem_code(u08* name, u08 stand)
{
u16 code;
event_e event;
do
{
code = eeprom_rw(ee_adr); // Get old Key Code
goto PRINT_CODE;
while((event = get_event()) == EV_IDLE)
{
time_flag = 0;
if (rec80_active()) // if IR active
{
if ((code = get_rec80(stand))) // Get Code and validation
{
PRINT_CODE: lcd_clrline(1);
uart_EOL();
both_progputs(name); // Print Event Name
lprintf(": %04x",code); // Print Key Code
#ifdef ENABLE_UART
uprintf(": %04x",code);
#endif
eeprom_ww(ee_adr, code); // Store Key Code to EEPROM
}
}
}
if (event == EV_STOP) // If Clear
{
eeprom_ww(ee_adr, 0xffff); // Clear Key Code
break;
}
} while(event != EV_PLAY);
ee_adr += 2; // Next code address
delayms(100);
return;
}
#ifdef AUTODETECT_STANDARD
static u08 ir0[] __attribute__ ((progmem)) = "REC80 ";
static u08 ir1[] __attribute__ ((progmem)) = "NEC80 ";
static u08 ir2[] __attribute__ ((progmem)) = "SONY15";
static u08 ir3[] __attribute__ ((progmem)) = "SONY12";
static u08 ir4[] __attribute__ ((progmem)) = "RC-5 ";
u08 *standard_name[] = { (u08*)&ir0, (u08*)&ir1, (u08*)&ir2, (u08*)&ir3, (u08*)&ir4 };
#endif
void setup_rem(void)
{
u08 stand = 0;
u08 i=4;
ir_standard = 255;
ee_adr = EEPROM_RemCodes;
Send_state(STATE_IR_LEARN);
#ifdef AUTODETECT_STANDARD
Vlcd_clrscr();
uart_EOL();
both_progputs(PSTR("Remote setup:\n"));
both_progputs(PSTR("Standard 0 ?"));
while(1) // Recognize IR standard
{
time_flag = 0;
if (rec80_active())
{
Vlcd_gotoxy(9,1);
if (get_rec80(stand)) // If != 0 - found standard
{
uart_EOL();
both_progputs(standard_name[stand]);
delayms(3000);
break;
}
else
{
if(--i == 0)
{
stand = (stand+1) % STANDARDS_COUNT;
i=4;
both_putchar(stand+'0');
}
}
}
if(get_event() == EV_STOP)
{
set_event(EV_STOP);
return;
}
}
#endif
Vlcd_clrscr();
uart_EOL();
both_progputs(PSTR("PLAY-Ok,STOP-Clear"));
for(i=0; i < EV_LASTEVENT-4; i++)
get_rem_code(function_name[i],stand); // Learn Remote Events codes
while(ee_adr++ < EV_LASTEVENT * 2 + EEPROM_RemCodes) // fill rest function with 0xffff
eeprom_wb(ee_adr, 0xff);
#ifdef NUMERICAL_KEYS
static u08 num[] __attribute__ ((progmem)) = {'0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0};
ee_adr--;
for(i=0; i<10; i++)
get_rem_code((u08*)&num[2*i],stand); // Learn Numerical keys codes
#endif
#ifdef AUTODETECT_STANDARD
ir_standard = stand;
eeprom_wb(EEPROM_IRSTAND,ir_standard); // Store IR Standard into EEPROM
#endif
both_progputs(PSTR("\rDone !"));
Send_state(STATE_IR_ENDL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -