/*************************************************************************** * Copyright (c) 2003-2006, Broadcom Corporation * All Rights Reserved * Confidential Property of Broadcom Corporation * * 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. * * $brcm_Workfile: $ * $brcm_Revision: $ * $brcm_Date: $ * * Module Description: * * Revision History: * * $brcm_Log: $ * ***************************************************************************/ #include "bapp.h" #include "bstd.h" #include "bapp_util.h" #include "bgfx.h" #include "chan_mgr.h" #include "bchp_hifidac_ctrl0.h" #include "bchp_sun_top_ctrl.h" #include "bchp_hifidac_rm0.h" BDBG_MODULE(bscreen_debug); /* Register software module with debug interface */ typedef enum dbg_layout_t { eDBG_STATUS_X = 260, eDBG_STATUS_Y = 40, eDBG_COL_WIDTH = 170, eDBG_ROW_HEIGHT = 26, }dbg_layout_t; static const unsigned char *s_status_str_table[] = { "V/A/PCR PID:", "VSTC/PTS:", "ASTC/PTS:", "AV,V,A Delta:", "A/V FIFO:", "SRC W:H:", "CH#,FREQ:", "SNR:", "State:", "Version:", #ifdef CONFIG_SCL_INFO "SCL IN:", "SCL OUT:", "SRC OUT:", "WIN:", "PanScan:", #endif "\0" }; /* left, freq 1000, count 48, repeat 1 */ static const uint32_t s_1khz_samples[] = { (uint32_t) 0, (uint32_t) 68433, (uint32_t) 135695, (uint32_t) 200636, (uint32_t) 262143, (uint32_t) 319166, (uint32_t) 370727, (uint32_t) 415945, (uint32_t) 454046, (uint32_t) 484378, (uint32_t) 506422, (uint32_t) 519802, (uint32_t) 524287, (uint32_t) 519802, (uint32_t) 506422, (uint32_t) 484378, (uint32_t) 454046, (uint32_t) 415945, (uint32_t) 370727, (uint32_t) 319166, (uint32_t) 262143, (uint32_t) 200636, (uint32_t) 135695, (uint32_t) 68433, (uint32_t) 0, (uint32_t) -68433, (uint32_t) -135695, (uint32_t) -200636, (uint32_t) -262143, (uint32_t) -319166, (uint32_t) -370727, (uint32_t) -415945, (uint32_t) -454046, (uint32_t) -484378, (uint32_t) -506422, (uint32_t) -519802, (uint32_t) -524287, (uint32_t) -519802, (uint32_t) -506422, (uint32_t) -484378, (uint32_t) -454046, (uint32_t) -415945, (uint32_t) -370727, (uint32_t) -319166, (uint32_t) -262144, (uint32_t) -200636, (uint32_t) -135695, (uint32_t) -68433 }; static int s_1khz_samples_num = sizeof(s_1khz_samples)/sizeof(s_1khz_samples[0]); /* Actual frequency: 10000, Repeat count: 24, Number of sine waves per repeat: 5 */ static const uint32_t s_10khz_samples[] = { (uint32_t) 0, (uint32_t) 506422, (uint32_t) 262143, (uint32_t) -370727, (uint32_t) -454046, (uint32_t) 135695, (uint32_t) 524287, (uint32_t) 135695, (uint32_t) -454046, (uint32_t) -370727, (uint32_t) 262144, (uint32_t) 506422, (uint32_t) 0, (uint32_t) -506422, (uint32_t) -262144, (uint32_t) 370727, (uint32_t) 454046, (uint32_t) -135695, (uint32_t) -524287, (uint32_t) -135695, (uint32_t) 454046, (uint32_t) 370727, (uint32_t) -262143, (uint32_t) -506422 }; static int s_10khz_samples_num = sizeof(s_10khz_samples)/sizeof(s_10khz_samples[0]); static bool antenna_detect = false; /* Summary: Use the this function to get a UNI string. */ static void get_status_str(bapp_t *p_app, int text_id, /* Text id */ unsigned int *p_uni_str, /* Buffer to put UNI string into */ unsigned int *str_len, /* On input the max length in words on output the actual size in characters. */ bdecode_status *p_status, btuner_ds_status *p_ds_status ) { static char ts_str[64]; *str_len = 0; switch (text_id) { case 0: *str_len = snprintf(ts_str,64,"0x%04x, 0x%04x, 0x%04x",p_status->vPID,p_status->aPID,p_status->pcrPID); break; case 1: *str_len = snprintf(ts_str,64,"0x%08x/0x%08x",p_status->video_stc,p_status->video_pts); break; case 2: *str_len = snprintf(ts_str,64,"0x%08x/0x%08x",p_status->audio_stc,p_status->audio_pts); break; case 3: *str_len = snprintf(ts_str,64,"%d,%d,%d",(int)p_status->audio_pts - (int)p_status->video_pts, (int)p_status->audio_stc-(int)p_status->audio_pts, (int)p_status->video_stc-(int)p_status->video_pts); break; case 4: *str_len = snprintf(ts_str,64,"%d/%d,%d/%d",p_status->audio_fifo_depth,p_status->audio_fifo_size,p_status->video_fifo_depth,p_status->video_fifo_size); break; case 5: *str_len = snprintf(ts_str,64,"%d:%d(%s,%d)",p_status->source_width,p_status->source_height,(p_status->bStreamProgressive ? "P" : "I"),p_status->video_aspect_ratio); break; case 6: *str_len = snprintf(ts_str,64,"%d,%d,%s",p_app->cur_ch_num + 2,p_ds_status->freq, antenna_detect ? "Smart" : "STD"); break; case 7: *str_len = snprintf(ts_str,64,"%d",p_ds_status->snr); break; case 8: *str_len = snprintf(ts_str,64,"%s(late: %d/%d) %s",(p_status->bVideoDecoderState == 0) ? "stop" : "start",p_status->late_int, p_status->picture_int_cnt,(ReadReg32(BCHP_HIFIDAC_CTRL0_MUTECTRL) & BCHP_HIFIDAC_CTRL0_MUTECTRL_MUTEALL_MASK) ? "mute" : "unmute"); break; case 9: *str_len = snprintf(ts_str, 64, "%d.%d.%d, %s", MAJOR_VERSION,MINOR_VERSION,SUB_VERSION,__DATE__); break; #ifdef CONFIG_SCL_INFO case 10: *str_len = snprintf(ts_str,64,"%d,%d,%d,%d",p_status->scl_cut_left,p_status->scl_cut_top,p_status->scl_cut_width,p_status->scl_cut_height); break; case 11: *str_len = snprintf(ts_str,64,"%d,%d,%d,%d",p_status->scl_out_left,p_status->scl_out_top,p_status->scl_out_width,p_status->scl_out_height); break; case 12: *str_len = snprintf(ts_str,64,"%d,%d,%d,%d",p_status->src_out_left,p_status->src_out_top,p_status->src_out_width,p_status->src_out_height); break; case 13: *str_len = snprintf(ts_str,64,"%d,%d,%d,%d",p_status->win_left,p_status->win_top,p_status->win_width,p_status->win_height); break; case 14: *str_len = snprintf(ts_str,64,"%d,%d(0x%04x)",p_status->hPanScan,p_status->vPanScan,p_status->video_format); break; #endif } if (*str_len) { *str_len = c_to_uni_str(ts_str,p_uni_str,*str_len); } } /* Summary: Use the this function to get a UNI string. */ static void get_status_label( int text_id, /* Text id */ unsigned int *p_uni_str, /* Buffer to put UNI string into */ unsigned int *str_len /* On input the max length in words on output the actual size in characters. */ ) { char *p_str; p_str = (char*)s_status_str_table[text_id]; if (!p_str) { *str_len = 0; return; } *str_len = c_to_uni_str(p_str,p_uni_str,*str_len); } /* Summary: Status screen drawing function. */ void bscreen_status_draw(void *v_app, void *v_screen) { bapp_t *p_app = (bapp_t*)v_app; /* not used bscreen_t *p_screen = (bscreen_t*)v_screen; */ uint16_t x,y,y_off; unsigned int num_chars = 0; int i; bdecode_status status; btuner_ds_status ds_status; x = eDBG_STATUS_X; y = eDBG_STATUS_Y; i = 0; status.audio_decode = p_app->audio; bdecode_get_status(p_app->decode,&status); btuner_get_ds_status(p_app->tuner, &ds_status); while (*(s_status_str_table[i]) != '\0') { y_off = y + (i * eDBG_ROW_HEIGHT); bgfx_fill_rect(&p_app->surf,x,y_off,eWIDTH - x,eDBG_ROW_HEIGHT,eCOLOR_BLACK_65); num_chars = SCREEN_MAX_STR_WIDTH; get_status_label(i, p_app->tmp_str, &num_chars); text_box(&p_app->surf, p_app->p_font[eLANG_ENGLISH][eFONT_SIZE_SMALL], x, y_off, eDBG_COL_WIDTH - 20, eDBG_ROW_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,0); num_chars = SCREEN_MAX_STR_WIDTH; get_status_str(p_app,i,p_app->tmp_str, &num_chars,&status, &ds_status); text_box(&p_app->surf, p_app->p_font[eLANG_ENGLISH][eFONT_SIZE_SMALL], x + eDBG_COL_WIDTH + 20, y_off, eWIDTH - x - eDBG_COL_WIDTH, eDBG_ROW_HEIGHT, p_app->tmp_str, num_chars, eCOLOR_WHITE,0); i++; } } /* Summary: Status screen event handler for debugging and monitoring. . */ #ifdef CONFIG_BCM_FACTORY_TEST int bscreen_status_event(void *v_app, void *v_screen, bscreen_event_t *p_event) { bapp_t *p_app = (bapp_t*)v_app; bscreen_t *p_screen = (bscreen_t*)v_screen; int result = 0; int i; unsigned int flags; static bool tune = false; static int cnt = 0; static int reject_key_timeout = 10; switch (p_event->type) { case eS_EVENT_IDLE: { if (reject_key_timeout > 0) { reject_key_timeout--; if (reject_key_timeout == 0) { bapp_sync(p_app); bgfx_fill_rect(&p_app->surf,0,0,eWIDTH,eHEIGHT,eCOLOR_CLEAR); bapp_flush_screen(p_app); } } if (cnt++ == 10) { cnt = 0; bapp_sync(p_app); bscreen_status_draw(v_app,v_screen); bapp_flush_screen(p_app); } } break; case eS_EVENT_SETUP_DONE: result = 0; BDBG_WRN(("eS_EVENT_SETUP_DONE...\n")); if (p_app->factory_test) { result = 1; p_app->cur_ch_num = 0; tune = true; } break; case eS_EVENT_SETUP: BDBG_WRN(("eS_EVENT_SETUP...\n")); if (p_app->factory_test) { antenna_detect = bant_detect(); p_app->audio_vol = 100; bapp_set_audio_volume(p_app, p_app->audio_vol); /* For factory test mode only */ flags = bos_enter_critical(); WriteReg32(LED_DATA_REG, ReadReg32( LED_DATA_REG) | LED_GREEN_MASK); bos_exit_critical(flags); } result = 1; flags = bos_enter_critical(); #if (BCHP_CHIP!=3543) WriteReg32(LED_DATA_REG, ReadReg32( LED_DATA_REG) & ~LED_RED_MASK); #else WriteReg32(BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1, ReadReg32( BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1) & ~BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1_irw_top_sw_led_cntrl_MASK); #endif bos_exit_critical(flags); bapp_av_mute(p_app, 0); break; case eS_EVENT_SELECTED: result = (p_screen->button_selection == p_event->id) ? 1 : 0; break; case eS_EVENT_CHECKED: result = (p_screen->button_checked == p_event->id) ? 1 : 0; break; case eS_EVENT_IR: { if (reject_key_timeout > 0) { BDBG_WRN(("############ STARTING UP THROW AWAY KEY (0x%08x) ############",p_event->id)); break; } if (p_event->id & 0x40000000) { BDBG_WRN(("############ THROW AWAY KEY UP (0x%08x) ############",p_event->id)); break; } switch (p_event->id) { case eIR_CH_UP: case eIR_UP: result = bapp_change_channel(p_app, 1, 1); break; case eIR_CH_DOWN: case eIR_DOWN: result = bapp_change_channel(p_app, 0, 1); break; case eIR_RIGHT: { static char idx = 0; if (idx < 4) { p_app->settings.ch[p_app->cur_ch_num].cmd = idx << 5; } else { p_app->settings.ch[p_app->cur_ch_num].cmd = 0; } bant_send(p_app->settings.ch[p_app->cur_ch_num].cmd, p_app->settings.ch[p_app->cur_ch_num].freq_idx + 2); idx++; if (idx > 4) idx = 0; } break; case eIR_LEFT: { static char idx = 0; p_app->settings.ch[p_app->cur_ch_num].cmd = idx; bant_send(p_app->settings.ch[p_app->cur_ch_num].cmd, p_app->settings.ch[p_app->cur_ch_num].freq_idx + 2); if (idx == 0x7F) idx = 0; else idx++; } break; default: break; } break; } break; default: break; } return result; /* always handle event */ } #else /* CONFIG_BCM_FACTORY_TEST */ int bscreen_status_event(void *v_app, void *v_screen, bscreen_event_t *p_event) { bapp_t *p_app = (bapp_t*)v_app; bscreen_t *p_screen = (bscreen_t*)v_screen; int result = 0; int i; unsigned int flags; static bool tune = false; static bool color_bars = false; static bool status = false; static int cnt = 0; static int reject_key_timeout = 10; switch (p_event->type) { case eS_EVENT_IDLE: { static int led_cnt = 0; static bool led_enabled = false; if (reject_key_timeout > 0) { reject_key_timeout--; if (reject_key_timeout == 0) { bapp_sync(p_app); bgfx_fill_rect(&p_app->surf,0,0,eWIDTH,eHEIGHT,eCOLOR_CLEAR); bapp_flush_screen(p_app); } } if (cnt++ == 10) { cnt = 0; if (color_bars) { cnt = 11; bapp_sync(p_app); bgfx_fill_rect(&p_app->surf,0,0,eWIDTH ,eHEIGHT,eCOLOR_BLACK); bgfx_fill_rect(&p_app->surf,40,40,eWIDTH - 80,eHEIGHT - 80,eCOLOR_WHITE); bgfx_fill_rect(&p_app->surf,80,80,(eWIDTH - 160)/3,eHEIGHT - 160,eCOLOR_LT_YELLOW); bgfx_fill_rect(&p_app->surf,80 + ((eWIDTH - 160)/3),80,(eWIDTH - 160)/3,eHEIGHT - 160,eCOLOR_NEON_GREEN); bgfx_fill_rect(&p_app->surf,80 + (((eWIDTH - 160) * 2)/3),80,(eWIDTH - 160)/3,eHEIGHT - 160,eCOLOR_LT_BLUE); bapp_flush_screen(p_app); } else if (!p_app->factory_test || status) { bapp_sync(p_app); bscreen_status_draw(v_app,v_screen); bapp_flush_screen(p_app); } } if ((led_cnt++ == 5) && p_app->factory_test) { flags = bos_enter_critical(); led_cnt = 0; /* flash the LED */ if (led_enabled) { WriteReg32(LED_DATA_REG, ReadReg32( LED_DATA_REG) | LED_GREEN_MASK); } else { WriteReg32(LED_DATA_REG, ReadReg32( LED_DATA_REG) & ~LED_GREEN_MASK); } bos_exit_critical(flags); led_enabled = (led_enabled) ? false : true; } } break; case eS_EVENT_SETUP_DONE: result = 0; BDBG_WRN(("eS_EVENT_SETUP_DONE...\n")); if (p_app->factory_test) { result = 1; p_app->cur_ch_num = 0; tune = true; } break; case eS_EVENT_SETUP: BDBG_WRN(("eS_EVENT_SETUP...\n")); if (p_app->factory_test) { p_app->audio_vol = 100; bapp_set_audio_volume(p_app, p_app->audio_vol); /* For factory test mode only */ flags = bos_enter_critical(); WriteReg32(LED_DATA_REG, ReadReg32( LED_DATA_REG) | LED_GREEN_MASK); bos_exit_critical(flags); } result = 1; flags = bos_enter_critical(); #if (BCHP_CHIP!=3543) WriteReg32(LED_DATA_REG, ReadReg32( LED_DATA_REG) & ~LED_RED_MASK); #else WriteReg32(BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1, ReadReg32( BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1) & ~BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1_irw_top_sw_led_cntrl_MASK); #endif bos_exit_critical(flags); bapp_av_mute(p_app, 0); break; case eS_EVENT_SELECTED: result = (p_screen->button_selection == p_event->id) ? 1 : 0; break; case eS_EVENT_CHECKED: result = (p_screen->button_checked == p_event->id) ? 1 : 0; break; case eS_EVENT_IR: { if (reject_key_timeout > 0) { BDBG_WRN(("############ STARTING UP THROW AWAY KEY (0x%08x) ############",p_event->id)); break; } if (p_event->id & 0x40000000) { BDBG_WRN(("############ THROW AWAY KEY UP (0x%08x) ############",p_event->id)); break; } WriteReg32(BCHP_HIFIDAC_CTRL0_TEST, ReadReg32(BCHP_HIFIDAC_CTRL0_TEST) & ~BCHP_HIFIDAC_CTRL0_TEST_TESTTONE_ENABLE_MASK); if (!p_app->factory_test) { bgfx_fill_rect(&p_app->surf,0,0,eWIDTH,eHEIGHT,eCOLOR_CLEAR); result = 1; bapp_goto_last_screen(v_app); /* for testing auto power off */ if (p_event->id == eIR_1) { p_app->settings.auto_power_off = 1; } return result; } color_bars = false; status = false; switch (p_event->id) { case eIR_1: p_app->cur_ch_num = 1; tune = true; break; case eIR_2: p_app->cur_ch_num = 0; tune = true; break; case eIR_3: p_app->cur_ch_num = 2; tune = true; break; case eIR_4: BDBG_WRN(("Test left audio channel...\n")); color_bars = true; cnt = 0; /* left, freq 1000, count 48, repeat 1 */ WriteReg32(BCHP_HIFIDAC_CTRL0_TEST, (BCHP_HIFIDAC_CTRL0_TEST_TESTTONE_ENABLE_MASK | BCHP_HIFIDAC_CTRL0_TEST_TESTTONE_SHARE_MASK | BCHP_HIFIDAC_CTRL0_TEST_TESTTONE_RIGHT_MASK | (47 << BCHP_HIFIDAC_CTRL0_TEST_TESTTONE_REPEAT_LEFT_SHIFT))); for (i = 0; i < s_1khz_samples_num; ++i) { WriteReg32(BCHP_HIFIDAC_CTRL0_TESTTONE_SAMPLE_i_ARRAY_BASE + (i * 4),s_1khz_samples[i]); } break; case eIR_6: BDBG_WRN(("Test right audio channel...\n")); color_bars = true; cnt = 0; /* Actual frequency: 10000, Repeat count: 24, Number of sine waves per repeat: 5 */ WriteReg32(BCHP_HIFIDAC_CTRL0_TEST, (BCHP_HIFIDAC_CTRL0_TEST_TESTTONE_ENABLE_MASK | BCHP_HIFIDAC_CTRL0_TEST_TESTTONE_SHARE_MASK | BCHP_HIFIDAC_CTRL0_TEST_TESTTONE_LEFT_MASK | (23 << BCHP_HIFIDAC_CTRL0_TEST_TESTTONE_REPEAT_LEFT_SHIFT))); /* Write every other sample */ for (i = 0; i < s_10khz_samples_num; ++i) { WriteReg32(BCHP_HIFIDAC_CTRL0_TESTTONE_SAMPLE_i_ARRAY_BASE + (i * 4),s_10khz_samples[i]); } break; case eIR_8: antenna_detect = bant_detect(); case eIR_7: BDBG_WRN(("Status...\n")); bapp_sync(p_app); bgfx_fill_rect(&p_app->surf,0,0,eWIDTH,eHEIGHT,eCOLOR_CLEAR); bapp_flush_screen(p_app); status = true; cnt = 0; break; case eIR_9: BDBG_WRN(("Reset user settings...\n")); /* setup flash */ bapp_reset_settings(p_app); /* update flash with new settings */ bapp_save_settings(p_app); BDBG_WRN(("Factory reset complete, powering off...\n")); bos_sleep(200); bapp_do_poweroff(p_app); result = 1; break; case eIR_UP: case eIR_CH_UP: if (p_app->cur_ch_num == 2) p_app->cur_ch_num = 0; else p_app->cur_ch_num++; tune = true; break; case eIR_CH_DOWN: case eIR_DOWN: if (p_app->cur_ch_num == 0) p_app->cur_ch_num = 2; else p_app->cur_ch_num--; tune = true; break; case eIR_0: case eIR_5: default: break; } break; } break; default: break; } if (tune) { BDBG_WRN(("Channel index = %d...\n",p_app->cur_ch_num)); bapp_sync(p_app); bgfx_fill_rect(&p_app->surf,0,0,eWIDTH,eHEIGHT,eCOLOR_CLEAR); bapp_flush_screen(p_app); bapp_tune(p_app); tune = false; } return result; /* always handle event */ } #endif /* CONFIG_BCM_FACTORY_TEST */