Fan rotation speed calculation and display In this laboratory work you are to write a program in assembly language that would calculate and send out to a VGA monitor the rotation speed (in revolutions per minute) of a cooling fan. All the necessary hardware part has been done for you. The image below illustrates the resulting system: The employed video standard is VESA 800x600 @ 72Hz. In the above implementation, the screen is divided into 10x10 rectangles to form a map with 100 locations (see image below). Each location contains an image (text and digits are stored as images). These images are stored in image ROM and are displayed by the VGA engine. In order to select the right image for the right location, the VGA engine turns to data RAM, where the images are represented by a code in the respective memory cell. Addresses 0 to 99 are reserved for this purpose. It is the responsibility of the application to maintain the data RAM. For example, by writing a value 5 to data RAM address 9 would result in digit 5 appearing in the top right corner of the screen. The fan issues pulses as it rotates. The pulse line is connected to the interrupt input of the picoBlaze processor, so the processor is aware of fan activity. The timer generates a short pulse every second. It is also connected to the interrupt input and is used to measure time periods. When the timer generates a pulse, it also writes a value 1 at address 128 (in decimal) of the data RAM. It then constantly reads the memory at this location and will not generate another pulse, unless it finds a value 0 at location 128. If the applications is willing to receive another pulse from the timer, is should write the value 0 to location 128. Refer to the picoBlaze user guide for details on the instruction set and architecture. A more detailed overview of the system will be given to you during the laboratory exercises. A suggested way of solving the task is described below: 1. Calculate the number of pulses issued by the fan during one second. 2. Convert this value to revolutions per minute (RPM). At this point you should have the required value, but in binary form. 3. Perform binary to binary-coded decimal (BCD) conversion of the obtained value. 4. Send out the BCD value of the rotation speed to the corresponding memory locations. These steps are further described below. 1. Calculate the number of pulses issued by the fan during one second. The fan issues pulses as it rotates, two pulses per revolution to be exact. The fan pulse line is connected to the interrupt input of the processor, so the pulse counter could be part of the code, that defines how the application should handle interrupts. This part of the code is called the interrupt service routine (ISR), and is executed automatically each time an interrupt signal arrives. You can use one of the general purpose registers as a counter and the “add” instruction to increment the counter. The embedded processor used in this work (picoBlaze) is not equipped with a built-in timer, and so an external timer is provided for you, which generates a short pulse every second. Because the processor has only one interrupt input, two lines are connected to it – the fan pulse line and the timer output. In order to distinguish these two signals the port with ID 128 (in decimal) should be tested for a value 1. If the value 1 is present at the port with ID 128, then the interrupt signal was generated by the timer, otherwise by the fan. The interrupt service routine may begin with reading from port 128 and comparing the obtained value with 1. If the comparison succeeds (the two values are equal), then it is time to stop collecting pulses from the fan, and proceed to the next step. If the two values do not match, the pulse counter should be incremented. 2. Convert this value to revolutions per minute (RPM). The fan issues two pulses on every revolution it makes. For example, if 50 pulses are received in one second, then the rotation speed is 50 / 2 = 25 revolutions per second. If the fan speed is constant, it would be logical to assume, that the fan would make 60 times as many revolutions per minute as it does per one second. So in order to find out the fan RPM, one must take the number of pulses per second, divide by two (because of two pulses per revolution) and multiply by sixty. For example, if 50 pulses are received in one second, then the RPM value would be 50 / 2 * 60 = 50 * 30 = 1500 revolutions per minute. In short, it is sufficient to multiply the number of pulses per second by thirty. The picoBlaze processor does not have a multiplication unit, and this operation has to be performed “by hand”. Any method is accepted. The problem is that the picoBlaze is just an 8-bit processor, and any of its registers can hold a value of only up to 255. This requires to employ several registers to store a larger value, and this can make multiplication algorithms difficult to implement. It is therefore allowed to substitute the multiplication by thirty with multiplication by thirty two (figure out for yourself why thirty two is more preferable than thirty in this case). This will result in lowered accuracy, but is allowed for the sake of simplicity. Accurate calculations would definitely give you extra points. At this point you have the RPM value stored in two general-purpose registers in binary form. 3. Perform binary to binary-coded decimal (BCD) conversion of the obtained value The obtained value cannot be directly displayed on the monitor – it has to be converted to BCD format first. This is the most difficult part of the task. You are suggested to use the “shift and add 3” algorithm to perform the conversion. 4. Send out the BCD value of the rotation speed to the corresponding memory locations. The number of thousands should be written to port 41 (in decimal), the number of hundreds – to port 42, and so on. Use the OUTPUT command to do so. A working example is given below: