⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 md.c

📁 dvr
💻 C
📖 第 1 页 / 共 2 页
字号:
u8 g1p_md_get_max_difference(void)
{
	xdata u8 tmp;
	tmp = g1pMDreg_read(MD_DMAXH); // maximum difference for mean variant
	tmp = g1pMDreg_read(MD_DMAXL); // maximum difference for mean
	return tmp;
}




//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
void g1p_md_reg_set_area(BYTE ch)
{
	BYTE bk, pos;
	BYTE areas[2][4];
	BYTE reg_base;

#ifdef DEBUG_G1PMD_AREA
	printf("\n\rCH[%d]", (int)ch);
#endif
	// convert 2 block position information (x,y) into 16 x 32 font based position information
	for(bk=0;bk<2;bk++) // for two block
	{
#ifdef DEBUG_G1PMD_AREA
		printf("blk%d ", (int)bk);
#endif
		for(pos=0;pos<4;pos++)
		{
			areas[bk][pos] = mdgv_md_areas[ch][bk][pos];	// X position
#ifdef DEBUG_G1PMD_AREA
			printf("(%2d,", (int)areas[bk][pos]);
#endif
			pos++;
			areas[bk][pos] = g1p_conv_16x24_to_16x32(mdgv_md_areas[ch][bk][pos]);	// Y position
#ifdef DEBUG_G1PMD_AREA
			printf("%2d) ", (int)areas[bk][pos]);
#endif
		}
	}

	// set the changed position information into G1P MD part
	reg_base = ch*0x10;
	// write first MD block of G1P
	g1pMDreg_write(reg_base+0x00, areas[0][1]);	// Y1
	g1pMDreg_write(reg_base+0x01, areas[0][0]);	// X1
	g1pMDreg_write(reg_base+0x02, areas[0][3]);	// Y2
	g1pMDreg_write(reg_base+0x03, areas[0][2]);	// X2
	// write second MD block of G1P
	g1pMDreg_write(reg_base+0x04, areas[1][1]);	// Y3
	g1pMDreg_write(reg_base+0x05, areas[1][0]);	// X3
	g1pMDreg_write(reg_base+0x06, areas[1][3]);	// Y4
	g1pMDreg_write(reg_base+0x07, areas[1][2]);	// X4

}

///////////////////////////////////////////////////////////
// NTSC system (720x480)
// 16x24 font based: x(0~44) y(0~19)
// 16x32 font based: x(0~44) y(0~14)
//
// PAL system (720x576)
// 16x24 font based: x(0~44) y(0~23)
// 16x32 font based: x(0~44) y(0~17)
//
///////////////////////////////////////////////////////////
u8 g1p_conv_16x24_to_16x32(u8 y)
{
	u8 r,m;
	u8 pix_y;
	u8 bottom_line;
	
	bottom_line = gv_NTSC_PAL ? 17:14; 
	
	// the result pix_y will be close to 16 x 32 font based position
	r = y % 4;
	if(r==2) r = 1;
	else if(r==3) r = 2;
	else ;
	m = y / 4;
	pix_y = m * 3 + r;
	
	if(pix_y > bottom_line)
		pix_y = bottom_line;
	return (u8)pix_y;
}

