source: svn/newcon3bcm2_21bu/nexus/app/bapp_remote.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 9.6 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2006, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile:  $
11 * $brcm_Revision:  $
12 * $brcm_Date: $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log:  $
19 *
20 ***************************************************************************/
21#include "nexus_types.h"
22#include "nexus_platform.h"
23#include "nexus_ir_input.h"
24#include "bapp_remote.h"
25#include "bapp_util.h"
26#include "bapp_task.h"
27#include "bir_codes.h"
28
29BDBG_MODULE(app_remote);                /* Register software module with debug interface */
30
31#define BUSER_IO_NUM_EVENTS     4
32
33#define BUSER_IO_MSG    BDBG_MSG
34
35        /* Convert timeout from milliseconds to ticks */
36#define MAX_TIMEOUT             ((200 * g_ticks_per_second)/ 1000)
37#define DEFAULT_PEND_TIMEOUT    10 /* in milliseconds */
38
39/* See IR State transition diagram in design document */
40 
41typedef enum ir_state_t
42{
43        eSTATE_IDLE,
44        eSTATE_WAIT_NEXT,
45        eSTATE_HOLD
46}ir_state_t;     
47
48
49
50struct bapp_remote
51{
52        /* User IO */
53    NEXUS_PlatformConfiguration platformConfig;
54    NEXUS_IrInputHandle irHandle;
55    NEXUS_IrInputSettings irSettings;
56       
57        unsigned int    timeout;
58        unsigned int    pend_timeout;
59        unsigned int    start_time;
60        ir_state_t              state;
61        unsigned int    cur_key;
62        unsigned int    last_key;
63        int                             event_cnt;
64        bapp_task_queue_t               queue;
65        bapp_task_event_t               events[BUSER_IO_NUM_EVENTS];
66};
67
68
69/* User Input API */
70
71/*
72        Summary:
73                Handle the input key state transitions for the IR remote
74*/
75static void bapp_remote_handle_input(bapp_remote_t handle, unsigned int input_key)
76{
77        struct bapp_remote *p_remote = (struct bapp_remote*)handle; 
78
79        BUSER_IO_MSG(("%s state = %d, timeout = %d, start_time = %d, cur_time = %d,  key = 0x%08x\n"
80                   ,__FUNCTION__,p_remote->state,p_remote->timeout,p_remote->start_time,bapp_task_getticks(),input_key));
81
82        input_key &= 0x00FFFFFF;
83
84        p_remote->cur_key = input_key;
85       
86    switch(p_remote->state)
87        {
88        case eSTATE_IDLE:
89
90                p_remote->start_time = bapp_task_getticks();
91                p_remote->last_key = input_key;
92                p_remote->state = eSTATE_WAIT_NEXT;
93                p_remote->timeout = MAX_TIMEOUT;
94
95                p_remote->event_cnt = 1;
96                bapp_task_post_event(p_remote->queue,(bapp_task_event_t)(eKEY_DOWN | p_remote->last_key));
97                break;
98
99        case eSTATE_WAIT_NEXT:
100               
101                if ((p_remote->start_time + p_remote->timeout) >= bapp_task_getticks())
102                {
103                        if (input_key == p_remote->last_key)
104                        {
105                                p_remote->start_time = bapp_task_getticks();
106                        }
107                        else if (p_remote->event_cnt < 2)
108                        {
109                                p_remote->event_cnt++;
110                                bapp_task_post_event(p_remote->queue,(bapp_task_event_t)(eKEY_UP | p_remote->last_key));
111                                p_remote->last_key = input_key;
112                                p_remote->start_time = bapp_task_getticks();
113                                p_remote->event_cnt++;
114                                bapp_task_post_event(p_remote->queue,(bapp_task_event_t)(eKEY_DOWN | p_remote->last_key));
115                                p_remote->state = eSTATE_WAIT_NEXT;
116                        }
117                }
118                else if (p_remote->event_cnt < 3)
119                {
120                        p_remote->last_key = input_key;
121                        p_remote->start_time = bapp_task_getticks();
122                        p_remote->event_cnt++;
123                        bapp_task_post_event(p_remote->queue,(bapp_task_event_t)(eKEY_DOWN | p_remote->last_key));
124                        p_remote->state = eSTATE_WAIT_NEXT;
125                }
126
127                break;
128        case eSTATE_HOLD:
129                /* this state should not happen from remote */
130                break;
131        }
132}
133/*
134Summary:
135        Channel Manager Task.
136*/
137
138
139
140static void bapp_remote_callback(void *pParam, int iParam)
141{
142       
143        struct bapp_remote *p_remote = (struct bapp_remote*)pParam; 
144    size_t numEvents = 1;
145    NEXUS_Error rc = 0;
146    bool overflow;
147
148        BAPP_UNUSED(iParam);
149    while (numEvents && !rc) 
150        {
151        NEXUS_IrInputEvent irEvent;
152        rc = NEXUS_IrInput_GetEvents(p_remote->irHandle,&irEvent,1,&numEvents,&overflow);
153        if (numEvents)
154                {
155                        BDBG_ERR(("############### %s, irEvent.code = 0x%08x\n",__FUNCTION__,irEvent.code));
156                        bapp_remote_handle_input(p_remote, irEvent.code & 0x0000FFFF);
157                }
158                bapp_util_sleep(0);
159    }
160}
161/*
162Summary:
163Open a user input object for receiving IR remote and keypad input.
164Description:
165For now, the following id's are used:
1660 - remote a
1671 - remote b
1682 - 56 MHz Sejin IR Keyboard
1693 - keypad (TODO implement)
1708 - Moto remote, device_type = 0x14
171 */
172bapp_result_t bapp_remote_open(bapp_remote_t *p_remote)
173{
174        *p_remote = (struct bapp_remote*)bapp_util_malloc(sizeof(struct bapp_remote)); 
175        if (!*p_remote)
176                return eBAPP_RESULT_ALLOC_FAILURE;
177       
178        bapp_util_memset(*p_remote,0,sizeof(struct bapp_remote));
179       
180        /* USER IO */
181
182    NEXUS_IrInput_GetDefaultSettings(&(*p_remote)->irSettings);
183    (*p_remote)->irSettings.mode = NEXUS_IrInputMode_eTwirpKbd;/*NEXUS_IrInputMode_eRemoteA;*/
184    (*p_remote)->irSettings.dataReady.callback = bapp_remote_callback;
185    (*p_remote)->irSettings.dataReady.context = *p_remote;
186    (*p_remote)->irHandle = NEXUS_IrInput_Open(0, &(*p_remote)->irSettings);
187
188        (*p_remote)->pend_timeout = DEFAULT_PEND_TIMEOUT;
189        if (!(*p_remote)->irHandle)
190        {
191                bapp_remote_close(*p_remote);
192                return eBAPP_RESULT_ALLOC_FAILURE;
193        }
194
195        bapp_task_create_queue(&(*p_remote)->queue,(*p_remote)->events,BUSER_IO_NUM_EVENTS);
196        if (!(*p_remote)->queue)
197        {
198                bapp_remote_close(*p_remote);
199                return eBAPP_RESULT_ALLOC_FAILURE;
200        }
201
202        return eBAPP_RESULT_OK;
203}
204
205/*
206Summary:
207Close a user input handle.
208Description:
209Releases all resources associated with the user input object
210 */
211void bapp_remote_close(
212                bapp_remote_t handle /* user input object */
213                )
214{
215        struct bapp_remote *p_remote = (struct bapp_remote*)handle;
216
217        if (p_remote->queue)
218        {
219                bapp_task_delete_queue(p_remote->queue);
220        }
221
222
223        /* USER IO */
224
225    NEXUS_IrInput_Close(p_remote->irHandle);
226
227        bapp_util_free(p_remote);
228}
229/*
230Summary:
231        Map key codes to match type 0
232 */
233static unsigned int bapp_remote_map_twirp( unsigned int code )
234{
235        unsigned int mapped_code = 0xFF;
236        BDBG_ERR(("############### %s, code = 0x%08x\n",__FUNCTION__,code));
237        code &= 0x000000FF;
238        switch (code)
239        {
240                default: mapped_code = code; break;
241
242                case 0x01:  mapped_code = eIR_1; break;
243                case 0x02:  mapped_code = eIR_2; break;
244                case 0x03:  mapped_code = eIR_3; break;
245                case 0x04:  mapped_code = eIR_4; break;
246                case 0x05:  mapped_code = eIR_5; break;
247                case 0x06:  mapped_code = eIR_6; break;
248                case 0x07:  mapped_code = eIR_7; break;
249                case 0x08:  mapped_code = eIR_8; break;
250                case 0x09:  mapped_code = eIR_9; break;
251                case 0x00:  mapped_code = eIR_0; break;
252
253                case 0x0d:  mapped_code = eIR_CH_UP; break;
254                case 0x0e:  mapped_code = eIR_CH_DOWN; break;
255
256                                /* mute */
257                case 0x0c:  mapped_code = eIR_MUTE; break;
258
259                                /* + vol */
260                case 0x0a:  mapped_code = eIR_VOL_UP; break;
261
262                                /* - vol */
263                case 0x0b:  mapped_code = eIR_VOL_DOWN; break;
264                                /* '-' no corresponding key */
265                                /* no - */
266                                /*case 0x9E:  mapped_code = eIR_DOT; break; */
267
268                                /* red C */
269                case 0x62:  mapped_code = eIR_DEBUG1; break;
270                                /* page down */
271                case 0x29:  mapped_code = eIR_DEBUG2; break;
272                                /* page up */
273                case 0x28:  mapped_code = eIR_POWER_SAVING; break;
274
275                                /* exit */
276                case 0x2a:  mapped_code = eIR_EXIT; break;
277                                /* menu */
278                case 0x20:  mapped_code = eIR_MENU; break;
279
280                case 0x21:  mapped_code = eIR_UP; break;
281                case 0x23:  mapped_code = eIR_LEFT; break;
282                case 0x25:  mapped_code = eIR_SELECT; break;
283                case 0x24:  mapped_code = eIR_RIGHT; break;
284                case 0x22:  mapped_code = eIR_DOWN; break;
285
286                case 0x26:  mapped_code = eIR_INFO; break;
287                case 0x27:  mapped_code = eIR_GUIDE; break;
288                case 0x51:  mapped_code =  eIR_PRECH; break;
289
290                                /* power */
291                case 0x0f:  mapped_code = eIR_POWER; break;
292
293                                /* help */
294                case 0x56:  mapped_code = eIR_HELP; break;
295
296                                /* FAV */
297                case 0x52:  mapped_code = eIR_FAV; break;
298        }
299        return mapped_code;
300}
301
302/*
303Summary:
304map gpio based buttons to key code based on current IR remote protocol used
305
306 */
307static unsigned int bapp_remote_map_code(
308        bapp_remote_t handle, /* user input object */
309        unsigned int button_id)
310{
311        switch (handle->irSettings.mode)
312        {
313        case NEXUS_IrInputMode_eCirTwirp:
314        case NEXUS_IrInputMode_eTwirpKbd:
315                button_id = bapp_remote_map_twirp(button_id);
316                break;
317        default:
318                break;
319        }
320        return button_id;
321}
322
323/*
324Summary:
325Read events from a user input device.
326
327Description:
328Because this function does not return a void* to raw data, but an array of structures,
329it is not called buser_input_read.
330 */
331bapp_result_t bapp_remote_get_event(
332                bapp_remote_t handle, /* user input object */
333                bapp_event_t *event /* [out,size_is(nevents)] event from the user */
334                )
335{
336        uint32_t pend_event;
337        bapp_result_t result = eBAPP_RESULT_BUSY;
338        struct bapp_remote *p_remote = (struct bapp_remote*)handle; 
339       
340        event->type = eBAPP_EVENT_IR;
341
342        pend_event = (unsigned int)bapp_task_pend_event(p_remote->queue,p_remote->pend_timeout);
343
344        if (pend_event)
345        {
346                BDBG_ERR(("%s, pend_event = 0x%08x\n",__FUNCTION__,pend_event));
347                pend_event >>= 8;
348                event->id = pend_event & 0xFF;
349                /* To match settop api behavior only return key down events and
350                   throw away key up events */
351                if (!(pend_event & eKEY_CMD))
352                {
353                        event->id = bapp_remote_map_code(handle,event->id);
354                }
355
356                if (pend_event & eKEY_UP)
357                        event->id |= eKEY_UP;
358                result = eBAPP_RESULT_OK;
359                BUSER_IO_MSG(("%s, event = 0x%08x\n",__FUNCTION__,event->id));
360        }
361        else if (p_remote->state == eSTATE_WAIT_NEXT)
362        {
363                if (p_remote->start_time + p_remote->timeout < bapp_task_getticks())
364                {
365                        p_remote->state = eSTATE_IDLE;
366                        event->id = p_remote->last_key & 0xFF;/* To provide same key code as settop api */
367                        event->id = bapp_remote_map_code(handle,event->id);
368
369                        event->id |= eKEY_UP; /* add modifier flag to identify as key up */
370                        result = eBAPP_RESULT_OK;
371                        BUSER_IO_MSG(("%s, event = 0x%08x\n",__FUNCTION__,event->id));
372                        return result;
373
374                }
375        }
376
377        return result;
378}
379
Note: See TracBrowser for help on using the repository browser.