User Tools

Site Tools



This shows you the differences between two versions of the page.

Link to this comparison view

timer_hardware [2019/05/07 13:19] (current)
hutch created
Line 1: Line 1:
 +==== Background ====
 +The hardware timers that you will access are LogiCORE IP AXI Timer (axi_timer) (v1.03a) provided by Xilinx. Here's a block diagram of the AXI timer taken from the Xilinx documentation. Please refer to the Xilinx documentation for functional details of the AXI timer (see Resources Section below).
 +{{ ::​axitimerblockdiagram2.jpg?​600 }}
 +I inserted three of these into the bit-stream and they are named: timer_0, timer_1, and timer_2, as shown below.
 +{{ threeintervaltimerdiagram.jpg?​600 }} 
 +Here's an excerpt from the ''​xparameters.h''​ file with definitions related to these three timers. As you should recall from Lab 2, the base address is your main concern.
 +**NOTE: Do not copy the code below into your own code. Just include xparameters.h and use the defined values, e.g., XPAR_AXI_TIMER_2_BASEADDR.**
 +<code C>
 +/* Definitions for driver TMRCTR */
 +/* Definitions for peripheral AXI_TIMER_0 */
 +#define XPAR_AXI_TIMER_0_BASEADDR 0x42800000
 +#define XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ 100000000
 +/* Definitions for peripheral AXI_TIMER_1 */
 +#define XPAR_AXI_TIMER_1_BASEADDR 0x42840000
 +#define XPAR_AXI_TIMER_1_CLOCK_FREQ_HZ 100000000
 +/* Definitions for peripheral AXI_TIMER_2 */
 +#define XPAR_AXI_TIMER_2_BASEADDR 0x42880000
 +#define XPAR_AXI_TIMER_2_CLOCK_FREQ_HZ 100000000
 +==== Resources ====
 +These timers are fully described in Xilinx'​s documentation. ​
 +  * {{:​axi_timer_ds764.pdf|Xilinx Timer Documentation}}
 +If the highlighting does not appear, make sure to read at least the following pages: 1, 2-3 (through Characteristics),​ 4-5 (Characteristics),​ 7 (Figure 2), and 11-14 (Register Definitions).
 +==== Overview of Timer Hardware ====
 +The timer hardware is pretty complex and provides lots of functionality. However, we will only use them in their simplest mode as interval timers. As such, you need to carefully study at least the highlighted sections of the Xilinx documentation.
 +As discussed in the manual, the timer consists of two identical sections each containing a 32-bit counter and associated registers. The two counters can be cascaded to form a single 64-bit counter. This is referred to as cascade mode. In cascade mode, almost all of the control is done via a single control register (TCSR0) as the other control registers are mostly ignored in this mode. The counters can be configured to count up or down, you will configure them to count up. This makes the most sense for a simple timer.
 +You will need to access the following registers in the timer hardware:
 +  * TCSR0: this control/​status register is used to control the cascaded 64-bit counter and to load values into the 32-bit counter.
 +  * TCSR1: you will use this control/​status register only to load a 0 into counter 1 to reset it.
 +  * TLR0: you will need to set both 32-bit counters to zero in order to reset the timer. You do this for counter 0 by loading a 0 into this register and loading the contents of TLR0 into the counter.
 +  * TLR1: you load a 0 into this and load the contents of TLR1 into counter 1 to reset it and set it to 0 (just like counter 0).
 +  * TCR0: you read this register to find out the current value of counter 0.
 +  * TCR1: you read this register to find out the current value of counter 1.
 +  - To initialize the counters, you should do the following:
 +    - write a 0 to the TCSR0 register.
 +    - write a 0 to the TCSR1 register.
 +    - set the CASC bit and clear the UDT0 bit in the TCSR0 register (cascade mode and up counting).
 +  - To store a 0 into counter 0, do the following:
 +    - write a 0 into the TLR0 register.
 +    - write a 1 into the LOAD0 bit in the TCSR0.
 +  - To store a 0 into counter 1, do the following:
 +    - write a 0 into the TLR1 register.
 +    - write a 1 into the LOAD1 bit of the TCSR1 register.
 +  - To start the cascaded counter:
 +    - write a 1 to the ENT0 bit of the TCSR0 register. When you do this, you must not disturb the other bits in TCSR0.
 +  - To stop the cascaded counter:
 +    - clear the ENT0 bit in the TCSR0 register. Make sure not to clear out the CASC bit when you do this (or you will need to restore it).
 +=== Additional Notes:===
 +  - After loading the counters with 0s to reset them, you must re-initialize them (see Step 1 above). In particular, make sure that you clear the load bit for both counters.
 +  - The process for reading the two 32-bit counters and reassembling them into a single 64-bit number is described on Page 5 of the documentation.
 +  - Search the ''​xparameters.h''​ file to find out the frequency for the timers. Always use the provided ''#​define''​s as they are provided by ''​xparameters.h''​. Don't use the actual numerical constants.
 +==== Requirements ====
 +  - You must write the ''​intervalTimer.c''​ file.
 +  - You must use ''​intervalTimer.h''​ as given. No modifications are necessary or allowed.
 +  - You must follow the coding standard.
 +  - You must provide the following functions for the three interval timers (see below).
 +  - You must use the Xilinx low-level access functions ''​Xil_In32()''​ and ''​Xil_Out32()''​ to access the registers in the timer hardware. These functions were discussed in a previous lab.
 +  - You must define isr_function() in your code to avoid linking errors. Just use the same empty function from the helloWorld lab.
 +  - Run the the final pass-off code (see below) for the TA to demonstrate the accuracy of your timer. Compare the time printed by the program to your watch to demonstrate accuracy.
 +<code C intervalTimer.h>​
 + * intervalTimer.h
 + *
 + ​* ​ Created on: Apr 2, 2014
 + ​* ​     Author: hutch
 + */
 +// Provides an API for accessing the three hardware timers that are installed
 +// in the ZYNQ fabric.
 +#include <​stdint.h>​
 +// Used to indicate status that can be checked after invoking the function.
 +typedef uint32_t intervalTimer_status_t; ​ // Use this type for the return type of a function.
 +#define INTERVAL_TIMER_STATUS_OK 1        // Return this status if successful.
 +#define INTERVAL_TIMER_STATUS_FAIL 0      // Return this status if failure.
 +// You must initialize the timers before you use them the first time.
 +// It is generally only called once but should not cause an error if it 
 +// is called multiple times.
 +// timerNumber indicates which timer should be initialized.
 +// returns INTERVAL_TIMER_STATUS_OK if successful, some other value otherwise.
 +intervalTimer_status_t intervalTimer_init(uint32_t timerNumber);​
 +// This is a convenience function that initializes all interval timers.
 +// Simply calls intervalTimer_init() on all timers.
 +// returns INTERVAL_TIMER_STATUS_OK if successful, some other value otherwise.
 +intervalTimer_status_t intervalTimer_initAll();​
 +// This function starts the interval timer running.
 +// If the interval timer is already running, this function does nothing.
 +// timerNumber indicates which timer should start running.
 +void intervalTimer_start(uint32_t timerNumber);​
 +// This function stops a running interval timer.
 +// If the interval time is currently stopped, this function does nothing.
 +// timerNumber indicates which timer should stop running.
 +void intervalTimer_stop(uint32_t timerNumber);​
 +// This function is called whenever you want to reuse an interval timer.
 +// For example, say the interval timer has been used in the past, the user
 +// will call intervalTimer_reset() prior to calling intervalTimer_start().
 +// timerNumber indicates which timer should reset.
 +void intervalTimer_reset(uint32_t timerNumber);​
 +// Convenience function for intervalTimer_reset().
 +// Simply calls intervalTimer_reset() on all timers.
 +void intervalTimer_resetAll();​
 +// Runs a test on a single timer as indicated by the timerNumber argument.
 +// Returns INTERVAL_TIMER_STATUS_OK if successful, something else otherwise.
 +intervalTimer_status_t intervalTimer_test(uint32_t timerNumber);​
 +// Convenience function that invokes test on all interval timers.
 +// Returns INTERVAL_TIMER_STATUS_OK if successful, something else otherwise.
 +intervalTimer_status_t intervalTimer_testAll();​
 +// Use this function to ascertain how long a given timer has been running.
 +// Note that it should not be an error to call this function on a running timer
 +// though it usually makes more sense to call this after intervalTimer_stop() has
 +// been called.
 +// The timerNumber argument determines which timer is read.
 +double intervalTimer_getTotalDurationInSeconds(uint32_t timerNumber);​
 +#endif /* INTERVALTIMER_H_ */
 +The functions that accept a timerNumber argument operate on a single timer. The timer number must be: 0, 1, or 2. Anything else should generate an error message. The intervalTimer_initAll(),​ intervalTimer_resetAll(),​ and intervalTimer_testAll() operate on all three timers. intervalTimer_getTotalDurationInSeconds() reads the 64-bit value from the timer and returns the number of seconds that have transpired since the counter was last reset and started.
 +intervalTimer_test() needs to see if the timers are working. In my code, I check things by:
 +  - I reset the counter and see if it is reset by reading it.
 +  - I start the counter and read it a couple of times to see if it is actually changing value.
 +  - I stop the counter and read it a couple of times to see that it is not changing.
 +==== Hints and Helps ====
 +  - The register access functions that you wrote for Lab 2 could be used here with little or no modification.
 +  - It is considered good practice to wrap the low-level I/O functions (''​Xil_In32(),​ Xil_Out32()''​) inside a helper function as demonstrated in the code provided for the buttons/​switches lab. 
 +  - It is considered very poor practice to expose these low-level I/O calls throughout your code because your code is less readable, is difficult to port (move to a different system) and is a pain to debug.
 +  - Don't try to use file-names or directories/​folder-names with spaces. The software will let you create them but the Xilinx software cannot handle them.
timer_hardware.txt ยท Last modified: 2019/05/07 13:19 by hutch