/**
*
* Starts the specified timer counter of the device such that it starts running.
* The timer counter is reset before it is started and the reset value is
* loaded into the timer counter.
*
* If interrupt mode is specified in the options, it is necessary for the caller
* to connect the interrupt handler of the timer/counter to the interrupt source,
* typically an interrupt controller, and enable the interrupt within the
* interrupt controller.
*
* @param	InstancePtr is a pointer to the XTmrCtr instance.
* @param	TmrCtrNumber is the timer counter of the device to operate on.
*		Each device may contain multiple timer counters. The timer
*		number is a zero based number with a range of
*		0 - (XTC_DEVICE_TIMER_COUNT - 1).
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void XTmrCtr_Start(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
{
	u32 ControlStatusReg;

	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Read the current register contents such that only the necessary bits
	 * of the register are modified in the following operations
	 */
	ControlStatusReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
					      TmrCtrNumber, XTC_TCSR_OFFSET);
	/*
	 * Reset the timer counter such that it reloads from the compare
	 * register and the interrupt is cleared simultaneously, the interrupt
	 * can only be cleared after reset such that the interrupt condition is
	 * cleared
	 */
	XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
			  XTC_TCSR_OFFSET,
			  XTC_CSR_LOAD_MASK);

	/*
	 * Remove the reset condition such that the timer counter starts running
	 * with the value loaded from the compare register
	 */
	XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
			  XTC_TCSR_OFFSET,
			  ControlStatusReg | XTC_CSR_ENABLE_TMR_MASK);
}
Example #2
0
/**
*
* Stops the timer counter by disabling it.
*
* It is the callers' responsibility to disconnect the interrupt handler of the
* timer_counter from the interrupt source, typically an interrupt controller,
* and disable the interrupt within the interrupt controller.
*
* @param	InstancePtr is a pointer to the XTmrCtr instance.
* @param	TmrCtrNumber is the timer counter of the device to operate on.
*		Each device may contain multiple timer counters. The timer
*		number is a zero based number with a range of
*		0 - (XTC_DEVICE_TIMER_COUNT - 1).
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void XTmrCtr_Stop(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
{
	u32 ControlStatusReg;

	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Read the current register contents
	 */
	ControlStatusReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
					      TmrCtrNumber, XTC_TCSR_OFFSET);
	/*
	 * Disable the timer counter such that it's not running
	 */
	ControlStatusReg &= ~(XTC_CSR_ENABLE_TMR_MASK);

	/*
	 * Write out the updated value to the actual register.
	 */
	XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
			  XTC_TCSR_OFFSET, ControlStatusReg);

	/*
	 * Indicate that the timer is stopped
	 */
	if (TmrCtrNumber == 0) {
		InstancePtr->IsStartedTmrCtr0 = 0;
	} else {
		InstancePtr->IsStartedTmrCtr1 = 0;
	}
}
Example #3
0
/**
*
* Set the reset value for the specified timer counter. This is the value
* that is loaded into the timer counter when it is reset. This value is also
* loaded when the timer counter is started.
*
* @param	InstancePtr is a pointer to the XTmrCtr instance.
* @param	TmrCtrNumber is the timer counter of the device to operate on.
*		Each device may contain multiple timer counters. The timer
*		number is a zero based number  with a range of
*		0 - (XTC_DEVICE_TIMER_COUNT - 1).
* @param	ResetValue contains the value to be used to reset the timer
*		counter.
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void XTmrCtr_SetResetValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber,
			   u32 ResetValue)
{

	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
			  XTC_TLR_OFFSET, ResetValue);
}
Example #4
0
void timer_handler()
{
	Xuint32 ControlStatusReg;

	ControlStatusReg = XTimerCtr_ReadReg(Timer_tmrctr.BaseAddress, 0, XTC_TCSR_OFFSET);


	count++;
	onLED(count);
	XTmrCtr_WriteReg(Timer_tmrctr.BaseAddress, 0, XTC_TCSR_OFFSET, ControlStatusReg |XTC_CSR_INT_OCCURED_MASK);
}
Example #5
0
/**
*
* Resets the specified timer counter of the device. A reset causes the timer
* counter to set it's value to the reset value.
*
* @param	InstancePtr is a pointer to the XTmrCtr instance.
* @param	TmrCtrNumber is the timer counter of the device to operate on.
*		Each device may contain multiple timer counters. The timer
*		number is a zero based number  with a range of
*		0 - (XTC_DEVICE_TIMER_COUNT - 1).
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void XTmrCtr_Reset(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
{
	u32 CounterControlReg;

	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Read current contents of the register so it won't be destroyed
	 */
	CounterControlReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
					       TmrCtrNumber, XTC_TCSR_OFFSET);
	/*
	 * Reset the timer by toggling the reset bit in the register
	 */
	XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
			  XTC_TCSR_OFFSET,
			  CounterControlReg | XTC_CSR_LOAD_MASK);

	XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
			  XTC_TCSR_OFFSET, CounterControlReg);
}
Example #6
0
/**
* (Re-)initialzes all timer counters which aren't started already.
*
* @param	InstancePtr is a pointer to the XTmrCtr instance.
*
* @return
*		- XST_SUCCESS if at least one timer counter is stopped.
*		- XST_DEVICE_IS_STARTED otherwise.
*
* @note		None.
*
******************************************************************************/
int XTmrCtr_InitHw(XTmrCtr *InstancePtr)
{
	int Status = XST_DEVICE_IS_STARTED;
	u8 TmrIndex;
	u32 TmrCtrStarted[XTC_DEVICE_TIMER_COUNT];

	/* Verify arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	TmrCtrStarted[0] = InstancePtr->IsStartedTmrCtr0;
	TmrCtrStarted[1] = InstancePtr->IsStartedTmrCtr1;

	for (TmrIndex = 0; TmrIndex < XTC_DEVICE_TIMER_COUNT; TmrIndex++) {
		/* Only initialize timers counters which aren't started. */
		if (TmrCtrStarted[TmrIndex] == XIL_COMPONENT_IS_STARTED) {
			continue;
		}

		/* Set the compare register to 0. */
		XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrIndex,
				  XTC_TLR_OFFSET, 0);
		/* Reset the timer and the interrupt. */
		XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrIndex,
				  XTC_TCSR_OFFSET,
				  XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK);
		/* Release the reset. */
		XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrIndex,
				  XTC_TCSR_OFFSET, 0);

		/* Indicate that at least one timer is not running and has been
		 * initialized. */
		Status = XST_SUCCESS;
	}

	return Status;
}
Example #7
0
/**
*
* Enables the specified options for the specified timer counter. This function
* sets the options without regard to the current options of the driver. To
* prevent a loss of the current options, the user should call
* XTmrCtr_GetOptions() prior to this function and modify the retrieved options
* to pass into this function to prevent loss of the current options.
*
* @param	InstancePtr is a pointer to the XTmrCtr instance.
* @param	TmrCtrNumber is the timer counter of the device to operate on.
*		Each device may contain multiple timer counters. The timer
*		number is a zero based number with a range of
*		0 - (XTC_DEVICE_TIMER_COUNT - 1).
* @param	Options contains the desired options to be set or cleared.
*		Setting the option to '1' enables the option, clearing the to
*		'0' disables the option. The options are bit masks such that
*		multiple options may be set or cleared. The options are
*		described in xtmrctr.h.
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void XTmrCtr_SetOptions(XTmrCtr * InstancePtr, u8 TmrCtrNumber, u32 Options)
{
	u32 CounterControlReg = 0;
	u32 Index;

	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Loop through the Options table, turning the enable on or off
	 * depending on whether the bit is set in the incoming Options flag.
	 */

	for (Index = 0; Index < XTC_NUM_OPTIONS; Index++) {
		if (Options & OptionsTable[Index].Option) {

			/*
			 * Turn the option on
			 */
			CounterControlReg |= OptionsTable[Index].Mask;
		}
		else {
			/*
			 * Turn the option off
			 */
			CounterControlReg &= ~OptionsTable[Index].Mask;
		}
	}

	/*
	 * Write out the updated value to the actual register
	 */
	XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
			  XTC_TCSR_OFFSET, CounterControlReg);
}
Example #8
0
/**
*
* Initializes a specific timer/counter instance/driver. Initialize fields of
* the XTmrCtr structure, then reset the timer/counter.If a timer is already
* running then it is not initialized.
*
*
* @param	InstancePtr is a pointer to the XTmrCtr instance.
* @param	DeviceId is the unique id of the device controlled by this
*		XTmrCtr component.  Passing in a device id associates the
*		generic XTmrCtr component to a specific device, as chosen by
*		the caller or application developer.
*
* @return
*		- XST_SUCCESS if initialization was successful
*		- XST_DEVICE_IS_STARTED if the device has already been started
*		- XST_DEVICE_NOT_FOUND if the device doesn't exist
*
* @note		None.
*
******************************************************************************/
int XTmrCtr_Initialize(XTmrCtr * InstancePtr, u16 DeviceId)
{
	XTmrCtr_Config *TmrCtrConfigPtr;
	int TmrCtrNumber;
	int TmrCtrLowIndex = 0;
	int TmrCtrHighIndex = XTC_DEVICE_TIMER_COUNT;

	Xil_AssertNonvoid(InstancePtr != NULL);


	/*
	 * If both the timers have already started, disallow the initialize and
	 * return a status indicating it is started.  This allows the user to stop
	 * the device and reinitialize, but prevents a user from inadvertently
	 * initializing.
	 * In case one of the timers has not started then that particular timer
	 * will be initialized
	 */
	if ((InstancePtr->IsStartedTmrCtr0 == XIL_COMPONENT_IS_STARTED) &&
	    (InstancePtr->IsStartedTmrCtr1 == XIL_COMPONENT_IS_STARTED)) {
		return XST_DEVICE_IS_STARTED;
	}


	/*
	 * Ensure that only the timer which is NOT started can be initialized
	 */
	if ((InstancePtr->IsStartedTmrCtr0 == XIL_COMPONENT_IS_STARTED)) {
		TmrCtrLowIndex = 1;
	} else if ((InstancePtr->IsStartedTmrCtr1 == XIL_COMPONENT_IS_STARTED)) {
		TmrCtrHighIndex = 1;
	} else {
		InstancePtr->IsStartedTmrCtr0 = 0;
		InstancePtr->IsStartedTmrCtr1 = 0;
	}



	/*
	 * Lookup the device configuration in the temporary CROM table. Use this
	 * configuration info down below when initializing this component.
	 */
	TmrCtrConfigPtr = XTmrCtr_LookupConfig(DeviceId);

	if (TmrCtrConfigPtr == (XTmrCtr_Config *) NULL) {
		return XST_DEVICE_NOT_FOUND;
	}

	/*
	 * Set some default values, including setting the callback
	 * handlers to stubs.
	 */
	InstancePtr->BaseAddress = TmrCtrConfigPtr->BaseAddress;
	InstancePtr->Handler = NULL;
	InstancePtr->CallBackRef = NULL;

	/*
	 * Clear the statistics for this driver
	 */
	InstancePtr->Stats.Interrupts = 0;

	/* Initialize the registers of each timer/counter in the device */

	for (TmrCtrNumber = TmrCtrLowIndex; TmrCtrNumber < TmrCtrHighIndex;
	     TmrCtrNumber++) {

		/*
		 * Set the Compare register to 0
		 */
		XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
				  XTC_TLR_OFFSET, 0);
		/*
		 * Reset the timer and the interrupt, the reset bit will need to
		 * be cleared after this
		 */
		XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
				  XTC_TCSR_OFFSET,
				  XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK);
		/*
		 * Set the control/status register to complete initialization by
		 * clearing the reset bit which was just set
		 */
		XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
				  XTC_TCSR_OFFSET, 0);
	}

	/*
	 * Indicate the instance is ready to use, successfully initialized
	 */
	InstancePtr->IsReady = XIL_COMPONENT_IS_READY;

	return XST_SUCCESS;
}
/**
*
* Runs a self-test on the driver/device. This test verifies that the specified
* timer counter of the device can be enabled and increments.
*
* @param	InstancePtr is a pointer to the XTmrCtr instance.
* @param	TmrCtrNumber is the timer counter of the device to operate on.
*		Each device may contain multiple timer counters. The timer
*		number is a  zero based number with a range of
*		0 - (XTC_DEVICE_TIMER_COUNT - 1).
*
* @return
* 		- XST_SUCCESS if self-test was successful
*		- XST_FAILURE if the timer is not incrementing.
*
* @note
*
* This is a destructive test using the provided timer. The current settings
* of the timer are returned to the initialized values and all settings at the
* time this function is called are overwritten.
*
******************************************************************************/
int XTmrCtr_SelfTest(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
{
    u32 TimerCount1 = 0;
    u32 TimerCount2 = 0;
    u16 Count = 0;

    Xil_AssertNonvoid(InstancePtr != NULL);
    Xil_AssertNonvoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
    Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

    /*
     * Set the Capture register to 0
     */
    XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
                     XTC_TLR_OFFSET, 0);

    /*
     * Reset the timer and the interrupt
     */
    XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
                     XTC_TCSR_OFFSET,
                     XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK);

    /*
     * Set the control/status register to enable timer
     */
    XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
                     XTC_TCSR_OFFSET, XTC_CSR_ENABLE_TMR_MASK);

    /*
     * Read the timer
     */
    TimerCount1 = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
                                  TmrCtrNumber, XTC_TCR_OFFSET);
    /*
     * Make sure timer is incrementing if the Count rolls over to zero
     * and the timer still has not incremented an error is returned
     */

    do {
        TimerCount2 = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
                                      TmrCtrNumber, XTC_TCR_OFFSET);
        Count++;
    }
    while ((TimerCount1 == TimerCount2) && (Count != 0));

    /*
     * Reset the timer and the interrupt
     */
    XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
                     XTC_TCSR_OFFSET,
                     XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK);

    /*
     * Set the control/status register to 0 to complete initialization
     * this disables the timer completely and allows it to be used again
     */

    XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
                     XTC_TCSR_OFFSET, 0);

    if (TimerCount1 == TimerCount2) {
        return XST_FAILURE;
    }
    else {
        return XST_SUCCESS;
    }
}
/**
*
* Initializes a specific timer/counter instance/driver. Initialize fields of
* the XTmrCtr structure, then reset the timer/counter
*
* @param	InstancePtr is a pointer to the XTmrCtr instance.
* @param	DeviceId is the unique id of the device controlled by this
*		XTmrCtr component.  Passing in a device id associates the
*		generic XTmrCtr component to a specific device, as chosen by
*		the caller or application developer.
*
* @return
*		- XST_SUCCESS if initialization was successful
*		- XST_DEVICE_IS_STARTED if the device has already been started
*		- XST_DEVICE_NOT_FOUND if the device doesn't exist
*
* @note		None.
*
******************************************************************************/
int XTmrCtr_Initialize(XTmrCtr * InstancePtr, u16 DeviceId)
{
	XTmrCtr_Config *TmrCtrConfigPtr;
	int TmrCtrNumber;
	u32 StatusReg;

	Xil_AssertNonvoid(InstancePtr != NULL);

	/*
	 * Lookup the device configuration in the temporary CROM table. Use this
	 * configuration info down below when initializing this component.
	 */
	TmrCtrConfigPtr = XTmrCtr_LookupConfig(DeviceId);

	if (TmrCtrConfigPtr == (XTmrCtr_Config *) NULL) {
		return XST_DEVICE_NOT_FOUND;
	}

	/*
	 * Check each of the timer counters of the device, if any are already
	 * running, then the device should not be initialized. This allows the
	 * user to stop the device and reinitialize, but prevents a user from
	 * inadvertently initializing.
	 */
	for (TmrCtrNumber = 0; TmrCtrNumber < XTC_DEVICE_TIMER_COUNT;
	     TmrCtrNumber++) {
		/*
		 * Read the current register contents and check if the timer
		 * counter is started and running, note that the register read
		 * is not using the base address in the instance so this is not
		 * destructive if the timer counter is already started
		 */
		StatusReg = XTmrCtr_ReadReg(TmrCtrConfigPtr->BaseAddress,
					       TmrCtrNumber, XTC_TCSR_OFFSET);
		if (StatusReg & XTC_CSR_ENABLE_TMR_MASK) {
			return XST_DEVICE_IS_STARTED;
		}
	}

	/*
	 * Set some default values, including setting the callback
	 * handlers to stubs.
	 */
	InstancePtr->BaseAddress = TmrCtrConfigPtr->BaseAddress;
	InstancePtr->Handler = NULL;
	InstancePtr->CallBackRef = NULL;

	/*
	 * Clear the statistics for this driver
	 */
	InstancePtr->Stats.Interrupts = 0;

	/* Initialize the registers of each timer/counter in the device */

	for (TmrCtrNumber = 0; TmrCtrNumber < XTC_DEVICE_TIMER_COUNT;
	     TmrCtrNumber++) {
		/*
		 * Set the Compare register to 0
		 */
		XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
				  XTC_TLR_OFFSET, 0);
		/*
		 * Reset the timer and the interrupt, the reset bit will need to
		 * be cleared after this
		 */
		XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
				  XTC_TCSR_OFFSET,
				  XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK);
		/*
		 * Set the control/status register to complete initialization by
		 * clearing the reset bit which was just set
		 */
		XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
				  XTC_TCSR_OFFSET, 0);
	}

	/*
	 * Indicate the instance is ready to use, successfully initialized
	 */
	InstancePtr->IsReady = XIL_COMPONENT_IS_READY;

	return XST_SUCCESS;
}
/**
*
* Interrupt Service Routine (ISR) for the driver.  This function only performs
* processing for the device and does not save and restore the interrupt context.
*
* @param	InstancePtr contains a pointer to the timer/counter instance for
*		the interrupt.
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void XTmrCtr_InterruptHandler(void *InstancePtr)
{
	XTmrCtr *TmrCtrPtr = NULL;
	u8 TmrCtrNumber;
	u32 ControlStatusReg;

	/*
	 * Verify that each of the inputs are valid.
	 */
	Xil_AssertVoid(InstancePtr != NULL);

	/*
	 * Convert the non-typed pointer to an timer/counter instance pointer
	 * such that there is access to the timer/counter
	 */
	TmrCtrPtr = (XTmrCtr *) InstancePtr;

	/*
	 * Loop thru each timer counter in the device and call the callback
	 * function for each timer which has caused an interrupt
	 */
	for (TmrCtrNumber = 0;
		TmrCtrNumber < XTC_DEVICE_TIMER_COUNT; TmrCtrNumber++) {

		ControlStatusReg = XTmrCtr_ReadReg(TmrCtrPtr->BaseAddress,
						   TmrCtrNumber,
						   XTC_TCSR_OFFSET);
		/*
		 * Check if interrupt is enabled
		 */
		if (ControlStatusReg & XTC_CSR_ENABLE_INT_MASK) {

			/*
			 * Check if timer expired and interrupt occured
			 */
			if (ControlStatusReg & XTC_CSR_INT_OCCURED_MASK) {
				/*
				 * Increment statistics for the number of
				 * interrupts and call the callback to handle
				 * any application specific processing
				 */
				TmrCtrPtr->Stats.Interrupts++;
				TmrCtrPtr->Handler(TmrCtrPtr->CallBackRef,
						   TmrCtrNumber);
				/*
				 * Read the new Control/Status Register content.
				 */
				ControlStatusReg =
					XTmrCtr_ReadReg(TmrCtrPtr->BaseAddress,
								TmrCtrNumber,
								XTC_TCSR_OFFSET);
				/*
				 * If in compare mode and a single shot rather
				 * than auto reload mode then disable the timer
				 * and reset it such so that the interrupt can
				 * be acknowledged, this should be only temporary
				 * till the hardware is fixed
				 */
				if (((ControlStatusReg &
					XTC_CSR_AUTO_RELOAD_MASK) == 0) &&
					((ControlStatusReg &
					  XTC_CSR_CAPTURE_MODE_MASK)== 0)) {
						/*
						 * Disable the timer counter and
						 * reset it such that the timer
						 * counter is loaded with the
						 * reset value allowing the
						 * interrupt to be acknowledged
						 */
						ControlStatusReg &=
							~XTC_CSR_ENABLE_TMR_MASK;

						XTmrCtr_WriteReg(
							TmrCtrPtr->BaseAddress,
							TmrCtrNumber,
							XTC_TCSR_OFFSET,
							ControlStatusReg |
							XTC_CSR_LOAD_MASK);

						/*
						 * Clear the reset condition,
						 * the reset bit must be
						 * manually cleared by a 2nd write
						 * to the register
						 */
						XTmrCtr_WriteReg(
							TmrCtrPtr->BaseAddress,
							TmrCtrNumber,
							XTC_TCSR_OFFSET,
							ControlStatusReg);
				}

				/*
				 * Acknowledge the interrupt by clearing the
				 * interrupt bit in the timer control status
				 * register, this is done after calling the
				 * handler so the application could call
				 * IsExpired, the interrupt is cleared by
				 * writing a 1 to the interrupt bit of the
				 * register without changing any of the other
				 * bits
				 */
				XTmrCtr_WriteReg(TmrCtrPtr->BaseAddress,
						 TmrCtrNumber,
						 XTC_TCSR_OFFSET,
						 ControlStatusReg |
						 XTC_CSR_INT_OCCURED_MASK);
			}
		}
	}
}
Example #12
0
int main(void) {
    u32 cmd;
    u32 count;
    u32 GenerateValue, CaptureDuration;
    u8 NumberOfTimes;
    u32 count1, count2;
    u32 status;
    u8 iop_pins[8];
    u32 timer_pin;

    // Initialize Pmod
    pmod_init(0,1);
    /*
     * Configuring Pmod IO switch
     * Timer is connected to bit[0] of the Channel 1 of AXI GPIO instance
     * This configuration is changed later
     */
    config_pmod_switch(TIMER, GPIO_1, GPIO_2, GPIO_3,
                       GPIO_4, GPIO_5, GPIO_6, GPIO_7);
    // by default tristate timer output
    Xil_Out32(XPAR_GPIO_0_BASEADDR+0x08,1);

    while(1){
        while(MAILBOX_CMD_ADDR==0); // wait for CMD to be issued
        cmd = MAILBOX_CMD_ADDR;
        
        switch(cmd){
            case CONFIG_IOP_SWITCH:
                // read new pin configuration
                timer_pin = MAILBOX_DATA(0);
                iop_pins[0] = GPIO_0;
                iop_pins[1] = GPIO_1;
                iop_pins[2] = GPIO_2;
                iop_pins[3] = GPIO_3;
                iop_pins[4] = GPIO_4;
                iop_pins[5] = GPIO_5;
                iop_pins[6] = GPIO_6;
                iop_pins[7] = GPIO_7;
                // set new pin configuration
                iop_pins[timer_pin] = TIMER;
                config_pmod_switch(iop_pins[0], iop_pins[1], iop_pins[2], 
                                   iop_pins[3], iop_pins[4], iop_pins[5], 
                                   iop_pins[6], iop_pins[7]);
                Xil_Out32(XPAR_GPIO_0_BASEADDR+0x08,1);
                MAILBOX_CMD_ADDR = 0x0;
                break;
                
            case STOP_TIMER:
                XTmrCtr_Stop(&TimerInst_0, 0);
                XTmrCtr_Stop(&TimerInst_0, 1);
                MAILBOX_CMD_ADDR = 0x0;
                break;

            case GENERATE_FOREVER:
                // tri-state control negated so output can be driven
                Xil_Out32(XPAR_GPIO_0_BASEADDR+0x08,0);
                // get period value in multiple of 10 ns clock period
                GenerateValue=MAILBOX_DATA(0);
                XTmrCtr_SetResetValue(&TimerInst_0, 0, GenerateValue);
                XTmrCtr_SetOptions(&TimerInst_0, 0,
                        XTC_AUTO_RELOAD_OPTION | XTC_CSR_LOAD_MASK |
                        XTC_CSR_EXT_GENERATE_MASK | XTC_CSR_DOWN_COUNT_MASK);
                XTmrCtr_Start(&TimerInst_0, 0);
                MAILBOX_CMD_ADDR = 0x0;
                break;

            case GENERATE_N_TIMES:
                // tri-state control negated so output can be driven
                Xil_Out32(XPAR_GPIO_0_BASEADDR+0x08,0);
                // bits 7:0 number of times, rest is period
                GenerateValue=MAILBOX_DATA(0)>>8;
                NumberOfTimes=MAILBOX_DATA(0) & 0xff;
                XTmrCtr_SetResetValue(&TimerInst_0, 0, GenerateValue);
                XTmrCtr_SetOptions(&TimerInst_0, 0,
                        XTC_AUTO_RELOAD_OPTION | XTC_CSR_LOAD_MASK |
                        XTC_CSR_EXT_GENERATE_MASK | XTC_CSR_DOWN_COUNT_MASK);
                XTmrCtr_Start(&TimerInst_0, 0);
                while(NumberOfTimes){
                    // wait for NumberOfTimes to count down to 0
                    status=XTmrCtr_ReadReg(XPAR_TMRCTR_0_BASEADDR, 0, TCSR0);
                    if(status & 0x100){
                        // wait for the asserted edge, reset the flag
                        XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 0,
                                        TCSR0, status);
                        NumberOfTimes--;
                    }
                }
                XTmrCtr_Stop(&TimerInst_0, 0);
                MAILBOX_CMD_ADDR = 0x0;
                break;

            case EVENT_OCCURED:
                // tri-state control asserted to enable input to capture
                Xil_Out32(XPAR_GPIO_0_BASEADDR+0x08,1);
                // get period value in multiple of 10 ns clock period
                CaptureDuration=MAILBOX_DATA(0);
                /*
                 * Use timer module 0 for event counts
                 * Use timer module 1 for the duration
                 * Load timer 1's Load register
                 */
                XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 1,
                                    TLR0, CaptureDuration);
                /*
                 * 0001 0010 0010 =>  no cascade, no all timers,
                 *                    no pwm, clear interrupt status,
                 *                    disable timer, no interrupt,
                 *                    load timer, hold capture value,
                 *                    disable external capture,
                 *                    disable external generate,
                 *                    down counter, generate mode
                 */
                // clear int flag and load counter
                XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 1, TCSR0, 0x122);
                // enable timer 1 in compare mode, no load counter
                XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 1, TCSR0, 0x082);
                /*
                 * 0001 1000 1001 =>  no cascade, no all timers,
                 *                    no pwm, clear interrupt status,
                 *                    enable timer, no interrupt,
                 *                    no load timer, hold capture value,
                 *                    enable external capture,
                 *                    disable external generate,
                 *                    up counter, capture mode
                 */
                XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 0, TCSR0, 0x189);
                while(1) {
                    if((XTmrCtr_ReadReg(XPAR_TMRCTR_0_BASEADDR, 1,
                                        TCSR0) & 0x100)){
                        // if duration over then get out, disable counter 1
                        XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 1,
                                            TCSR0, 0x100);
                        MAILBOX_DATA(0)=0;
                        break;
                    }
                    if((XTmrCtr_ReadReg(XPAR_TMRCTR_0_BASEADDR, 0,
                                        TCSR0) & 0x100)){
                        // wait for the asserted edge, disable counter 0
                        XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 0,
                                            TCSR0, 0x100);
                        MAILBOX_DATA(0)=1;
                        break;
                    }
                }
                MAILBOX_CMD_ADDR = 0x0;
                break;

            case COUNT_EVENTS:
                // tri-state control asserted to enable input to capture
                Xil_Out32(XPAR_GPIO_0_BASEADDR+0x08,1);
                // get period value in multiple of 10 ns clock period
                CaptureDuration=MAILBOX_DATA(0);
                count=0;
                /*
                 * Use timer module 0 for event counts
                 * Use timer module 1 for the duration
                 * Load timer 1's Load register
                 */
                XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 1,
                                    TLR0, CaptureDuration);
                /*
                 * 0001 0010 0010 =>  no cascade, no all timers, no pwm,
                 *                    clear interrupt status, disable timer,
                 *                    no interrupt, load timer,
                 *                    hold capture value,
                 *                    disable external capture,
                 *                    disable external generate,
                 *                    down counter, generate mode
                 */
                // clear int flag and load counter
                XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 1, TCSR0, 0x122);
                // enable timer 1 in compare mode, no load counter
                XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 1, TCSR0, 0x082);
                /* 0001 1000 1001 =>  no cascade, no all timers, no pwm,
                 *                    clear interrupt status, enable timer,
                 *                    no interrupt, no load timer,
                 *                    hold capture value,
                 *                    enable external capture,
                 *                    disable external generate, up counter,
                 *                    capture mode
                 */
                XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 0, TCSR0, 0x189);
                while(1) {
                    if((XTmrCtr_ReadReg(XPAR_TMRCTR_0_BASEADDR, 1,
                                        TCSR0) & 0x100)){
                        // if duration over then get out, disable counter 1
                        XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 1,
                                        TCSR0, 0x100);
                        break;
                    }
                    if((XTmrCtr_ReadReg(XPAR_TMRCTR_0_BASEADDR, 0,
                                        TCSR0) & 0x100)){
                        // wait for the asserted edge
                        XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 0,
                                        TCSR0, 0x189);
                        count++;
                    }
                }
                MAILBOX_DATA(0)=count;
                MAILBOX_CMD_ADDR = 0x0;
                break;

            case MEASURE_PERIOD:
                // tri-state control asserted to enable input to capture
                Xil_Out32(XPAR_GPIO_0_BASEADDR+0x08,1);
                /*
                 * Use timer module 0 for event capture
                 * Use module 1 for the maximum duration
                 */
                count1=0;
                count2=0;
                /*
                 * 0001 1000 1001 =>  no cascade, no all timers, no pwm,
                 *                    clear interrupt status, enable timer,
                 *                    no interrupt, no load timer,
                 *                    hold capture value,
                 *                    enable external capture,
                 *                    disable external generate,
                 *                    up counter, capture mode
                 */
                // clear capture flag and enable capture mode
                XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 0, TCSR0, 0x189);
                // skip high or 1st asserted edge
                while(!(XTmrCtr_ReadReg(XPAR_TMRCTR_0_BASEADDR, 0,
                                        TCSR0) & 0x100));
                // dummy read
                XTmrCtr_ReadReg(XPAR_TMRCTR_0_BASEADDR, 0, TLR0);
                // clear capture flag and enable capture mode
                XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 0, TCSR0, 0x189);
                // wait for 1st asserted edge
                while(!(XTmrCtr_ReadReg(XPAR_TMRCTR_0_BASEADDR, 0,
                                        TCSR0) & 0x100));
                // read counter value
                count1=XTmrCtr_ReadReg(XPAR_TMRCTR_0_BASEADDR, 0, TLR0);
                // reset interrupt flag
                XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 0, TCSR0, 0x189);
                // wait for 2nd asserted edge
                while(!(XTmrCtr_ReadReg(XPAR_TMRCTR_0_BASEADDR, 0,
                                        TCSR0) & 0x100));
                // read counter value
                count2=XTmrCtr_ReadReg(XPAR_TMRCTR_0_BASEADDR, 0, TLR0);
                // clear capture flag and disable
                XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 0, TCSR0, 0x100);
                MAILBOX_DATA(0)=count2-count1;
                MAILBOX_CMD_ADDR = 0x0;
                break;
                
             default:
                MAILBOX_CMD_ADDR = 0x0;
                break;
            }
    }
    return 0;
}