microvfd.c

来自「ESS3890+SL原代码(1*16内存)」· C语言 代码 · 共 1,859 行 · 第 1/3 页

C
1,859
字号
/* Copyright 1997, ESS Technology, Inc.					*//* SCCSID @(#)microvfd.c	4.11.1.2 04/12/05 *//* * $Log$ */#include "vcxi.h"#include "const.h"#include "timedef.h"#include "util.h"#include "micro.h"#include "panel.h"#include "ir.h"#include "vfdshare.h"#include "keydef.h"#include "play.h"#ifdef SCR_SAVER#include "scrsaver.h"#endif/************************************************************************ * Shadows are for VFD icons.						* * 									* * Size is determined by the number of grids (G) and segments (P).	* * Our internal representation may be different from actual hardware	* * especially when we have more than 16 segments (P). In any case,	* * the number of "shadows" is the same as number of elements in		* * VFD_refresh_table.							* ************************************************************************/#ifdef HOST_SLAVE#define SHADOW_LENGTH           1#else#define SHADOW_LENGTH           T_VFD_refresh_tbl_SZ#endif/*  * Macro to define number of usec (Don't be fractional! Don't be more * than half second!) */#define	RETURN_BEFORE_SCHEDULED_TIME	if (!VFD_is_scheduled_time()) return;#define	SCH_DELAY_BETWEEN_DATA	VFD_schedule_state_change(DELAY_BETWEEN_DATA)#define	SCH_DELAY_AFTER_DATA	VFD_schedule_state_change(DELAY_AFTER_DATA)/************************************************************************ * Macros specific to different VFD drivers.				* ************************************************************************/#if (D16311 || D16312)#define KEY_LENGTH              3#define VFD_DUTY_CYCLE          0x8c#define VFD_ADDRESS_INC         0x40#define VFD_ADDRESS_FIX         0x44#define VFD_ADDRESS_MASK        0xc0#define VFD_READ_KEY            0x42#define VFD_READ_SW             0x43#endif /* D16311 || D16312 */#ifdef DSTC6311#define KEY_LENGTH              6#define VFD_DUTY_CYCLE          0x8c#define VFD_ADDRESS_INC         0x40#define VFD_ADDRESS_FIX         0x44#define VFD_ADDRESS_MASK        0xc0#define VFD_READ_KEY            0x42#define VFD_READ_SW             0x43#endif /* DSTC6311 */#ifdef MN12510/* By Liang Weihua */#define KEY_LENGTH              6#define VFD_ADDRESS_MASK        0x40#define VFD_READ_KEY            0x80#if 0  /* philips (Andy may need)*/#define KEY_LENGTH              8#define VFD_ADDRESS_MASK        0x40#define VFD_READ_KEY            0x80#endif#endif /* MN12510 */#ifdef BU2872#define KEY_LENGTH              3#define VFD_ADDRESS_MASK        0x80#define VFD_READ_KEY            0xa0#endif /* BU2872 */#ifdef HT1621#define KEY_LENGTH              3#define CLR_LCD_CS             CLEAR_VFD_STROBE /* CLEAR_AUX6 */#define SET_LCD_CS             SET_VFD_STROBE /* SET_AUX6 */#define CLR_LCD_WR             CLEAR_VFD_CLK /* CLEAR_AUX7 */#define SET_LCD_WR             SET_VFD_CLK /* SET_AUX7 */#define CLR_LCD_DATA           CLEAR_VFD_DATA /* CLEAR_AUX5 */#define SET_LCD_DATA           SET_VFD_DATA /* SET_AUX5 */#define LCD_SYS_EN		0x01	/*turn on system oscillator*/#define LCD_LCD_ON		0x03	/*trun on LCD bias generator*/#define LCD_RC_256		0x18	/*on-chip RC oscillator*/#define LCD_IRQ_DIS		0x80	/*disable IRQ output*/#define LCD_BIAS        	0x29	/*4COM & LCD 1/3 bias option */#define LCD_TIMER_DIS           0x008	/*disable time base output*/#define LCD_WDT_DIS		0x00a	/*disable WDT time_out flag output*/#define LCD_TONE_OFF	        0x010	/*turn off tone output*/#define LCD_TONE_ON	        0x012	/*turn on tone output*/#define LCD_NORMAL		0x1c6	/*normal mode*/#define LCD_COMMAND		0x04		/*write command id to 1621*/#define LCD_WRITE		0x05		/*write date/addr id to 1621*/#endif HT1621/************************************************************************ * Macros relate to remote control ASSIGN_SYSCODE moved to ir.c ************************************************************************/#define CLEAR_REMOTE            (codeIR &= ~0x100)#ifdef IR_PHILIPS/* Philips IR only has 6 bits */#define REMOTE_KEY              (char)(codeIR & 0x3f)#endif /* IR_PHILIPS */#if (IR_NEC || IR_SANYO)/* NEC/SANYO IR have 8 bits */#define REMOTE_KEY              (char)(codeIR & 0xff)#endif /* IR_NEC || IR_SANYO */#ifdef PLUS5_KEY      int sign_plus5 = 0;#endif PLUS5_KEY/************************************************************************ * Global functions.							* ************************************************************************/void	initMicroObject(void);int	get_keycode(int mode);void	microEngine(void);void	VFD_clear_lite_anode(unsigned short, int);#ifndef  HOST_SLAVE /************************************************************************ * Private functions.							* ************************************************************************/PRIVATE	void	flashCalendar(void);PRIVATE	int	micro_convert_irkey(int);PRIVATE	void	VFD_clearSegment(int, unsigned short *);PRIVATE	void	VFD_flashCalendar(void);PRIVATE	void	VFD_objectReadByte(void);PRIVATE	void	VFD_objectSendByte(int);PRIVATE	void	VFD_parseKey(void);PRIVATE	void	VFD_searchKey(void);PRIVATE	void	VFD_set_char(unsigned short *, unsigned int);PRIVATE	void	VFD_strobeSendByte(int, int);PRIVATE void	VFD_schedule_state_change(unsigned int);PRIVATE int	VFD_is_scheduled_time(void);PRIVATE	void	VFD_state_init(void);PRIVATE	void	VFD_state_scan_key_0(void);PRIVATE	void	VFD_state_scan_key_1(void);PRIVATE	void	VFD_state_scan_key_2(void);PRIVATE	void	VFD_state_scan_key_3(void);PRIVATE	void	VFD_state_scan_key_4(void);PRIVATE	void	VFD_state_scan_key_5(void);PRIVATE	void	VFD_state_refresh_0(void);PRIVATE	void	VFD_state_refresh_1(void);PRIVATE	void	VFD_state_refresh_2(void);PRIVATE	void	VFD_state_refresh_3(void);PRIVATE	void	VFD_state_refresh_4(void);PRIVATE	void	VFD_state_refresh_5(void);#ifdef HT1621PRIVATE void    LCD_objectSendcommand(int command);PRIVATE void    LCD_objectSenddata(int address,int data);PRIVATE void	VFD_schedule_state_change(unsigned int);PRIVATE int	VFD_is_scheduled_time(void);/*void Fill_Seg(int seg);*/void lcd_delay();#endif HT1621/************************************************************************ * Local variables							* ************************************************************************/PRIVATE struct {    unsigned int     FlashTime;} ObjectTime;/* * There is a stack to keep track which "G/P" byte needs to be updated. * G/P combinations are defined as ANODE_G1L, ANODE_G1H etc in vfdshare.h. */PRIVATE	int		VFDptr;PRIVATE	char		VFD_refresh_stack[SHADOW_LENGTH]; #define POPVFD          VFD_refresh_stack[--VFDptr]/* * ShadowRam keeps track of the value that needs to be set for the * corresponding G/P combination. */PRIVATE	unsigned char	ShadowRam[SHADOW_LENGTH];PRIVATE	int		RefreshCounter;PRIVATE	char		DataLength;/* * Keep track of scheduled delay. */PRIVATE		 int	VFD_scheduled_timer2;PRIVATE unsigned int	VFD_scheduled_realtime;PRIVATE	PFV		VFD_next_state = VFD_state_init;#endif /* HOST_SLAVE *//************************************************************************ * Global variables							* ************************************************************************/int EnableFlashing=0;int FlashingCalendar=0;int key0 = NO_KEY;#define put_keycode(key) (key0 = key) int last_voice_clock;#ifdef HOST_SLAVEextern Slave_Message_Dispatch();#define CUSTOM#else#define CUSTOM	static#endifCUSTOM struct {    char    KeyBuffer[KEY_LENGTH];    char    FireKey;    unsigned short    Digit10Key;#ifdef PLUS5_KEY    int    Digit5Key;#endif} ObjectKey;/* * Schedule an event in the future. Some VFD controller can't take command * too fast, so we need to give it some breathing room. This routine will * not sit there and hog CPU time! * * Input: *	delay:	In timer ticks (CPUCLK equals to 10us) assuming it is powered *		up. */#ifndef HOST_SLAVEPRIVATE void VFD_schedule_state_change(delay)unsigned int delay;{    if (IS_POWER_DOWN) delay /= IDLEFACTOR;    VFD_scheduled_timer2 = 	UTIL_set_timer2_end(delay, &VFD_scheduled_realtime);}/* * Wait for a scheduled time to arrive. * * Return: 1: time is up. *	   0: not yet. */PRIVATE int VFD_is_scheduled_time(){    return(UTIL_reached_timer2_end(VFD_scheduled_timer2,				   VFD_scheduled_realtime));}#endif /*HOST_SLAVE*/int microKeyPending(){    if ((REMOTE_VALID) || (key0 != NO_KEY)) return (1);    return (0);}void initMicroObject(void){#ifndef HOST_SLAVE	    int i;        ObjectTime.FlashTime = glbTimer + HALF_SECOND;    VFD_STROBE_INACTIVE;    SET_VFD_CLK;    SET_VFD_DATA;    VFD_blank_all();#endif	}int get_keycode(int mode){    int return_key;    return_key = key0;    if(!mode)key0 = NO_KEY;    return return_key;}int Time0;/*===========================================================================*/PRIVATE void VFD_parseKey(void){    int ignore_key, key;    if (ObjectKey.FireKey != NO_KEY) {	if ((glbTimer - Time0) < 30) return;		Time0 = glbTimer;#ifdef SCR_SAVER        if (scr_saver_state == SAVER_SHOW || scr_saver_state == SAVER_WAIT) {            key_in = 1;            process_scr_saver();        }#endif #ifdef PLUS5_KEY        if (ObjectKey.FireKey == _KEY_PLUS_5) {            sign_plus5 = 1;            ObjectKey.Digit5Key += 5;            ObjectKey.Digit5Key = preprocess_digit_key(ObjectKey.Digit5Key,							&ignore_key,1);            ObjectKey.FireKey = NO_KEY;#ifdef JD5PLUS5             ltsign=1;            pre_timer=glbTimer+180;#endif        } else#endif PLUS5_KEY        if (ObjectKey.FireKey == 10) {#ifdef PLUS5_KEY            sign_plus5 = 0;#endif PLUS5_KEY            ObjectKey.Digit10Key += 10;            ObjectKey.Digit10Key = preprocess_digit_key(ObjectKey.Digit10Key, 							&ignore_key,1);        } else if (ObjectKey.FireKey <= 10) {#ifdef PLUS5_KEY          if(sign_plus5 == 1) {            ObjectKey.Digit5Key += ObjectKey.FireKey;            ObjectKey.Digit5Key = preprocess_digit_key(ObjectKey.Digit5Key,							&ignore_key,0);#ifdef JD5PLUS5   if(ltsign==1)   ltsign = 0;#endif            if (!ignore_key)                put_keycode(ObjectKey.Digit5Key);            ObjectKey.Digit5Key = 0;            ObjectKey.Digit10Key = 0;            sign_plus5 = 0;          } else#endif PLUS5_KEY          {            ObjectKey.Digit10Key += ObjectKey.FireKey;            ObjectKey.Digit10Key = preprocess_digit_key(ObjectKey.Digit10Key, 							&ignore_key,0);            if (!ignore_key)                put_keycode(ObjectKey.Digit10Key);            ObjectKey.Digit10Key = 0;         }        } else {	    key = ObjectKey.FireKey | 0xff00;            put_keycode(key);    /* function key     */            preprocess_function_key(key);#ifdef IR_PHILIPS            key = NO_KEY;				/* starts at 0xffxx.*/#endif /* IR_PHILIPS */            ObjectKey.Digit10Key = 0;#ifdef PLUS5_KEY            sign_plus5 = 0;            ObjectKey.Digit5Key = 0;#endif        }	/* according to Weihua, we should always clear the "Firekey" to 	 * prevent duplicate key entries.	 */	ObjectKey.FireKey = NO_KEY;     }}#ifndef HOST_SLAVE/* * Complement the calendar icon associated with FlashingCalendar. */PRIVATE void flashCalendar(){#if MAX_CALENDAR /* Calendar exists */    unsigned short anode;	/* Data read from T_VFD_calendar_tbl	*/    /*     * calendar_tbl is in xxxxyzzzzzzzz format where z is 1 hot while     * xxxxy give the "ShadowRam" index.     */    anode = T_VFD_calendar_tbl[FlashingCalendar];    VFD_clear_lite_anode(anode, 2);#endif /* Calendar exists */}#endif /*HOST_SLAVE*//* * This routine takes a G/P position and lite/clear the corresponding anode. * This routine will also carry out the old VFD_push function to save * another function call. * * Inputs: *	anode:	G/P position of the icon *	lite:	0 - clear *		1 - lite *		2 - complement */void VFD_clear_lite_anode(anode, lite)unsigned short anode;int lite;{    unsigned int index, tmp;    int i;#ifndef HOST_SLAVE    index = anode >> 8;#ifdef HT1621#if defined(LCD_2DANCE)||defined(LCD_6DANCE)      index = index;#else    if(index == 0x0f)          index = 16;    else if(index == 0x1d)          index = 17;    else          index = index/2;#endif#endif HT1621    tmp = anode;    if (lite == 2)      ShadowRam[index] ^= tmp;    else {	ShadowRam[index] &= ~tmp;	if (lite) ShadowRam[index] |= tmp;    }    /* Search in reverse order because of locality */    for (i = VFDptr; i > 0; )       if (VFD_refresh_stack[--i] == index) 	return;    VFD_refresh_stack[VFDptr++] = index;#endif /*HOST_SLAVE */}/* * If there is a wheel in VFD, this routine spins it. * * Input: *	set:	VFD_WHEEL_CLEAR_FAN	clear all fans *		VFD_WHEEL_SET_FAN	set all fans *		VFD_WHEEL_SPIN		spin *//*#define INVERT_LITED_WHEEL*/void VFD_spin_wheel(set)int set;{    static int wheelpos = -1;    unsigned short * ptr;    int items;    int i;        if (T_VFD_wheel_SZ == 0) return;    ptr   = T_VFD_wheel;    items = T_VFD_wheel_SZ / sizeof(unsigned short);    if (set == VFD_WHEEL_SPIN) {	wheelpos++;	if (wheelpos >= items) wheelpos = 0;	for (i = 0; i < items; i++) #ifdef INVERT_LITED_WHEEL	  VFD_clear_lite_anode(T_VFD_wheel[i], i == wheelpos);#else	  VFD_clear_lite_anode(T_VFD_wheel[i], i != wheelpos);#endif    } else if (set == VFD_WHEEL_SET_FAN) {	wheelpos = -1;	for (i = 0; i < items; i++) 	  VFD_clear_lite_anode(T_VFD_wheel[i], 1);    } else if (set == VFD_WHEEL_CLEAR_FAN) {	wheelpos = -1;	for (i = 0; i < items; i++) 	  VFD_clear_lite_anode(T_VFD_wheel[i], 0);    }}/* * Set a 7-segment character (really 8 segments) to a given character. * * Inputs: *	seg:	G/P positions for the given character *	target:	Target character (not in ASCII but in segments) */PRIVATE void VFD_set_char(seg, target)unsigned short * seg;unsigned int target;{    int i;    for (i = 0; i < T_VFD_char_segment_size[0]; i++) {	/*	 * By convention, T_VFDICON_tbl[1] is ICON_empty. Don't	 * update ICON_empty, it is just wasting time!	 */	if (seg[i] != T_VFDICON_tbl[1])	  VFD_clear_lite_anode(seg[i], target & 1);	target >>= 1;    }}/* * Output 2 7-segment digits. *  * Inputs: *	pos:		VFD_TRACK, VFD_MINUTE, VFD_SECOND, VFD_MIN100,  *			VFD_TITLE * 	data:		BCD data to write in case of Minute and Second *                  >>> Hex in case of Track number (TRACK_LOW/TRACK_HIGH) * 	maskFlag:	1 - Show blank when the high digit is 0 *			0 - Show '0'   when the high digit is 0 */void VFD_segment(pos, data, maskFlag)int pos;unsigned int data;int maskFlag;{    unsigned short * digit_tbl = T_VFD_digit_tbl;    VFD_CHAR_SEGMENTS * ptr;    ptr = &(((VFD_CHAR_SEGMENTS *) T_VFD_char_segments)[pos]);    /*      * Assume everything is limited to 2 digits (may not be true for      * DVD's minute field.     */    data &= 0xff;    if ((pos == VFD_TRACK) || (pos == VFD_CHAPTER)) {	/* hex2bcd table only valid up to 99 */	while (data > 99) data -= 100; 	data = hex2bcd[data]; /* track/chapter nums are in hex */    }    if (pos == VFD_MIN100 ) {	/* position VFD_MIN100 only has one digit. */	VFD_set_char(ptr->seg, digit_tbl[data]);    } else {	/* update the lower digit. */	VFD_set_char((ptr+1)->seg, digit_tbl[data & 0xf]); /* Data is BCD*/    	data >>= 4;	/* If we don't want to mask off 0, or the digit is not 0, then	   output the digit. */	VFD_set_char(ptr->seg, (!maskFlag || data) ? digit_tbl[data] : CHAR_);    }}/* * Lite those calendar icons associated with track_list. Only * track_list items between [start_index, track_list_max) are included. * * If start_index > track_list_max, then we'll clean all calendar numbers. */void VFD_calendar(int start_index){#ifndef HOST_SLAVE#if MAX_CALENDAR /* Calendar exists */    unsigned short i, lite, index;    unsigned short anode;            EnableFlashing = 0;        /*     * calendar_tbl is in xxxxyzzzzzzzz format where z is 1 hot while     * xxxxy give the "ShadowRam" index.     */    /* Clear up all the calendar icons */    for (i = 0; i <=  MAX_CALENDAR; i++) {	anode = T_VFD_calendar_tbl[i];	VFD_clear_lite_anode(anode, 0);    }        /* Lite up ones that we are interested in */    for (i = start_index; i < track_list_max; i++) {	lite = track_list[i];	if (lite <= MAX_CALENDAR) {	    anode = T_VFD_calendar_tbl[lite];	    VFD_clear_lite_anode(anode, 1);	}    }#endif /* Calendar exists */#endif /*HOST_SLAVE*/}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?