///////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
void g1p_md_enable(BOOL enable)
{
	xdata BYTE i;
	xdata BYTE mn;	//	mean
	xdata BYTE mv;	//	mean variant

	mdgv_md_active_ch_stat = 0;
	for(i=0;i<4;i++)
	{
		mn = mv = 0;	//	default value
		if(enable)
		{	
			// if now enabling and the channel is enabled
			mn = (mdgvp_md_sensitivity_level_set[mdgv_md_sensitivity_levels[i]]&0xF0)>>4;
			mv =  mdgvp_md_sensitivity_level_set[mdgv_md_sensitivity_levels[i]]&0x0F;

			//	set activation status for each channel
			//	if both mn and mv are zero -> the channel is disabled
			if(mn+mv)
				mdgv_md_active_ch_stat |= (0x01)<<i;
		}
		//	write registers
		g1pMDreg_write(i*0x10+0x08, mn);
		g1pMDreg_write(i*0x10+0x09, mv);
	}
	mdgv_md_enabled = (mdgv_md_active_ch_stat==0)?0:1;
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
BOOL g1p_md_is_detected(u8 cmd)
{
	static xdata u8 is_FirstMdDetected[4] = {1,1,1,1};
	static xdata u16 s_blk_cnt[4] = {0,0,0,0};
	static xdata u8  s_diff[4] = {0,0,0,0};

	xdata u8 i;
	xdata BYTE detected_ch_num; // 0,1,2,3
	xdata WORD blk_cnt;
	xdata BYTE max_diff;
	
	if(cmd==MD_CLEAR_OLD_REG_V)
	{
		for(i=0;i<4;i++)
		{
			is_FirstMdDetected[i] = 1;
			s_blk_cnt[i] = 0;
			s_diff[i] = 0;
		}
	}	
	
	mdgv_channel_detected = 0;
	
	blk_cnt = g1p_md_get_block_count(&detected_ch_num);
	max_diff = g1p_md_get_max_difference();

	if(is_FirstMdDetected[detected_ch_num])
	{
		is_FirstMdDetected[detected_ch_num] = 0; // At the first case, we just save the current MD reg values
#ifdef DEBUG_MD_DETECT
		printf("\n\rG1PMD= blk[%04x] diff[%02x] ch[%02x]", blk_cnt, (u16)max_diff, (u16)detected_ch_num);
#endif			
	}
	else	// check the difference from the previous values
	{
		if((s_blk_cnt[detected_ch_num]!= blk_cnt)||(s_diff[detected_ch_num]!= max_diff))
		{
			mdgv_channel_detected = 0x01 << detected_ch_num;
#ifdef DEBUG_MD_DETECT
			printf("\n\rG1PMD: blk[%04x] diff[%02x] ch[%02x]", blk_cnt, (u16)max_diff, (u16)detected_ch_num);
#endif			
		}
	}
	// update current blk_cnt number
	s_blk_cnt[detected_ch_num] = blk_cnt;
	s_diff[detected_ch_num] = max_diff;
	
	return (mdgv_channel_detected==0)?0:1;

}

//==============================================================================
// Access G1P MD register
//==============================================================================
void g1pMDreg_write(u8 addr, u8 value)
{
	MD_ADDRESS_REGISTER = addr;
	MD_DATA_REGISTER = value;
}
u8 g1pMDreg_read(u8 addr)
{
	u8 value;
	
	MD_ADDRESS_REGISTER = addr;
	value = MD_DATA_REGISTER;
	return value;
}

#endif // G1PMD



#ifdef TW2804
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
void tw2804_md_reg_set_area(BYTE ch)
{
	BYTE i,j,x,y;
#ifdef VY_MD_DEBUG_AREA
	WORD temp[2][4];
#endif
	BYTE areas[2][4];
	BYTE mask[3];

	//	convert coordination
	for(i=0;i<2;i++)
	{
		for(j=0;j<4;j++)
		{
			#ifdef VY_MD_DEBUG_AREA
			temp[i][j] = (mdgv_md_areas[ch][i][j]+((j&0x02)?1:0))*((j&0x01)?24:16)+((j&0x02)?-1:0);
			#endif
			areas[i][j] = ((mdgv_md_areas[ch][i][j]+((j&0x02)?1:0))*((j&0x01)?24:16)+((j&0x02)?-1:0))/((j&0x01)?(gv_NTSC_PAL?48:40):60);
		}
	}

#ifdef VY_MD_DEBUG_AREA
	for(i=0;i<2;i++)
	{
		printf("\r\nch %d [%2u,%2u-%2u,%2u] -> [%3u,%3u-%3u,%3u] [%X,%X-%X,%X]",
			(WORD)ch,(WORD)mdgv_md_areas[ch][i][0], (WORD)mdgv_md_areas[ch][i][1], (WORD)mdgv_md_areas[ch][i][2], (WORD)mdgv_md_areas[ch][i][3],
			temp[i][0], temp[i][1], temp[i][2], temp[i][3], (WORD)areas[i][0], (WORD)areas[i][1], (WORD)areas[i][2], (WORD)areas[i][3]); 
	}
	printf("\r\n 0 1 2 3 4 5 6 7 8 9 A B");
#endif

	for(i=0;i<6;i++)
	{	//	process 2 rows at a time covers all 12 lines
		//	default = masking all blocks
		mask[0] = mask[1] = mask[2] = 0xFF;
		for(j=0;j<2;j++)
		{	//	process 2 rows at a time
			//	calculate row index
			y = i*2 + j;
			for(x=0;x<12;x++)
			{	//	sweep a row
				if( (areas[0][0]<=x && x<=areas[0][2] && areas[0][1]<=y && y<=areas[0][3]) ||
					(areas[1][0]<=x && x<=areas[1][2] && areas[1][1]<=y && y<=areas[1][3]))
				{	//	when a block should be enabled,
					if(x<8)
					{
						mask[j] &= ~(0x01<<x);
					}
					else
					{
						mask[2] &= ~((j?0x10:0x01)<<(x-8));
					}
				}
			}
		}
#ifdef VY_MD_DEBUG_AREA
		printf("\r\n %c %c %c %c %c %c %c %c %c %c %c %c",
				(mask[0]&0x01)?'1':'0',	// 0
				(mask[0]&0x02)?'1':'0',	// 1
				(mask[0]&0x04)?'1':'0',	// 2
				(mask[0]&0x08)?'1':'0',	// 3
				(mask[0]&0x10)?'1':'0',	// 4
				(mask[0]&0x20)?'1':'0',	// 5
				(mask[0]&0x40)?'1':'0',	// 6
				(mask[0]&0x80)?'1':'0',	// 7
				(mask[2]&0x01)?'1':'0',	// 8
				(mask[2]&0x02)?'1':'0',	// 9
				(mask[2]&0x04)?'1':'0',	// 10
				(mask[2]&0x08)?'1':'0');// 11
		printf("\r\n %c %c %c %c %c %c %c %c %c %c %c %c",
				(mask[1]&0x01)?'1':'0',	// 0
				(mask[1]&0x02)?'1':'0',	// 1
				(mask[1]&0x04)?'1':'0',	// 2
				(mask[1]&0x08)?'1':'0',	// 3
				(mask[1]&0x10)?'1':'0',	// 4
				(mask[1]&0x20)?'1':'0',	// 5
				(mask[1]&0x40)?'1':'0',	// 6
				(mask[1]&0x80)?'1':'0',	// 7
				(mask[2]&0x10)?'1':'0',	// 8
				(mask[2]&0x20)?'1':'0',	// 9
				(mask[2]&0x40)?'1':'0',	// 10
				(mask[2]&0x80)?'1':'0');// 11
#endif
		tw2804_write(MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch+MD_2804_MDMASK1+i*3, mask[0]);
		tw2804_write(MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch+MD_2804_MDMASK1+i*3+1, mask[2]);
		tw2804_write(MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch+MD_2804_MDMASK1+i*3+2,	mask[1]);
	}
}

///////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
void tw2804_md_enable(BOOL enable)
{
	xdata BYTE ch;
	xdata BYTE int_mask;

	//	clear interrupt if raised
	tw2804_write(MD_2804_REG_IRQCLR,0x0F); // clear only MD interrupt
	mdgv_md_active_ch_stat = 0;
	if(enable)
	{
		for(ch=0;ch<4;ch++)
		{
#ifdef VY_MD_DEBUG_REG_RW
			printf("\r\n[ch %u]",(WORD)ch);
#endif
			tw2804_write((BYTE)(MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch), (BYTE)mdgvp_md_sensitivity_level_set[mdgv_md_sensitivity_levels[ch]]);

#ifdef VY_MD_DEBUG_REG_RW
			printf("\r\n  Sensitivity at 0x%02X, 0x%02X - 0x%02X", 
			(WORD)MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch, (WORD)mdgvp_md_sensitivity_level_set[mdgv_md_sensitivity_levels[ch]], (WORD)tw2804_read(MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch)	);
#endif

			tw2804_write((BYTE)(MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch+MD_2804_MPERIOD), (BYTE)MD_MPERIOD);

#ifdef VY_MD_DEBUG_REG_RW
			printf("\r\n  Period at      0x%02X, 0x%02X - 0x%02X", 
			(WORD)MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch+MD_2804_MPERIOD, (WORD)MD_MPERIOD, (WORD)tw2804_read(MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch+MD_2804_MPERIOD));
#endif
			if(mdgv_md_sensitivity_levels[ch])
				mdgv_md_active_ch_stat |= (0x01)<<ch;
		}
	}
	tw2804_write(MD_2804_REG_IRQCLR,0x0F); // clear only MD interrupt
	int_mask = tw2804_read(MD_2804_REG_IRQENA);
	tw2804_write(MD_2804_REG_IRQENA, (mdgv_md_active_ch_stat&0x0F)|(int_mask&0xF0));
	mdgvp_channel_enable_mask = mdgv_md_active_ch_stat;

#ifdef VY_MD_DEBUG_REG_RW
	printf("\r\n[ENABLE - 0x%02X] 0x%02X - 0x%02X", 
	(WORD)tw2804_read(MD_2804_REG_IRQCLR), (WORD)mdgv_md_active_ch_stat, (WORD)tw2804_read(MD_2804_REG_IRQENA));
#endif

#ifdef DEBUG_MD
	{		
		u8 tmp = tw2804_read(MD_2804_REG_IRQENA);
		printf("\n\rMD: IRQENA = %c %c %c %c", (tmp&0x01)?'O':'x', (tmp&0x02)?'O':'x', (tmp&0x04)?'O':'x', (tmp&0x08)?'O':'x');
	}
#endif
	mdgv_md_enabled = enable;	// Steve add

}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
BOOL tw2804_md_is_detected(void)
{
	xdata BYTE temp;
	xdata BYTE int_mask;
#ifdef VY_MD_DEBUG_INT
	static xdata BYTE counter=0;
#endif
	mdgv_channel_detected = 0;
	if(INT_2804 == HIGH)
	{
        #ifdef USE_4954_GP
		temp = cs4954_read(0x0A);
        #endif
		mdgv_channel_detected = mdgv_md_active_ch_stat&(temp>>4);
		// clear interrupt
		tw2804_write(MD_2804_REG_IRQCLR,mdgv_channel_detected&0x0F);
		if(mdgv_channel_detected)
		{
			mdgvp_channel_enable_mask &= ~mdgv_channel_detected;
			// disable detected channel - enabled when recording completed
			int_mask = tw2804_read(MD_2804_REG_IRQENA);
			tw2804_write(MD_2804_REG_IRQENA, (mdgvp_channel_enable_mask&0x0F)|(int_mask&0xF0));

#ifdef VY_MD_DEBUG_INT
			printf("\r\nINT[0x%02X] 4954[0x%02X] channel[0x%02X] [[0x%02X]]", 
			(WORD)counter++, (WORD)temp, (WORD)mdgv_channel_detected, (WORD)tw2804_read(MD_2804_REG_IRQENA) );
#endif

#ifdef DEBUG_MD
			{		
				u8 tmp = tw2804_read(MD_2804_REG_IRQENA);
				printf("\n\rMD: IRQENAi= %c %c %c %c", 
					(tmp&0x01)?'O':'x',
					(tmp&0x02)?'O':'x',
					(tmp&0x04)?'O':'x',
					(tmp&0x08)?'O':'x'
					);
			}
#endif
			return TRUE;
		}
	}
	return FALSE;
}
#endif // TW2804


#endif	//end of VY_MD

⌨️ 快捷键说明

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