M:Robe 500: Move all remote specific code into a common file for reuse on other playe...
[kugel-rb.git] / firmware / target / arm / tms320dm320 / mrobe-500 / lcd-remote-mr500.c
blob3ff5d9c2fdc1af3184fb44cc2855afc8d21afba6
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
10 * Copyright (C) 2009 Karl Kurbjun
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "config.h"
23 #include "system.h"
24 #include "file.h"
25 #include "lcd-remote.h"
26 #include "adc.h"
27 #include "scroll_engine.h"
28 #include "uart-target.h"
29 #include "button.h"
31 static enum remote_control_states
33 REMOTE_CONTROL_IDLE,
34 REMOTE_CONTROL_NOP,
35 REMOTE_CONTROL_POWER,
36 REMOTE_CONTROL_MASK,
37 REMOTE_CONTROL_DRAW,
38 REMOTE_CONTROL_SLEEP
39 } remote_state_control = REMOTE_CONTROL_NOP, remote_state_control_next;
41 static enum remote_draw_states
43 DRAW_TOP,
44 DRAW_BOTTOM,
45 DRAW_PAUSE,
46 } remote_state_draw = DRAW_TOP, remote_state_draw_next;
48 static bool remote_hold_button=false;
50 bool remote_initialized=true;
52 static unsigned char remote_contrast=DEFAULT_REMOTE_CONTRAST_SETTING;
53 static unsigned char remote_power=0x00;
54 static unsigned char remote_mask=0x00;
56 /*** hardware configuration ***/
58 int lcd_remote_default_contrast(void)
60 return DEFAULT_REMOTE_CONTRAST_SETTING;
63 void lcd_remote_sleep(void)
65 remote_state_control_next=REMOTE_CONTROL_SLEEP;
68 void lcd_remote_powersave(bool on)
70 if(on)
72 remote_power|=0xC0;
73 remote_state_control_next=REMOTE_CONTROL_POWER;
75 else
77 remote_power&=~(0xC0);
78 remote_state_control_next=REMOTE_CONTROL_POWER;
82 void lcd_remote_set_contrast(int val)
84 remote_contrast=(char)val;
85 remote_state_control_next=REMOTE_CONTROL_POWER;
88 void lcd_remote_set_invert_display(bool yesno)
90 (void)yesno;
93 bool remote_detect(void)
95 return true;
98 void lcd_remote_on(void)
100 remote_power|=0x80;
101 remote_state_control_next=REMOTE_CONTROL_POWER;
104 void lcd_remote_off(void)
106 remote_power&=~(0x80);
107 remote_state_control_next=REMOTE_CONTROL_POWER;
110 /* This is the maximum transfer size to the remote (op 0x51= 7 bytes setup+79
111 * bytes screen data+xor+sum
113 unsigned char remote_payload[88];
114 unsigned char remote_payload_size;
115 bool remote_repeat_draw=false;
117 unsigned char remote_draw_x, remote_draw_y,
118 remote_draw_width, remote_draw_height;
120 /* Monitor remote hotswap */
121 static void remote_tick(void)
123 unsigned char i;
124 static unsigned char pause_length=0;
126 if(remote_state_control!=REMOTE_CONTROL_DRAW)
127 remote_state_control=remote_state_control_next;
129 switch (remote_state_control)
131 case REMOTE_CONTROL_IDLE:
132 remote_payload_size=0;
133 remote_state_control=REMOTE_CONTROL_IDLE;
134 break;
136 case REMOTE_CONTROL_NOP:
137 remote_payload[0]=0x11;
138 remote_payload[1]=0x30;
140 remote_payload_size=2;
141 remote_state_control=REMOTE_CONTROL_NOP;
142 break;
144 case REMOTE_CONTROL_POWER:
145 remote_payload[0]=0x31;
146 remote_payload[1]=remote_power;
147 remote_payload[2]=remote_contrast;
149 remote_payload_size=3;
150 remote_state_control=REMOTE_CONTROL_NOP;
151 break;
153 case REMOTE_CONTROL_MASK:
154 remote_payload[0]=0x41;
155 remote_payload[1]=remote_mask;
157 remote_payload_size=2;
158 remote_state_control=REMOTE_CONTROL_NOP;
159 break;
161 case REMOTE_CONTROL_DRAW:
162 remote_payload[0]=0x51;
163 remote_payload[1]=0x80;
164 remote_payload[2]=remote_draw_width;
165 remote_payload[3]=remote_draw_x;
167 remote_payload[5]=remote_draw_x+remote_draw_width;
168 remote_payload_size=7+remote_payload[2];
170 switch (remote_state_draw)
172 case DRAW_TOP:
173 remote_payload[4]=0;
174 remote_payload[6]=8;
176 pause_length=6;
177 remote_state_draw_next=DRAW_BOTTOM;
178 remote_state_draw=DRAW_PAUSE;
179 break;
181 case DRAW_BOTTOM:
182 remote_payload[4]=8;
183 remote_payload[6]=16;
185 pause_length=6;
186 remote_state_draw_next=DRAW_TOP;
187 remote_state_draw=DRAW_PAUSE;
188 break;
190 case DRAW_PAUSE:
191 remote_payload_size=0;
193 if(--pause_length==0)
195 if(remote_state_draw_next==DRAW_TOP)
196 remote_state_control=REMOTE_CONTROL_NOP;
198 remote_state_draw=remote_state_draw_next;
200 else
201 remote_state_draw=DRAW_PAUSE;
203 break;
205 default:
206 remote_payload_size=0;
207 break;
209 break;
211 case REMOTE_CONTROL_SLEEP:
212 remote_payload[0]=0x71;
213 remote_payload[1]=0x30;
215 remote_payload_size=2;
216 remote_state_control=REMOTE_CONTROL_IDLE;
217 break;
219 default:
220 remote_payload_size=0;
221 break;
224 if(remote_payload_size==0)
226 return;
229 if(remote_payload[0]==0x51)
231 for(i=7; i<remote_payload_size; i++)
233 remote_payload[i]=
234 lcd_remote_framebuffer[remote_payload[4]>>3][i+remote_draw_x-7];
238 /* Calculate the xor and sum to place in the payload */
239 remote_payload[remote_payload_size]=remote_payload[0];
240 remote_payload[remote_payload_size+1]=remote_payload[0];
241 for(i=1; i<remote_payload_size; i++)
243 remote_payload[remote_payload_size]^=remote_payload[i];
244 remote_payload[remote_payload_size+1]+=remote_payload[i];
247 uart1_puts(remote_payload, remote_payload_size+2);
250 void lcd_remote_init_device(void)
252 lcd_remote_clear_display();
253 if (remote_detect())
254 lcd_remote_on();
256 lcd_remote_update();
258 /* put the remote control in the tick task */
259 tick_add_task(remote_tick);
262 /* Update the display.
263 This must be called after all other LCD functions that change the display. */
264 void lcd_remote_update(void)
266 lcd_remote_update_rect(0, 0, LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT);
269 /* Update a fraction of the display. */
270 void lcd_remote_update_rect(int x, int y, int width, int height)
272 remote_draw_x=x;
273 remote_draw_y=y;
274 remote_draw_width=width;
275 remote_draw_height=height;
277 remote_state_control=REMOTE_CONTROL_DRAW;
280 bool remote_button_hold(void)
282 return remote_hold_button;
285 int remote_read_device(void)
287 char read_buffer[5];
288 int read_button = BUTTON_NONE;
290 static int oldbutton=BUTTON_NONE;
292 /* Handle remote buttons */
293 if(uart1_gets_queue(read_buffer, 5)>=0)
295 int button_location;
297 for(button_location=0;button_location<4;button_location++)
299 if((read_buffer[button_location]&0xF0)==0xF0
300 && (read_buffer[button_location+1]&0xF0)!=0xF0)
301 break;
304 if(button_location==4)
305 button_location=0;
307 button_location++;
309 read_button |= read_buffer[button_location];
311 /* Find the hold status location */
312 if(button_location==4)
313 button_location=0;
314 else
315 button_location++;
317 remote_hold_button=((read_buffer[button_location]&0x80)?true:false);
319 uart1_clear_queue();
320 oldbutton=read_button;
322 else
323 read_button=oldbutton;
325 return read_button;
328 void _remote_backlight_on(void)
330 remote_power|=0x40;
331 remote_state_control_next=REMOTE_CONTROL_POWER;
334 void _remote_backlight_off(void)
336 remote_power&=~(0x40);
337 remote_state_control_next=REMOTE_CONTROL_POWER;