Sean Baartmans
Applications Support
Intel Corporation
Article ID#
The High Speed Input (HSI) on the 8XC196KC/KD is a relatively simple yet extremely useful peripheral. The HSI is mainly used to monitor events. This in turn can be applied to a variety of applications. It can be used in a simple application such as measuring the speed of an external object, or something a little more complicated such as providing feedback in a motor control application. This document will explain the general operation of the HSI and how to use it to monitor events.
The HSI is a means for the user to associate time values with actual events. The unit can be configured to monitor four different types of events. These events are rising edges, falling edges, both rising and falling edges, or a series of eight consecutive rising edges. This is chosen by writing to the HSI_MODE register. (See page C-17 of the 8XC196KC/8XC196KD User's Manual.) Refer to the HSI block diagram in Figure 1 throughout this section.
Figure 1. High Speed Input (HSI) Peripheral Block Diagram
When an event occurs it gets loaded into a 7´20-bit FIFO queue. Eight state times later, it is loaded into a Holding Register provided that the Holding Register is empty. The user then reads the events by reading the HSI_STATUS and HSI_TIME registers. Events are cleared from the FIFO when the user reads the HSI_TIME register. Care must be taken by the programmer to ensure that HSI_STATUS is read before HSI_TIME, otherwise HSI_STATUS information will be lost. Once an event is cleared, the earliest entry in the FIFO will be loaded into the Holding Register. Depending on where the event is in the FIFO, it can take up to eight state times for this next event to be loaded into the Holding Register. If additional events occur before the Holding Register is cleared, they will be held in the FIFO.
An event that enters an empty FIFO with an empty Holding Register will take eight state times to be loaded into the Holding Register. An event that has been sitting in the FIFO waiting for the Holding Register to be cleared will be loaded immediately.
Reading events can be done in a variety of ways. However, this is almost always done through the use of an interrupt. There are three interrupts that can be used to read HSI events.
The first interrupt is the HSI Data Available interrupt (INT02). This interrupt has two sources. The first interrupt source is triggered when an event is loaded into the Holding Register. Once an event moves from the FIFO to the Holding Register, the HSI Data Available interrupt pending bit will be set. The second interrupt source occurs when the HSI FIFO is full. In this case the interrupt will wait until six entries are entered into the FIFO before the pending bit is set. The source of the HSI Data Available interrupt is selected by IOC1.7. Clearing this bit will select HSI Holding Register Loaded to be the interrupt source, setting the bit will select HSI FIFO Full as the source.
The second type of interrupt used to read HSI events is the HSI FIFO 4 interrupt (INT10). The use of this type of interrupt will allow you to process more than one entry at a time while also minimizing the chance of the FIFO becoming overloaded resulting in a missed event. The interrupt pending bit will be set when a fourth entry is entered into the FIFO.
The third type of interrupt is the HSI FIFO Full interrupt (INT14). This interrupt carries the highest priority of the three. It is the same as the first interrupt when the first is configured for FIFO Full. The interrupt pending bit will be set upon the sixth entry into the FIFO.
Once you have chosen which interrupt best suits your application you must write an appropriate service routine to read the HSI events. You may also decide to use the Peripheral Transaction Server (PTS) to do this for you. This is an efficient means of reading these events without bogging down the CPU with a long interrupt service routine.
The PTS can be used to read events out of the Holding Register faster than a normal interrupt service routine. The PTS should be used when you are using either the HSI Fourth Entry interrupt or the HSI FIFO Full interrupt. This is because the PTS is optimized when you are transferring a block of data from one location to another. When using either INT10 or INT14 you will be transferring such a block.
When an interrupt is configured to be serviced by the PTS, the interrupt will initially vector to the PTS vector. In this location you would have the location of your PTS Control Block. The program will then vector to the PTS control block. The PTS Control Block should be set up something like this.
Unused |
PTSBLOCK = 07H |
Unused |
Unused |
PTSDST (HI) = XXXXH |
PTSDST (LO) = XXXXH |
PTSCON = 6AH |
PTSCOUNT = 0AH |
PTSDST should contain the destination address in memory where you want to store your data. PTSCOUNT will decrement for each PTS cycle until it reaches zero. When this happens the PTS cycle will be complete. Once the PTSCOUNT reaches zero, the end-of-PTS interrupt will be generated. The end-of-PTS will point to the normal Interrupt Service Routine vector. The user should then update his PTS Control Block within this routine. Please refer to Chapter 5 of the 8XC196KC/8XC196KD User's Manual for more details on using interrupts and the PTS.
Interrupt Number | Interrupt Vector | Interrupt Source(s) | Interrupt Vector Location | PTS Vector Location |
INT14 | HSI FIFO Full | HSI Sixth Entry | 203CH | 205CH |
INT10 | HSI FIFO 4 | HSI FIFO Fourth Entry | 2034H | 2054H |
INT02 | HSI Data Avail | HSI Sixth Entry or HSI Holding Register Loaded | 2004H | 2044H |
When using the HSI Holding Register Loaded interrupt, the user should read the HSI within the standard Interrupt Service Routine.
The following is an overview of the steps that need to be taken when using the HSI Data Available interrupt to monitor events and measure the speed of an object. This example is intended to monitor rising edges, make speed calculations, and then transmit the result back through the serial port. The example will be given as a block diagram.
The first thing that we need to do is initialize our serial port and the HSI unit. We will use the serial port in mode 1 and the HSI.0. The following is a list of registers that need to be initialized.
WSR = 00H ;Valid Hwindows are 0, 1, and 15 (selected with WSR0-3) CCB = 0FFH ;16 bit bus width and ready pin controls wait states BAUD_RATE = 8067H ;Bit 15 set to select internal clock source, and baud rate is 9600 ;(corresponds to 8067H in mode 1) HSI_MODE = 01H ;HSI.0 will capture both rising edges. INT_MASK = 05H ;Timer 1 overflow interrupt and HSI Data Available interrupt ;enabled. INT_MASK1 = 00H ;No interrupts enabled in Interrupt Mask 1 IOC0 = 01H ;HSI.0 enabled as High Speed Input IOC1 = 24H ;Timer 1 overflow generates INT00, P2.0 selected for serial ;transmit. IOC2 = 00H ;Timer 1 clocked at normal speed (once every eight state times). IOC3 = 01H ;Clock Timer 1 internally. IOPORT2 = 03H ;P2.0 selected for Transmit, P2.1 selected for Receive. SP_CON = 09H ;Serial Mode 1 selected, RXD enabled.The initialization code should have all of the above settings. The next step is to come up with an algorithm to process the HSI routines. In this case make the HSI routine interrupt driven. When an event comes in we will vector to the HSI Data Available interrupt, do our time measurement calculations, and then transmit the results out via the serial port. In addition, the Timer 1 Overflow will be used for a "17-bit" timer. Therefore, the HSI routine must monitor the additional count done in the timer overflow routine and some other considerations explained below. The following flowchart in Figure 2 describes the general flow of the program.
Figure 2. Example of Main Program Flow
The next step in the design process is to program the interrupt routines accordingly. This can be tricky if the user does not have a firm understanding of the timer overflow and interrupt timing. The following should be taken into account when using both the Overflow and the HSI Data Available interrupts together.
When using the HSI and Timer1 to monitor events it is possible, that if an event came in at FFFFH that the Timer overflow interrupt could occur first which would cause the timing calculation to be incremented. This would only occur if both interrupts are enabled and the user's code has not taken this into account. The following is an explanation and workaround for this.
First of all let's examine the amount of time that it takes for an HSI event to vector to an interrupt. When an event triggers an HSI, it will take a minimum of 8 state times from the time it goes into the FIFO to the time that it enters the holding register. This means that if an event comes in right on the Overflow boundary, it will be at least 8 state times before the corresponding interrupt pending bit is set. The Timer Overflow interrupt will be set right on the overflow boundary. If the current instruction plus the next instruction take less than 8 state times, then the Timer overflow interrupt will be vectored to first.
The workaround for this is done in the HSI interrupt service routine. When you vector to the interrupt service routine, check to see if the HSI Time is equal to FFFFH. If it is, then check to see if the Timer overflow interrupt is pending. If it is not pending, then you know that the timer overflow interrupt has already occurred. Take this into account when you are making your calculations. If the timer overflow interrupt is pending, process your interrupt as normal. The following block diagram in Figure 3 explains the process of servicing an HSI interrupt.
Figure 3. Example HSI Interrupt Service Routine Block Diagram.
The results can be transmitted out via the serial port within the HSI interrupt service routine by writing to the SBUF register in horizontal window 15.
When using the HSI unit to monitor events, the user should follow these steps.
* Legal Information © 1999 Intel Corporation