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

📄 external_timer.c

📁 移植到WLIT项目的redboot源代码
💻 C
字号:
//=============================================================================////      external_timer.c - Cyclone Diagnostics////=============================================================================//####COPYRIGHTBEGIN####//                                                                          // -------------------------------------------                              // The contents of this file are subject to the Red Hat eCos Public License // Version 1.1 (the "License"); you may not use this file except in         // compliance with the License.  You may obtain a copy of the License at    // http://www.redhat.com/                                                   //                                                                          // Software distributed under the License is distributed on an "AS IS"      // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the // License for the specific language governing rights and limitations under // the License.                                                             //                                                                          // The Original Code is eCos - Embedded Configurable Operating System,      // released September 30, 1998.                                             //                                                                          // The Initial Developer of the Original Code is Red Hat.                   // Portions created by Red Hat are                                          // Copyright (C) 2001 Red Hat, Inc.                             // All Rights Reserved.                                                     // -------------------------------------------                              //                                                                          //####COPYRIGHTEND####//=============================================================================//#####DESCRIPTIONBEGIN####//// Author(s):   Scott Coulter, Jeff Frazier, Eric Breeden// Contributors:// Date:        2001-01-25// Purpose:     // Description: ////####DESCRIPTIONEND####////===========================================================================*/#include "iq80310.h"extern int enable_external_interrupt (int int_id);extern int disable_external_interrupt (int int_id);extern int isr_connect(int int_num, void (*handler)(int), int arg);extern int isr_disconnect(int int_num);/* 01/05/01 jwf *//* extern void _restart_tmr(); */volatile int timer_ticks;/* interrupt handler for the PAL-based external timer */void ext_timer_handler (int arg){	/* increment tick counter */	timer_ticks++;	/* to clear the timer interrupt, clear the timer interrupt	   enable, then re-set the int. enable bit *//* 01/05/01 jwf *//*	_restart_tmr(); */	EXT_TIMER_INT_DISAB();	EXT_TIMER_INT_ENAB();	return;}/* timer count must be written 8 bits at a time */void write_timer_count (UINT32 count){	UINT8 cnt_word;	/* first ensure that there are only 22 bits of count data */	count &= 0x003fffff;	/* grab least significant 8 bits of timer value */	cnt_word = (UINT8)(count & 0xff);	*TIMER_LA0_REG_ADDR = cnt_word;	/* grab next 8 bits of timer value */	count = (count >> 8);	cnt_word = (UINT8)(count & 0xff);	*TIMER_LA1_REG_ADDR = cnt_word;	/* grab last 6 bits of timer value */	count = (count >> 8);	cnt_word = (UINT8)(count & 0x3f);	*TIMER_LA2_REG_ADDR = cnt_word;	return;}/* timer must be read 6 bits at a time */UINT32 read_timer_count (void){	UINT8 timer_cnt0, timer_cnt1, timer_cnt2, timer_cnt3;	UINT8 timer_byte0, timer_byte1, timer_byte2;	UINT32 count;	/* first read latches the count */	timer_cnt0 = (*TIMER_LA0_REG_ADDR & TIMER_COUNT_MASK);	timer_cnt1 = (*TIMER_LA1_REG_ADDR & TIMER_COUNT_MASK);	timer_cnt2 = (*TIMER_LA2_REG_ADDR & TIMER_COUNT_MASK);	timer_cnt3 = (*TIMER_LA3_REG_ADDR & 0xf);	/* only 4 bits in most sig. */	/* now build up the count value */	timer_byte0 = (((timer_cnt0 & 0x20) >> 1) | (timer_cnt0 & 0x1f));	timer_byte1 = (((timer_cnt1 & 0x20) >> 1) | (timer_cnt1 & 0x1f));	timer_byte2 = (((timer_cnt2 & 0x20) >> 1) | (timer_cnt2 & 0x1f));	count = ((timer_cnt3 << 18) | (timer_byte2 << 12) | (timer_byte1 << 6) |			  timer_byte0);	return (count);}/* 12/18/00 jwf *//* This test reads the timer la0-la3 registers on the fly while an up count is in progress. */void counter_test (void){	unsigned char TmrLa0Write=0xff; /* ff max, b0-b7, b0-b7 contain timer load data */		unsigned char TmrLa1Write=0xff; /* ff max, b8-b15, b0-b7 contain timer load data  */	unsigned char TmrLa2Write=0x3f; /* 3f max, b16-b21, b0-b5 contain timer load data  */	unsigned char TmrLa3Write=0x00; /* x - don't care */		unsigned long int TmrLa0Read=0;		unsigned long int TmrLa1Read=0;	unsigned long int TmrLa2Read=0;	unsigned long int TmrLa3Read=0;	unsigned long int temp3=0;	unsigned long int temp4=0;	unsigned long int CntInit=0;	unsigned long int CurrentCount;	unsigned long int LastCount;	unsigned long int LastLastCount;		char Error = FALSE;	/* This flag indicates a test pass(FALSE) or fail(TRUE) condition */	unsigned long int sample;	unsigned long int index;	const int MAX_N_PASSES = 10;										/* N times the counter shall wrap around */	const unsigned long int MAX_N_SAMPLES = 65536;						/* N samples to cover the full range of count, 0x3fffff/0x40 = 0xffff <--> 65535d, use 65536 to guarantee a counter wrap around occurs */	unsigned long int MAX_N_SIZE = MAX_N_PASSES * MAX_N_SAMPLES * 4;	/* allocate 4 bytes per sample for a 0x0 - 0x3fffff count range to hold contents of registers LA0-LA3 */	unsigned char *data;	// Arbitrarily pick a spot in memory.	// RedBoot won't ever use more than 1MB.	data = (unsigned char *) MEMBASE_DRAM + (1*1024*1024);	/* sample storage area */	if( data != NULL )	{		printf( "Allocated %d bytes\n", MAX_N_SIZE );			/* load control data to disable timer enable b0=0 and timer disable interrupt b1=0, write to timer enable port */		EXT_TIMER_INT_DISAB();		EXT_TIMER_CNT_DISAB();			/* write timer la0 port count data */		*TIMER_LA0_REG_ADDR = TmrLa0Write;			/* write timer la1 port count data */		*TIMER_LA1_REG_ADDR = TmrLa1Write;			/*  write timer la2 port count data */		*TIMER_LA2_REG_ADDR = TmrLa2Write;			/*  write timer la3 port count data */		*TIMER_LA3_REG_ADDR = TmrLa3Write;		CntInit = TmrLa0Write + (TmrLa1Write << 8 ) + (TmrLa2Write << 16 );		printf("Timer load data = 0x%x\n", CntInit );		printf("Reading Timer registers LA0-LA3 on the fly...\n");			/* load control data to enable timer counter and write control data to start the counter */		EXT_TIMER_CNT_ENAB();			/* sample the timer counter on the fly and store LA0-3 register contents in an array */		for ( sample=0, index=0 ; sample < ( MAX_N_PASSES * MAX_N_SAMPLES ) ; sample++, index += 4)		{				/* read LSB register first to latch 22 bits data into four la registers */			data[index]   = *TIMER_LA0_REG_ADDR;	/* bits 0 1 2 3 4 6 contain count data b0-b5 */					data[index+1] = *TIMER_LA1_REG_ADDR;	/* bits 0 1 2 3 4 6 contain count data b6-b11 */			data[index+2] = *TIMER_LA2_REG_ADDR;	/* bits 0 1 2 3 4 6 contain count data b12-b17 */			data[index+3] = *TIMER_LA3_REG_ADDR;	/* bits 0 1 2 3 contain count data b18-b21 */				}		printf("Checking for errors...\n" );			/* Assemble and check recorded register data for errors */		for ( sample=0, index=0 ; sample < ( MAX_N_PASSES * MAX_N_SAMPLES ) ; sample++, index += 4)		{				/* Assembles counter data that was read on the fly */				/* xbxbbbbb */				/* 01000000 = 0x40 */				/* 00011111 = 0x1F */			data[index] &= 0x7f;		/* mask all unused bits */			temp3=data[index];			temp4=data[index];			temp3 &= 0x40;				/* isolate bit 6 */			temp3 = temp3 >> 1;			/* shift bit 6 to bit 5 */			temp4 &= 0x1f;				/* isolate bits 0-4 */			TmrLa0Read = temp3 + temp4;			data[index+1] &= 0x7f;		/* mask all unused bits */			temp3=data[index+1];			temp4=data[index+1];			temp3 &= 0x40;				/* isolate bit 6 */			temp3 = temp3 >> 1;			/* shift bit 6 to bit 5 */			temp4 &= 0x1f;				/* isolate bits 0-4 */			TmrLa1Read = temp3 + temp4;			data[index+2] &= 0x7f;		/* mask all unused bits */			temp3=data[index+2];			temp4=data[index+2];			temp3 &= 0x40;				/* isolate bit 6 */			temp3 = temp3 >> 1;			/* shift bit 6 to bit 5 */			temp4 &= 0x1f;				/* isolate bits 0-4 */			TmrLa2Read = temp3 + temp4;			data[index+3] &= 0x0f;		/* mask all unused bits */			TmrLa3Read = data[index+3];										/* sum timer count data */			CurrentCount = TmrLa0Read + (TmrLa1Read << 6 ) + (TmrLa2Read << 12 ) + (TmrLa3Read << 18 );			if ( sample == 0 )			{				LastLastCount = 0;				LastCount = CurrentCount;			}			if (sample == 1 )			{				LastLastCount = LastCount;				LastCount = CurrentCount;			}			if ( sample > 1 )	/* check for data anomaly, is count value read 2 samples ago greater than the count value read 1 sample ago */			{				/* print error value (LastCount) positioned in between the previous and current values */				if ( ( LastLastCount > LastCount ) && ( CurrentCount > LastLastCount ) )	/* show error only, do not show a counter wrap around reading, print error value (LastCount) positioned in between the previous and current values */				{					printf("0x%x 0x%x 0x%x \n", LastLastCount, LastCount, CurrentCount );					Error = TRUE;	/* set flag to error condition */				}				LastLastCount = LastCount;				LastCount = CurrentCount;			}		}			/* load control data to stop timer b0=0 and reset timer interrupt b1=0 */		EXT_TIMER_CNT_DISAB();	} /* end if( data != NULL ) */		else	/* data = NULL */	{		printf( "Cannot allocate memory.\n" );	}	if ( Error == TRUE )	{		printf("Timer LA0-3 register read test FAILED.\n");	}	else	{		printf("Timer LA0-3 register read test PASSED.\n");	}} /* end counter_test() *//* initialize timer for diagnostic use */void init_external_timer(){	/* disable timer in case it was running */	EXT_TIMER_INT_DISAB();	EXT_TIMER_CNT_DISAB();	timer_ticks = 0;	/* connect the timer ISR */	isr_connect (TIMER_INT_ID, ext_timer_handler, 0);	/* enable the external interrupt */	if (enable_external_interrupt(TIMER_INT_ID) != OK)		printf("ERROR enabling EXT TIMER interrupt!\n");}/* uninitialize timer after diagnostics */void uninit_external_timer(){		/* disable timer */	EXT_TIMER_INT_DISAB();	EXT_TIMER_CNT_DISAB();	/* disable and disconnect timer interrupts */	disable_external_interrupt(TIMER_INT_ID);	isr_disconnect (TIMER_INT_ID);}/* 02/02/01 jwf *//* delay_ms - delay specified number of milliseconds */void delay_ms(int num_ms){UINT32 count;int num_ticks;	timer_ticks = 0;	if (num_ms < 10)		num_ticks = 1;	else	{		/* num_ms must be multiple of 10 - round up */		num_ticks = num_ms / 10;		if (num_ms % 10)			num_ticks++; /* round up */	}	/* for the test we will setup the timer to generate a 10msec tick */	count = EXT_TIMER_10MSEC_COUNT;	/* write the initial count to the timer */	write_timer_count (count);	/* enable the interrupt at the timer */	EXT_TIMER_INT_ENAB();	/* enable the timer to count */	EXT_TIMER_CNT_ENAB();	while (timer_ticks < num_ticks)		;		/* disable timer */	EXT_TIMER_INT_DISAB();	EXT_TIMER_CNT_DISAB();}/* test the 32 bit timer inside the CPLD, U17 */void timer_test (void){	volatile int i;	UINT32 count;		/*****  Perform 10 second count at 100 ticks/sec ****/	/* for the test we will setup the timer to generate a 10msec tick */	count = EXT_TIMER_10MSEC_COUNT;	/* write the initial count to the timer */	write_timer_count (count);	/* enable the interrupt at the timer */	EXT_TIMER_INT_ENAB();	/* enable the timer to count */	EXT_TIMER_CNT_ENAB();	printf ("Counting at %d Ticks Per Second.\n", TICKS_10MSEC);	printf ("Numbers should appear on 1 second increments...\n");	for (i = 0; i < 10; i++)	{		while (timer_ticks < TICKS_10MSEC)			;		printf ("%d ", i);		timer_ticks = 0;	}	printf ("\nDone\n\n");	/* disable timer */	EXT_TIMER_INT_DISAB();	EXT_TIMER_CNT_DISAB();		/*****  Perform 10 second count at 200 ticks/sec ****/	count = EXT_TIMER_5MSEC_COUNT;	write_timer_count (count);	timer_ticks = 0;	/* enable the interrupt at the timer */	EXT_TIMER_INT_ENAB();	/* enable the timer to count */	EXT_TIMER_CNT_ENAB();	printf ("Counting at %d Ticks Per Second.\n", TICKS_5MSEC);	printf ("Numbers should appear on 1 second increments...\n");	for (i = 0; i < 10; i++)	{		while (timer_ticks < TICKS_5MSEC)			;		printf ("%d ", i);		timer_ticks = 0;	}	printf ("\nDone\n\n");	/* disable timer */	EXT_TIMER_INT_DISAB();	EXT_TIMER_CNT_DISAB();/* 12/18/00 jwf */	uninit_external_timer();	/* disable interrupt */	counter_test();	init_external_timer();		/* enable interrupt */	printf("\nExternal Timer Test Done\n");/* 12/18/00 jwf */	printf("\n\nStrike <CR> to exit this test." );	while (xgetchar() != 0x0d);	return;} /* end timer_test() *//* 02/07/01 jwf *//* Use the CPLD 22 bit timer to generate a variable delay time *//* set up the timer to generate a t msec tick, where ( 0mS < t < 127mS ) *//* count=(33MHZ)(t/1 timer interrupt) where ( 0x0 < count <= 0x3fffff ) *//* set total number of timer interrupts to num_tmr_int *//* generate t(delay)=(count)(num_tmr_int) */void time_delay (UINT32 count, volatile int num_tmr_int){	/* write the initial count to the timer */	write_timer_count (count);	/* enable the interrupt at the timer */	EXT_TIMER_INT_ENAB();	/* enable the timer to count */	EXT_TIMER_CNT_ENAB();	/* generate tmr_int timer interrupts */	while (timer_ticks < num_tmr_int);	timer_ticks = 0;	/* disable timer */	EXT_TIMER_INT_DISAB();	EXT_TIMER_CNT_DISAB();} /* end time_delay() */

⌨️ 快捷键说明

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