/*************************************************************** ** ** Broadcom Corp. Confidential ** Copyright 1998-2000 Broadcom Corp. All Rights Reserved. ** ** THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED ** SOFTWARE LICENSE AGREEMENT BETWEEN THE USER AND BROADCOM. ** YOU HAVE NO RIGHT TO USE OR EXPLOIT THIS MATERIAL EXCEPT ** SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. ** ** File: pc_fstore.c ** Description: Flash storage manager ** ****************************************************************/ /* include files */ #include "bsettop_user_io.h" #define BUSER_IO_NUM_EVENTS 4 #define BUSER_IO_MSG(x) ((void)0) //#define BUSER_IO_MSG(x) printf x #define MAX_TIMEOUT ((200 * g_ticks_per_second)/ 1000) #define DEFAULT_PEND_TIMEOUT 10 /* in milliseconds */ /* See IR State transition diagram in design document */ typedef enum ir_state_t { eSTATE_IDLE, eSTATE_WAIT_NEXT }ir_state_t; /* Key code modifier stored in msb of event but this might not work for all protocols */ typedef enum ir_key_type_t { eKEY_DOWN = 0x80000000, eKEY_UP = 0x40000000, eKEY_CMD = 0x20000000, }ir_key_type_t; struct buser_input { unsigned int input_device_type; unsigned int timeout; unsigned int pend_timeout; unsigned int start_time; ir_state_t state; unsigned int cur_key; unsigned int last_key; int event_cnt; b_queue_t queue; b_event_t events[BUSER_IO_NUM_EVENTS]; /* for same kind of IR remote but generate diffrent key map, like Comcast ones */ unsigned int input_device_subtype; /* build intelligent to diffrentiate them */ int repeat; /* repeat key */ }buser_input; struct buser_input s_buser_input = { 0, 40,0,eSTATE_IDLE,0,0 }; /* Summary: Handle the input key state transitions for the IR remote */ static void pc_handle_ir_input( unsigned int input_key, int port) { BUSER_IO_MSG(("%s state = %d, timeout = %d, start_time = %d, cur_time = %d, key = 0x%08x\n" ,__FUNCTION__,s_buser_input.state,s_buser_input.timeout,s_buser_input.start_time,bos_getticks(),input_key)); input_key &= 0x00FFFFFF; s_buser_input.cur_key = input_key; switch(s_buser_input.state) { case eSTATE_IDLE: s_buser_input.start_time = bos_getticks(); s_buser_input.last_key = input_key; s_buser_input.state = eSTATE_WAIT_NEXT; s_buser_input.timeout = (port + 1) * MAX_TIMEOUT; s_buser_input.event_cnt = 1; bos_post_event(s_buser_input.queue,(b_event_t*)(eKEY_DOWN | s_buser_input.last_key)); break; case eSTATE_WAIT_NEXT: if ((s_buser_input.start_time + s_buser_input.timeout) >= bos_getticks()) { if (input_key == s_buser_input.last_key) { s_buser_input.start_time = bos_getticks(); } else if (s_buser_input.event_cnt < 2) { s_buser_input.event_cnt++; bos_post_event(s_buser_input.queue,(b_event_t*)(eKEY_UP | s_buser_input.last_key)); s_buser_input.last_key = input_key; s_buser_input.start_time = bos_getticks(); s_buser_input.event_cnt++; bos_post_event(s_buser_input.queue,(b_event_t*)(eKEY_DOWN | s_buser_input.last_key)); s_buser_input.state = eSTATE_WAIT_NEXT; } } else if (s_buser_input.event_cnt < 3) { s_buser_input.last_key = input_key; s_buser_input.start_time = bos_getticks(); s_buser_input.event_cnt++; bos_post_event(s_buser_input.queue,(b_event_t*)(eKEY_DOWN | s_buser_input.last_key)); s_buser_input.state = eSTATE_WAIT_NEXT; } break; } } extern pc_post_user_io_event(char* name,unsigned int id) { pc_handle_ir_input(id,0); } buser_input_t buser_input_open( bobject_t user_input_id ) { static int s_init = 0; if (!s_init) { s_init = 1; s_buser_input.timeout = MAX_TIMEOUT; s_buser_input.pend_timeout = DEFAULT_PEND_TIMEOUT; bos_create_queue(&s_buser_input.queue,s_buser_input.events,BUSER_IO_NUM_EVENTS); } return (buser_input_t)&s_buser_input; } void buser_input_close( buser_input_t ui) { if (s_buser_input.queue) { bos_delete_queue(&s_buser_input.queue); } } bresult buser_input_get_event( buser_input_t ui, buser_input_event *event, unsigned nevents, unsigned *result_nevents) { uint32_t pend_event; bresult result = berr_not_available; *result_nevents = 0; pend_event = (unsigned int)bos_pend_event(s_buser_input.queue,s_buser_input.pend_timeout); if (pend_event) { /* To match settop api behavior only return key down events and throw away key up events */ *result_nevents = 1; event[0].code = pend_event & 0xFF;/* To provide same key code as settop api */ if (!(pend_event & eKEY_CMD)) { event[0].code = buser_input_map_code(event[0].code); } if (event[0].code == 0xFF) *result_nevents = 0; if (pend_event & eKEY_UP) event[0].code |= eKEY_UP; result = b_ok; BUSER_IO_MSG(("%s, event = 0x%08x\n",__FUNCTION__,event[0].code)); } else if (s_buser_input.state == eSTATE_WAIT_NEXT) { if (s_buser_input.start_time + s_buser_input.timeout < bos_getticks() || s_buser_input.repeat) { s_buser_input.repeat = false; s_buser_input.state = eSTATE_IDLE; *result_nevents = 1; event[0].code = s_buser_input.last_key & 0xFF;/* To provide same key code as settop api */ event[0].code = buser_input_map_code(event[0].code); if (event[0].code == 0xFF) *result_nevents = 0; else event[0].code |= eKEY_UP; /* add modifier flag to identify as key up */ result = b_ok; BUSER_IO_MSG(("%s, event = 0x%08x\n",__FUNCTION__,event[0].code)); return result; } } return result; } unsigned int buser_input_map_code( unsigned int code ) { return code; } void buser_input_sim_key(uint32_t code) { pc_post_user_io_event(NULL,code); }