577 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			577 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*****************************************************************************
 | |
| * Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
 | |
| *
 | |
| * Unless you and Broadcom execute a separate written software license
 | |
| * agreement governing use of this software, this software is licensed to you
 | |
| * under the terms of the GNU General Public License version 2, available at
 | |
| * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
 | |
| *
 | |
| * Notwithstanding the above, under no circumstances may you combine this
 | |
| * software in any way with any other Broadcom software provided under a
 | |
| * license other than the GPL, without Broadcom's express prior written
 | |
| * consent.
 | |
| *****************************************************************************/
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @file    tmrHw.c
 | |
| *
 | |
| *  @brief   Low level Timer driver routines
 | |
| *
 | |
| *  @note
 | |
| *
 | |
| *   These routines provide basic timer functionality only.
 | |
| */
 | |
| /****************************************************************************/
 | |
| 
 | |
| /* ---- Include Files ---------------------------------------------------- */
 | |
| 
 | |
| #include <csp/errno.h>
 | |
| #include <csp/stdint.h>
 | |
| 
 | |
| #include <csp/tmrHw.h>
 | |
| #include <mach/csp/tmrHw_reg.h>
 | |
| 
 | |
| #define tmrHw_ASSERT(a)                     if (!(a)) *(char *)0 = 0
 | |
| #define tmrHw_MILLISEC_PER_SEC              (1000)
 | |
| 
 | |
| #define tmrHw_LOW_1_RESOLUTION_COUNT        (tmrHw_LOW_RESOLUTION_CLOCK / tmrHw_MILLISEC_PER_SEC)
 | |
| #define tmrHw_LOW_1_MAX_MILLISEC            (0xFFFFFFFF / tmrHw_LOW_1_RESOLUTION_COUNT)
 | |
| #define tmrHw_LOW_16_RESOLUTION_COUNT       (tmrHw_LOW_1_RESOLUTION_COUNT / 16)
 | |
| #define tmrHw_LOW_16_MAX_MILLISEC           (0xFFFFFFFF / tmrHw_LOW_16_RESOLUTION_COUNT)
 | |
| #define tmrHw_LOW_256_RESOLUTION_COUNT      (tmrHw_LOW_1_RESOLUTION_COUNT / 256)
 | |
| #define tmrHw_LOW_256_MAX_MILLISEC          (0xFFFFFFFF / tmrHw_LOW_256_RESOLUTION_COUNT)
 | |
| 
 | |
| #define tmrHw_HIGH_1_RESOLUTION_COUNT       (tmrHw_HIGH_RESOLUTION_CLOCK / tmrHw_MILLISEC_PER_SEC)
 | |
| #define tmrHw_HIGH_1_MAX_MILLISEC           (0xFFFFFFFF / tmrHw_HIGH_1_RESOLUTION_COUNT)
 | |
| #define tmrHw_HIGH_16_RESOLUTION_COUNT      (tmrHw_HIGH_1_RESOLUTION_COUNT / 16)
 | |
| #define tmrHw_HIGH_16_MAX_MILLISEC          (0xFFFFFFFF / tmrHw_HIGH_16_RESOLUTION_COUNT)
 | |
| #define tmrHw_HIGH_256_RESOLUTION_COUNT     (tmrHw_HIGH_1_RESOLUTION_COUNT / 256)
 | |
| #define tmrHw_HIGH_256_MAX_MILLISEC         (0xFFFFFFFF / tmrHw_HIGH_256_RESOLUTION_COUNT)
 | |
| 
 | |
| static void ResetTimer(tmrHw_ID_t timerId)
 | |
|     __attribute__ ((section(".aramtext")));
 | |
| static int tmrHw_divide(int num, int denom)
 | |
|     __attribute__ ((section(".aramtext")));
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Get timer capability
 | |
| *
 | |
| *  This function returns various capabilities/attributes of a timer
 | |
| *
 | |
| *  @return  Capability
 | |
| *
 | |
| */
 | |
| /****************************************************************************/
 | |
