Allen Ng
ENCM 511
Assignment #3/4
Legend: Green -> Nothing to Change
Grey -> Added from what my partner did
Pink -> Explanation of error(s).
Question 0.A)
You’re an engineer that has been teleported back to 1997 when the blackfin processor didn’t exist. However, you’re currently working with analog devices and intel designing “blackfin” even though you have knowledge of how the processor should work. You have been teamed up with a group of other engineers to test the only chip available so no mistakes can be afforded. The company has asked your group to create code that reads the GPIO data register and returns the values of pins 4 to 7. The team is given that SW1 to SW4 are connected to PF4 to PF7 respectively. When everything is written you notice that the FIO_POLAR and FIO_DIR registers were incorrectly set. Which error is more serious, and why?
Answer:
FIO_DIR register because it has potential to burn the chip if the pins aren’t set as input then the chip may burn out as opposed to the FIO_POLAR register. [Correct answer!]
Question 0.B)
You’ve now saved the team from being fired by fixing the registers that were incorrectly set. The company is so impressed with your ability to catch the mistake that you`ve been promoted. You`re now split up from the team and told to write the blackfin code that writes the LED to pins 4 to 7. You’re given that the LED data write register is held at address location 0x20270005.
Answer:
Question 2)
Look at the figure at the bottom of this question and answer the following. Assume that NC’s are 0’s
A. What is wrong with this configuration?
B. When the accelerometer is enabled – what value is in the Direction register
C. Label the PF pins on the schematic as input, output or NC.
D. What value is in the Polar register?
E. If the accelerometers are both off what values are in PF 0 to 11?
Answer:
A. See figure above
B. “To float” means the voltage on the line will be unpredictable – it could be low or high.
C. “Burn out” is when an output pin attempts to control the voltage on a line that is already being controlled by another output pin. Since the line can only have one voltage level, the output pins will fight for control until one or both of the pins destroys itself and “burns out.”
D. The pull up resistors prevent the light sensors from being enabled prematurely by a floating line. The only way either can be enabled is by grounding PF11 or PF0. If a programmer mis-programs the system and grounds both the PF0 and PF 11 lines at the same time, the resistors will not be able to prevent burn out because the PF will have control of the line (because the resistance is so high in the pull up resistors.)
Assignment 3/4
Riley Kotchorek
Question 0.A)
In class we discussed the speed and efficiency of interrupt service routines. Why is it important an ISR completes as fast as possible?
Answer:
An interrupt service routine does just that, interrupts the current task or tasks running on the processor. Because of this, the ISR must return control to the tasks it interrupted as quickly as possible or it risks destroying the integrity of the system.
Question 0.B)
The following C++ code was taken from inside an interrupt service routine. Translate the code into assembly language, keep in mind the ISR code must be as fast and efficient as possible after translation. Assume count is stored in R7 and pointer is stored in P5, all other data and pointer registers are free to be used and *pointer is of type long int. Also assume it takes 15 instructions to call and return from the abs() function and reading data from *pointer requires 4 instructions before the data can be used.
while(count < 10) {
pointer[count] = abs(pointer[count]); //returns the absolute value of pointer[count]
//doesn’t do any other operation
count++;
}
Answer:
newPoint_P4 = pointer_P5 + count_R7;
compare10_R6 = 10;
compare0_R4 = 0;
Loop_Start:
temp_R5 = [newPoint_P4];
CC = count_R7 < compare_R6;
IF CC JUMP Loop_End; //not expected to jump (assuming count starts at 0)
count_R7 += 1; //placed up here to allow more time for temp_R5 to be loaded
CC = compare0_R4 <= temp_R5; //get rid of expensive function call and take the
IF CC JUMP Loop_Start; //absolute value within the ISR itself
temp_R5 = ~temp_R5;
temp_R5 += 1;
[newPoint_P4++] = temp_R5;
JUMP Loop_Start (bp); //expected jump
Loop_End:
Q6. This C++ code is an interrupt service routine which places values from the CYCLES / CYCLES2 counter into an array each time a PF11 interrupt occurs. When 200 values are placed in the array, the interrupts service routine uses a semaphore to signal “main( )” that values are ready for data processing. Translate into “efficient” assembly code using the coding conventions established in this course 15 marks
BLACKFIN ASSEMBLY CODE / C++ CODE // Pseudo code#include “all necessary Blackfin files” to define MMR / volatile unsigned long long int time[201];
volatile unsigned int timeValuesReady = 0;
volatile unsigned short int nextElement = 0;
EX_INTERRUPT_HANDLER(Q3ISR) {
ASSUME THAT THIS CODE BLOCK
IS WRITTEN FOR YOU
AND THAT AT THE END OF
THIS CODE BLOCK
YOU HAVE the 64 bit value timeNow_R6_R7
made up of R6 (low 32-bits) and R7 (high 32-bits)
R7 contains CYCLES2 register value
R6 contains CYCLES register value / unsigned long long int timeNow_R6_R7 ;
// timeNow variable is made up of two register
// R7 for high 32 word and R6 for low 32 bit word
// There is not need to call subroutine – read CYCLES
// registers directly in this order
// Place CYCLES2 register value into R7
// Place CYCLES register value into R6
Fill timeNow variable with CYCLES2 and CYCLES
// Check if ISR is waiting for main( ) to process the data
// if waiting (timeValueReady = 1) then exit ISR
if (timeValuesReady ! = 1) {
time[nextElement] = timeNow_R6_R7;
nextElement++;
if (nextElement == 200) {
timesValueReady = 1;
}
} // end if
*pFIO_FLAG_C = 0x0800;
}
#include <blackfin.h>
.section L1_Data;
.global time;
.global timeValuesReady;
.global nextElement;
.byte4 time[402];
.byte4 timeValuesReady = 0;
.byte2 nextElement = 0;
.section program;
.global _Q3ISR;
#define PF11BIT 0x0800
_Q3ISR:
LINK 16;
[--SP] = (R7:R3; P5:P2);
[--SP] = FP;
[--SP] = ASTAT;
P5.H = hi(timeValuesReady); P5.L = lo(timeValuesReady);
timeValuesReady_R5 = [P5]; //placed up here to value is ready for IF statement
//CODE BLOCK HERE
P4.H = hi(nextElement); P4.L = lo(nextElement);
nextElement_R4 = W[P5](Z); //placed here so value is ready in IF statement
//Put this code in here for padding so R4 and R5 have time to load
//their values
P3.H = hi(FIO_FLAG_C); P3.L = lo(FIO_FLAG_C);
P2.H = hi(time); P3.L = lo(time);
clearInterrupt_R3 = PF11BIT;
W[P3] = clearInterrupt_R3;
temp_R3 = 1;
CC = R5 == R3;
IF CC JUMP IF_END; //will not jump for the first 200 runs hence no (bp)
nextElement_R4 += 1;
W[P4] = nextElement_R4;
nextElement_R 4 -= 1;
nextElement_R4 = nextElement_R4 < 1;
P2 = P2 + nextElement_R4;
[P2++] = high_R7;
[P2] = low_R6;
valueReadyCheck_R7 = 400;
nextElement_R4 += 2;
CC = nextElement_R4 < valueReadyCheck_R7;
IF CC JUMP EndIfValuesReady (bp); //will jump 200 times for every 1
P5.H = hi(timeValuesReady); P5.L = lo(timeValuesReady);
[P5] = temp_R3;
EndIfValuesReady:
IF_END:
ssync;
ASTAT = [SP++];
FP = [SP++];
(R7:R3; P5:P2) = [SP++];
UNLINK;
_Q3ISR.END:
RTI;