Developer Home Contents Search Contact Us Support Intel(r)

8XC196KB/KC/KD: Using the High Speed Input

Sean Baartmans
Applications Support
Intel Corporation
Article ID#

For additional information about the HSI, refer to the 8XC196KC/8XC196KD User's Manual or the ApBUILDER software.

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.

Overview of the HSI

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 HSI Events

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.

Using the PTS to Service the HSI

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.

Table 1. PTS Control Block
for HSI Mode


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.

Table 2. 196KC/KD Interrupt Vector Sources and Locations
Interrupt Source(s)Interrupt Vector
PTS Vector
INT14HSI FIFO FullHSI Sixth Entry203CH205CH
INT10HSI FIFO 4HSI FIFO Fourth Entry2034H2054H
INT02HSI Data AvailHSI Sixth Entry or HSI Holding Register Loaded2004H2044H

Using Standard Interrupts to Service HSI

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.

Initialization of Registers

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.

  1. Decide how many HSIs that you are going to be using.
  2. Decide on an algorithm for reading the HSI events. You should decide on which type of interrupt you are going to use (HSI Data Available, HSI 4th Entry, or HSI FIFO Full). Also decide whether or not to use the Peripheral Transaction Server to service the interrupts.
  3. Initialize the HSI by writing to the appropriate SFRs (listed in this document). Also make sure when writing to these SFRs that you are in the appropriate horizontal window.
  4. If using the PTS, write the appropriate values to the PTS Control Block.
  5. Initialize the serial port if you are planning to use this to transmit the HSI results.
  6. Write the appropriate code into your Interrupt Service Routine(s). Make sure that you have written the locations of the interrupts into the appropriate vector locations.
  7. Locate code into appropriate areas of memory. (Start main code at 2080H in your own system.)
  8. Run code.

* Legal Information © 1999 Intel Corporation