For additional information about the High Speed Input, refer to the 8XC196KC/KD User's Manual (order #272238) or ApBUILDER software (order #272216).
The High Speed Input (HSI) is a very powerful peripheral that allows the 8XC196KC/KD to monitor the status of an external digital signal. The HSI can be thought of as a message taker. This message taker records the time that a transition takes place and on what pin (0-3) it occurred. This is very useful for applications such as position tracking, pulse width measurement, frequency counting and phase difference measurement. These applications are used in everything from bar code scanners to motor control to anti-lock brake systems.
The HSI detects the digital transition of electric signals. The HSI can be configured to detect positive transitions, negative transitions, every transition (positive and negative) and every 8th positive transition. All event times are based on Timer 1. All of the events and times are placed in a 7 level FIFO. A FIFO is an acronym for a First In First Out queue. This FIFO holds a 16 bit Timer 1 value and a 4 bit event status value. After this information is moved to the FIFO it is placed in a Holding Register, which is capable of storing 1 level of information. This combination of storage areas creates an 8 level FIFO queue. This allows the HSI to handle a flurry of transitions in a short period of time. Events may occur as fast as once every 9 state times. When using the 8th transition mode, events may occur as fast as eight per 16 state times. Once an event has entered the FIFO, eight state times later it can enter the Holding Register. By reading the HSI_TIME register from the Holding Register the event is cleared from the FIFO. It is important to always read the HSI_STATUS register before the HSI_TIME register otherwise the HSI_STATUS information will be lost.
1 state time = [2/crystal frequency (MHz)]
Registers Involved with the HSI
There are several Special Function Registers (SFRs) that are essential to programming the High Speed Input. In the text that follows some of the key HSI SFRs will be described in detail. Let us begin by discussing the HSI_MODE register.
The HSI_MODE SFR is responsible for selecting the type of event that will trigger a capture. The event type is represented by a two bit number, which is shown above. In program listings 1-4 the HSI_MODE register is configured to scan all 4 channels for positive transitions. Since we are looking for positive transitions only, we need to place 01 into each of the two-bit fields. This task is accomplished by loading 55H into the HSI_MODE SFR.
In the program listings a value of 55H is loaded into IOC0. Bits 1,3,5 and 7 do not concern us in this discussion and can be loaded with 0. Bits 0,2,4 and 6 control whether events are loaded into the HSI FIFO. If each of these bits are set, the HSI is enabled for each channel. If these bits are not enabled, the events are never recognized.
The HSI_STATUS SFR is used to indicate whether an event occurred and the current pin states, on the 4 input pins of the HSI. (NOTE: It is important to always read the HSI_STATUS before reading HSI_TIME so that HSI_STATUS information is not lost.) Bits 0,2,4 and 6 always report whether an event occurred on the HSI pin. If the bits hold a value of 1, a transition has occurred. Bits 1,3,5 and 7 hold the current state of the HSI pin. If the bits hold a 1 the input port is logic level high, otherwise, the port is logic level low. Bits 1,3,5 and 7 can be read even if the HSI pins have not been enabled. This is handy for checking the state of an input at any time.
HSI_TIME is a 16 bit register that holds the time, based on Timer 1, of an HSI event. When HSI_TIME is read the contents of the Holding Register are moved into the HSI_TIME SFR. Each time the HSI_TIME is read, the FIFO is moved up by one level.
In program listings 1 and 2, IOS1 is used to see if the Holding Register has been loaded. By monitoring the status of Bit 7 we can determine if an event has occurred. When bit 7 holds a 0, no transition has occurred, otherwise, bit 7 will alert us to activity on the HSI lines. Another useful bit is the FIFO_FULL bit. When the FIFO holds six or more entries bit 6 will become set. When this bit is set the HSI FIFO Full (INT 14, 203CH) interrupt is generated.
In program listings 3 and 4, IOC1 bit 7 is set to 0. This bit selects the source of the interrupt. In this case we will be using INT 2, (HSI Data Available). By clearing bit 7, an interrupt will be triggered when the HSI Holding Register is loaded (one event has occurred). If bit 7 were set, an interrupt (INT 14) would occur when the 6th entry of the FIFO was loaded. For this discussion we will be focusing on bit 7 alone, because it is the only one that concerns us.
NOTE: When using a Project Builder board make sure bit 5 of IOC1, the serial transmit select, is enabled or communication with the PC's monitor program will become corrupted. One way to avoid corruption is to use AND and OR, instead of LD and ST instructions. Communication becomes corrupted because the serial port transmit interrupt is not generated, which interferes with RISM. RISM is the program that allows the 8XC196KC/KD to communicate with your PC, through the serial port. RISM resides either inside the 8XC196KC/KD, in the OTPROM (One Time Programmable Read Only Memory) or externally in separate EPROMS (Erasable Programmable Read Only Memories).
In the program listings 3 and 4, INT_MASK is loaded with 4H. Bit 2 is the only bit we need to worry about right now. By loading bit 2 with 1 the HSI Data Available interrupt is enabled. When interrupt INT02 occurs, program flow is altered, and the microcontroller will vector to memory location 2004H.
Programming the HSI
There are two different ways of checking for transitions on the HSI lines of the 8XC196KC/KD. One way of checking is to constantly monitor the status of bit 7 in IOS1. This method gets the job done but chews up sometimes costly CPU cycles. This method is demonstrated in program listings 1 and 2. Program listing 1 is written in assembly while listing 2 is written in C. A better way of checking for HSI Data Available, is to generate an interrupt when data enters the Holding Register. This method is demonstrated in program listings 3 and 4. The second method utilizes the CPU more efficiently, thus freeing up the CPU to perform other important tasks. In the following text polling and interrupt programming methods will be discussed.
POLLING: (program listings 1 and 2)
This section describes how to go about setting up registers and coding the HSI. The first SFR we should take a look at is the Stack Pointer (SP). The SP should be loaded with a value when programming in ASM196. In program listings 1 and 3 a value of 100H was used. If you use C196 some of the initialization is already done, so this step is not needed. When reading or writing to the SFRs it is always important to be sure that you are in the correct horizontal window or Hwindow. For example, in order to access IOC0 we should select Hwindow 0. We select this Hwindow by loading the WSR (Window Select Register) with 0. IOC0 is loaded with a value of 55H, which enables HSI lines 0-3. A user definable register, called old_status, is set up to hold the previous value of HSI_STATUS. Old_status is set to 0 upon initialization. This register plays a key role in toggling the output of IOPORT1, on and off, each time the HSI senses a transition. Next we need to tell the HSI what kinds of transitions to sense. In this example we are triggering the HSI on positive transitions, so we must load HSI_MODE with 55H. Now we will poll bit 7 of IOS1 until a value of 1 is detected. We will continuously loop until an HSI transition is received. Once this transition has taken place we XOR HSI_STATUS and old_status. Now we need to update IOPORT1 with old_status. Essentially what this does is toggle the output of IOPORT1 each time one of the HSI lines detects a positive transition. If this program is run on an Intel 8XC196KC/KD Evaluation board or Project Builder board, IOPORT1 drives an LED bank. This means that we can monitor the status of the HSI lines with the LED bank. Lastly HSI_TIME is loaded into the user defined time register. This unloads the FIFO one level. Now we are ready to repeat the cycle again.
INTERRUPTS: (program listings 3 and 4)
Setting up the HSI to generate interrupts is similar to the polling procedure. The difference is when an interrupt is generated, the program flow is altered, unlike the polling situation. For example, the HSI Data Available interrupt causes the microcontroller to vector to interrupt vector location 2004H. At that point a DCW command allows vectoring to the proper interrupt service routine location. (See program listing 3 for specifics.) In program listing 4, which accomplishes this task in C, setting up the interrupt vector location may seem more mysterious. When using C196, setting up the interrupt vector location is done by including the line #pragma interrupt(). In this case, we set our ISR (Interrupt Service Routines) name equal to the number 2. Each interrupt in C196 is associated with a number. For instance, if a software timer interrupt is desired, the name of the ISR is assigned a value of 5. See your C196 user's manual for more information and the values associated with each interrupt.
Once we have set up our interrupt vector location we are ready to begin initialization. To begin coding, we disable all interrupts to make sure they do not occur while we are initializing the HSI. Next we should load the stack pointer with 100H. In order to access the IOC1 SFR we should load WSR with 0 to select Hwindow 0. NOTE: It is important to have the correct Hwindow selected to ensure that you are accessing the proper register. By clearing bit 7, of IOC1, an interrupt is generated when the HSI Holding Register is loaded. We clear bit 7 by ANDing IOC1 with 7FH. This will effectively clear bit 7 and leave all other bits unchanged. Only bit 7 should be cleared. This alleviates the possibility of corrupting serial communications, by inadvertently clearing bit 5. Next we load IOC0 with 55H. This enables HSI lines 0-3. The user defined register old_status needs to be loaded with 0 for initialization purposes. Next we load HSI_MODE with 55H. This allows positive transitions to be captured. INT_MASK, bit 2, must be loaded with a value of 1 to ensure that the HSI Data Available interrupt will occur. Now that the initialization has taken place we can enable the interrupts. While there are no transitions occurring on the HSI channels, we sit in an endless loop. This endless loop simulates other instructions that the processor could be executing. The free time that the processor has now can be used to perform other activities like pulse width calculations, counting, numerical analysis or other system maintenance. Now we are ready to set up the ISR. In assembly we should issue a PUSHA upon entering the ISR and a POPA upon exiting the ISR. In C this is not necessary because this has already taken care of for us. Inside the ISR, we XOR old_status and HSI_STATUS to toggle the HSI status bits every time a transition occurs. At this point we need to move the contents of the user defined register, old_status, into IOPORT1 or the LED bank. Finally we load the user defined register, time, with the contents of HSI_TIME. This unloads the FIFO one level.
PROGRAM LISTINGS: Program listings 1-4 can be found in the files, BTBEVAL.EXE for evaluation boards and, BTBDEVEL.EXE for Project Builder boards on the Intel Bulletin Board Service in the MCS(R) 96 Family / General section.
* Legal Information © 1999 Intel Corporation