| uint32_t tmrHw_getTimerCapability(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
 | |
| 				  tmrHw_CAPABILITY_e capability	/*  [ IN ] Timer capability */
 | |
| ) {
 | |
| 	switch (capability) {
 | |
| 	case tmrHw_CAPABILITY_CLOCK:
 | |
| 		return (timerId <=
 | |
| 			1) ? tmrHw_LOW_RESOLUTION_CLOCK :
 | |
| 		    tmrHw_HIGH_RESOLUTION_CLOCK;
 | |
| 	case tmrHw_CAPABILITY_RESOLUTION:
 | |
| 		return 32;
 | |
| 	default:
 | |
| 		return 0;
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Resets a timer
 | |
| *
 | |
| *  This function initializes  timer
 | |
| *
 | |
| *  @return  void
 | |
| *
 | |
| */
 | |
| /****************************************************************************/
 | |
| static void ResetTimer(tmrHw_ID_t timerId	/*  [ IN ] Timer Id */
 | |
| ) {
 | |
| 	/* Reset timer */
 | |
| 	pTmrHw[timerId].LoadValue = 0;
 | |
| 	pTmrHw[timerId].CurrentValue = 0xFFFFFFFF;
 | |
| 	pTmrHw[timerId].Control = 0;
 | |
| 	pTmrHw[timerId].BackgroundLoad = 0;
 | |
| 	/* Always configure as a 32 bit timer */
 | |
| 	pTmrHw[timerId].Control |= tmrHw_CONTROL_32BIT;
 | |
| 	/* Clear interrupt only if raw status interrupt is set */
 | |
| 	if (pTmrHw[timerId].RawInterruptStatus) {
 | |
| 		pTmrHw[timerId].InterruptClear = 0xFFFFFFFF;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Sets counter value for an interval in ms
 | |
| *
 | |
| *  @return   On success: Effective counter value set
 | |
| *            On failure: 0
 | |
| *
 | |
| */
 | |
| /****************************************************************************/
 | |
| static tmrHw_INTERVAL_t SetTimerPeriod(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
 | |
| 				       tmrHw_INTERVAL_t msec	/*  [ IN ] Interval in milli-second */
 | |
| ) {
 | |
| 	uint32_t scale = 0;
 | |
| 	uint32_t count = 0;
 | |
| 
 | |
| 	if (timerId == 0 || timerId == 1) {
 | |
| 		if (msec <= tmrHw_LOW_1_MAX_MILLISEC) {
 | |
| 			pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
 | |
| 			scale = tmrHw_LOW_1_RESOLUTION_COUNT;
 | |
| 		} else if (msec <= tmrHw_LOW_16_MAX_MILLISEC) {
 | |
| 			pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_16;
 | |
| 			scale = tmrHw_LOW_16_RESOLUTION_COUNT;
 | |
| 		} else if (msec <= tmrHw_LOW_256_MAX_MILLISEC) {
 | |
| 			pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_256;
 | |
| 			scale = tmrHw_LOW_256_RESOLUTION_COUNT;
 | |
| 		} else {
 | |
| 			return 0;
 | |
| 		}
 | |
| 
 | |
| 		count = msec * scale;
 | |
| 		/* Set counter value */
 | |
| 		pTmrHw[timerId].LoadValue = count;
 | |
| 		pTmrHw[timerId].BackgroundLoad = count;
 | |
| 
 | |
| 	} else if (timerId == 2 || timerId == 3) {
 | |
| 		if (msec <= tmrHw_HIGH_1_MAX_MILLISEC) {
 | |
| 			pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
 | |
| 			scale = tmrHw_HIGH_1_RESOLUTION_COUNT;
 | |
| 		} else if (msec <= tmrHw_HIGH_16_MAX_MILLISEC) {
 | |
| 			pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_16;
 | |
| 			scale = tmrHw_HIGH_16_RESOLUTION_COUNT;
 | |
| 		} else if (msec <= tmrHw_HIGH_256_MAX_MILLISEC) {
 | |
| 			pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_256;
 | |
| 			scale = tmrHw_HIGH_256_RESOLUTION_COUNT;
 | |
| 		} else {
 | |
| 			return 0;
 | |
| 		}
 | |
| 
 | |
| 		count = msec * scale;
 | |
| 		/* Set counter value */
 | |
| 		pTmrHw[timerId].LoadValue = count;
 | |
| 		pTmrHw[timerId].BackgroundLoad = count;
 | |
| 	}
 | |
| 	return count / scale;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Configures a periodic timer in terms of timer interrupt rate
 | |
| *
 | |
| *  This function initializes a periodic timer to generate specific number of
 | |
| *  timer interrupt per second
 | |
| *
 | |
| *  @return   On success: Effective timer frequency
 | |
| *            On failure: 0
 | |
| *
 | |
| */
 | |
| /****************************************************************************/
 | |
| tmrHw_RATE_t tmrHw_setPeriodicTimerRate(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
 | |
| 					tmrHw_RATE_t rate	/*  [ IN ] Number of timer interrupt per second */
 | |
| ) {
 | |
| 	uint32_t resolution = 0;
 | |
| 	uint32_t count = 0;
 | |
| 	ResetTimer(timerId);
 | |
| 
 | |
| 	/* Set timer mode periodic */
 | |
| 	pTmrHw[timerId].Control |= tmrHw_CONTROL_PERIODIC;
 | |
| 	pTmrHw[timerId].Control &= ~tmrHw_CONTROL_ONESHOT;
 | |
| 	/* Set timer in highest resolution */
 | |
| 	pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
 | |
| 
 | |
| 	if (rate && (timerId == 0 || timerId == 1)) {
 | |
| 		if (rate > tmrHw_LOW_RESOLUTION_CLOCK) {
 | |
| 			return 0;
 | |
| 		}
 | |
| 		resolution = tmrHw_LOW_RESOLUTION_CLOCK;
 | |
| 	} else if (rate && (timerId == 2 || timerId == 3)) {
 | |
| 		if (rate > tmrHw_HIGH_RESOLUTION_CLOCK) {
 | |
| 			return 0;
 | |
| 		} else {
 | |
| 			resolution = tmrHw_HIGH_RESOLUTION_CLOCK;
 | |
| 		}
 | |
| 	} else {
 | |
| 		return 0;
 | |
| 	}
 | |
| 	/* Find the counter value */
 | |
| 	count = resolution / rate;
 | |
| 	/* Set counter value */
 | |
| 	pTmrHw[timerId].LoadValue = count;
 | |
| 	pTmrHw[timerId].BackgroundLoad = count;
 | |
| 
 | |
| 	return resolution / count;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Configures a periodic timer to generate timer interrupt after
 | |
| *           certain time interval
 | |
| *
 | |
| *  This function initializes a periodic timer to generate timer interrupt
 | |
| *  after every time interval in millisecond
 | |
| *
 | |
| *  @return   On success: Effective interval set in milli-second
 | |
| *            On failure: 0
 | |
| *
 | |
| */
 | |
| /****************************************************************************/
 | |
| tmrHw_INTERVAL_t tmrHw_setPeriodicTimerInterval(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
 | |
| 						tmrHw_INTERVAL_t msec	/*  [ IN ] Interval in milli-second */
 | |
| ) {
 | |
| 	ResetTimer(timerId);
 | |
| 
 | |
| 	/* Set timer mode periodic */
 | |
| 	pTmrHw[timerId].Control |= tmrHw_CONTROL_PERIODIC;
 | |
| 	pTmrHw[timerId].Control &= ~tmrHw_CONTROL_ONESHOT;
 | |
| 
 | |
| 	return SetTimerPeriod(timerId, msec);
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Configures a periodic timer to generate timer interrupt just once
 | |
| *           after certain time interval
 | |
| *
 | |
| *  This function initializes a periodic timer to generate a single ticks after
 | |
| *  certain time interval in millisecond
 | |
| *
 | |
| *  @return   On success: Effective interval set in milli-second
 | |
| *            On failure: 0
 | |
| *
 | |
| */
 | |
| /****************************************************************************/
 | |
| tmrHw_INTERVAL_t tmrHw_setOneshotTimerInterval(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
 | |
| 					       tmrHw_INTERVAL_t msec	/*  [ IN ] Interval in milli-second */
 | |
| ) {
 | |
| 	ResetTimer(timerId);
 | |
| 
 | |
| 	/* Set timer mode oneshot */
 | |
| 	pTmrHw[timerId].Control |= tmrHw_CONTROL_PERIODIC;
 | |
| 	pTmrHw[timerId].Control |= tmrHw_CONTROL_ONESHOT;
 | |
| 
 | |
| 	return SetTimerPeriod(timerId, msec);
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Configures a timer to run as a free running timer
 | |
| *
 | |
| *  This function initializes a timer to run as a free running timer
 | |
| *
 | |
| *  @return   Timer resolution (count / sec)
 | |
| *
 | |
| */
 | |
| /****************************************************************************/
 | |
| tmrHw_RATE_t tmrHw_setFreeRunningTimer(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
 | |
| 				       uint32_t divider	/*  [ IN ] Dividing the clock frequency */
 | |
| ) {
 | |
| 	uint32_t scale = 0;
 | |
| 
 | |
| 	ResetTimer(timerId);
 | |
| 	/* Set timer as free running mode */
 | |
| 	pTmrHw[timerId].Control &= ~tmrHw_CONTROL_PERIODIC;
 | |
| 	pTmrHw[timerId].Control &= ~tmrHw_CONTROL_ONESHOT;
 | |
| 
 | |
| 	if (divider >= 64) {
 | |
| 		pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_256;
 | |
| 		scale = 256;
 | |
| 	} else if (divider >= 8) {
 | |
| 		pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_16;
 | |
| 		scale = 16;
 | |
| 	} else {
 | |
| 		pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
 | |
| 		scale = 1;
 | |
| 	}
 | |
| 
 | |
| 	if (timerId == 0 || timerId == 1) {
 | |
| 		return tmrHw_divide(tmrHw_LOW_RESOLUTION_CLOCK, scale);
 | |
| 	} else if (timerId == 2 || timerId == 3) {
 | |
| 		return tmrHw_divide(tmrHw_HIGH_RESOLUTION_CLOCK, scale);
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Starts a timer
 | |
| *
 | |
| *  This function starts a preconfigured timer
 | |
| *
 | |
| *  @return  -1     - On Failure
 | |
| *            0     - On Success
 | |
| *
 | |
| */
 | |
| /****************************************************************************/
 | |
| int tmrHw_startTimer(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
 | |
| ) {
 | |
| 	pTmrHw[timerId].Control |= tmrHw_CONTROL_TIMER_ENABLE;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Stops a timer
 | |
| *
 | |
| *  This function stops a running timer
 | |
| *
 | |
| *  @return  -1     - On Failure
 | |
| *            0     - On Success
 | |
| *
 | |
| */
 | |
| /****************************************************************************/
 | |
| int tmrHw_stopTimer(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
 | |
| ) {
 | |
| 	pTmrHw[timerId].Control &= ~tmrHw_CONTROL_TIMER_ENABLE;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Gets current timer count
 | |
| *
 | |
| *  This function returns the current timer value
 | |
| *
 | |
| *  @return  Current downcounting timer value
 | |
| *
 | |
| */
 | |
| /****************************************************************************/
 | |
| uint32_t tmrHw_GetCurrentCount(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
 | |
| ) {
 | |
| 	/* return 32 bit timer value */
 | |
| 	switch (pTmrHw[timerId].Control & tmrHw_CONTROL_MODE_MASK) {
 | |
| 	case tmrHw_CONTROL_FREE_RUNNING:
 | |
| 		if (pTmrHw[timerId].CurrentValue) {
 | |
| 			return tmrHw_MAX_COUNT - pTmrHw[timerId].CurrentValue;
 | |
| 		}
 | |
| 		break;
 | |
| 	case tmrHw_CONTROL_PERIODIC:
 | |
| 	case tmrHw_CONTROL_ONESHOT:
 | |
| 		return pTmrHw[timerId].BackgroundLoad -
 | |
| 		    pTmrHw[timerId].CurrentValue;
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Gets timer count rate
 | |
| *
 | |
| *  This function returns the number of counts per second
 | |
| *
 | |
| *  @return  Count rate
 | |
| *
 | |
| */
 | |
| /****************************************************************************/
 | |
| tmrHw_RATE_t tmrHw_getCountRate(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
 | |
| ) {
 | |
| 	uint32_t divider = 0;
 | |
| 
 | |
| 	switch (pTmrHw[timerId].Control & tmrHw_CONTROL_PRESCALE_MASK) {
 | |
| 	case tmrHw_CONTROL_PRESCALE_1:
 | |
| 		divider = 1;
 | |
| 		break;
 | |
| 	case tmrHw_CONTROL_PRESCALE_16:
 | |
| 		divider = 16;
 | |
| 		break;
 | |
| 	case tmrHw_CONTROL_PRESCALE_256:
 | |
| 		divider = 256;
 | |
| 		break;
 | |
| 	default:
 | |
| 		tmrHw_ASSERT(0);
 | |
| 	}
 | |
| 
 | |
| 	if (timerId == 0 || timerId == 1) {
 | |
| 		return tmrHw_divide(tmrHw_LOW_RESOLUTION_CLOCK, divider);
 | |
| 	} else {
 | |
| 		return tmrHw_divide(tmrHw_HIGH_RESOLUTION_CLOCK, divider);
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Enables timer interrupt
 | |
| *
 | |
| *  This function enables the timer interrupt
 | |
| *
 | |
| *  @return   N/A
 | |
| *
 | |
| */
 | |
| /****************************************************************************/
 | |
| void tmrHw_enableInterrupt(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
 | |
| ) {
 | |
| 	pTmrHw[timerId].Control |= tmrHw_CONTROL_INTERRUPT_ENABLE;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Disables timer interrupt
 | |
| *
 | |
| *  This function disable the timer interrupt
 | |
| *
 | |
| *  @return   N/A
 | |
| *
 | |
| */
 | |
| /****************************************************************************/
 | |
| void tmrHw_disableInterrupt(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
 | |
| ) {
 | |
| 	pTmrHw[timerId].Control &= ~tmrHw_CONTROL_INTERRUPT_ENABLE;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Clears the interrupt
 | |
| *
 | |
| *  This function clears the timer interrupt
 | |
| *
 | |
| *  @return   N/A
 | |
| *
 | |
| *  @note
 | |
| *     Must be called under the context of ISR
 | |
| */
 | |
| /****************************************************************************/
 | |
| void tmrHw_clearInterrupt(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
 | |
| ) {
 | |
| 	pTmrHw[timerId].InterruptClear = 0x1;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Gets the interrupt status
 | |
| *
 | |
| *  This function returns timer interrupt status
 | |
| *
 | |
| *  @return   Interrupt status
 | |
| */
 | |
| /****************************************************************************/
 | |
| tmrHw_INTERRUPT_STATUS_e tmrHw_getInterruptStatus(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
 | |
| ) {
 | |
| 	if (pTmrHw[timerId].InterruptStatus) {
 | |
| 		return tmrHw_INTERRUPT_STATUS_SET;
 | |
| 	} else {
 | |
| 		return tmrHw_INTERRUPT_STATUS_UNSET;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Indentifies a timer causing interrupt
 | |
| *
 | |
| *  This functions returns a timer causing interrupt
 | |
| *
 | |
| *  @return  0xFFFFFFFF   : No timer causing an interrupt
 | |
| *           ! 0xFFFFFFFF : timer causing an interrupt
 | |
| *  @note
 | |
| *     tmrHw_clearIntrrupt() must be called with a valid timer id after calling this function
 | |
| */
 | |
| /****************************************************************************/
 | |
| tmrHw_ID_t tmrHw_getInterruptSource(void	/*  void */
 | |
| ) {
 | |
| 	int i;
 | |
| 
 | |
| 	for (i = 0; i < tmrHw_TIMER_NUM_COUNT; i++) {
 | |
| 		if (pTmrHw[i].InterruptStatus) {
 | |
| 			return i;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return 0xFFFFFFFF;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Displays specific timer registers
 | |
| *
 | |
| *
 | |
| *  @return  void
 | |
| *
 | |
| */
 | |
| /****************************************************************************/
 | |
| void tmrHw_printDebugInfo(tmrHw_ID_t timerId,	/*  [ IN ] Timer id */
 | |
| 			  int (*fpPrint) (const char *, ...)	/*  [ IN ] Print callback function */
 | |
| ) {
 | |
| 	(*fpPrint) ("Displaying register contents \n\n");
 | |
| 	(*fpPrint) ("Timer %d: Load value              0x%X\n", timerId,
 | |
| 		    pTmrHw[timerId].LoadValue);
 | |
| 	(*fpPrint) ("Timer %d: Background load value   0x%X\n", timerId,
 | |
| 		    pTmrHw[timerId].BackgroundLoad);
 | |
| 	(*fpPrint) ("Timer %d: Control                 0x%X\n", timerId,
 | |
| 		    pTmrHw[timerId].Control);
 | |
| 	(*fpPrint) ("Timer %d: Interrupt clear         0x%X\n", timerId,
 | |
| 		    pTmrHw[timerId].InterruptClear);
 | |
| 	(*fpPrint) ("Timer %d: Interrupt raw interrupt 0x%X\n", timerId,
 | |
| 		    pTmrHw[timerId].RawInterruptStatus);
 | |
| 	(*fpPrint) ("Timer %d: Interrupt status        0x%X\n", timerId,
 | |
| 		    pTmrHw[timerId].InterruptStatus);
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Use a timer to perform a busy wait delay for a number of usecs.
 | |
| *
 | |
| *  @return   N/A
 | |
| */
 | |
| /****************************************************************************/
 | |
| void tmrHw_udelay(tmrHw_ID_t timerId,	/*  [ IN ] Timer id */
 | |
| 		  unsigned long usecs /*  [ IN ] usec to delay */
 | |
| ) {
 | |
| 	tmrHw_RATE_t usec_tick_rate;
 | |
| 	tmrHw_COUNT_t start_time;
 | |
| 	tmrHw_COUNT_t delta_time;
 | |
| 
 | |
| 	start_time = tmrHw_GetCurrentCount(timerId);
 | |
| 	usec_tick_rate = tmrHw_divide(tmrHw_getCountRate(timerId), 1000000);
 | |
| 	delta_time = usecs * usec_tick_rate;
 | |
| 
 | |
| 	/* Busy wait */
 | |
| 	while (delta_time > (tmrHw_GetCurrentCount(timerId) - start_time))
 | |
| 		;
 | |
| }
 | |
| 
 | |
| /****************************************************************************/
 | |
| /**
 | |
| *  @brief   Local Divide function
 | |
| *
 | |
| *  This function does the divide
 | |
| *
 | |
| *  @return divide value
 | |
| *
 | |
| */
 | |
| /****************************************************************************/
 | |
| static int tmrHw_divide(int num, int denom)
 | |
| {
 | |
| 	int r;
 | |
| 	int t = 1;
 | |
| 
 | |
| 	/* Shift denom and t up to the largest value to optimize algorithm */
 | |
| 	/* t contains the units of each divide */
 | |
| 	while ((denom & 0x40000000) == 0) {	/* fails if denom=0 */
 | |
| 		denom = denom << 1;
 | |
| 		t = t << 1;
 | |
| 	}
 | |
| 
 | |
| 	/* Intialize the result */
 | |
| 	r = 0;
 | |
| 
 | |
| 	do {
 | |
| 		/* Determine if there exists a positive remainder */
 | |
| 		if ((num - denom) >= 0) {
 | |
| 			/* Accumlate t to the result and calculate a new remainder */
 | |
| 			num = num - denom;
 | |
| 			r = r + t;
 | |
| 		}
 | |
| 		/* Continue to shift denom and shift t down to 0 */
 | |
| 		denom = denom >> 1;
 | |
| 		t = t >> 1;
 | |
| 	} while (t != 0);
 | |
| 	return r;
 | |
| }
 |