Sunday, December 8, 2013

Raspberry Pi Lesson 05



1- Introduction:
        Lesson 5  basically builds on the operating system of lesson4 and the objective of lesson 5 is to show how we can use the SOS, which is a Morse Code ,in order to flashing the ‘ACT’ LED. Morse Code (SOS) is a sequence of three dots, three slashes, then three dots (…---…). Generally, we classify data into a specific type such as text, image, and so, then we store different types of data into their related files. Actually, a computer deals with different types of data in the same manner; they are represented in binary numbers.  This data explanation is also true for Mores Code, so we are going to use a sequence of SOS Mores Code pattern in order to flash “ACT LED. The flashing pattern should be a sequence of three short pulses, three long pulses and finally three more shorts pulses, and after the required delay is over,   this sequence of flashing keeps on forever until disconnecting the Raspberry PI from a proper supply source.

2- Materials and Procedures:
In order to carry this assignment out, there are two types of requirements .The first type is the required equipment and the second one is the software and the operating system.
2.1Equipment:
   1-A Raspberry Pi board (it is a single circuit that considered as a computer which, primary runs on a version of Linux).
   2-A computer uses a Microsoft Windows-based Operating System.
   3- A SD card (it is a memory card).
   4- A power supply.

2.2Software:
1-     Using  the GNU compiler toolchain in order to deal with the architecture
2-     The OS Template File
 (It provides a Makefile script, a Linker script and no assembly code would be provided. Since the compiler needs required instructions in order to create Operating System for the Raspberry Pi, those instructions have been provided by the OS Template file )

2.3 Experimental Procedure




The ARM assembly code for Lesson 5:
main's:

.section .init
.globl _start
_start:

.section .init and .globl _start are directives that instructs the assembler in order to put our assembly code in a section its name is ( .init ).  Because of that, we will be able to control the order of the code execution. Also, the GNU toolchain needs a entry point to work properly, so we need to include symbol _start. Then, we need global, which is required by the linker. Then ( _start:) to start the address of the new line.


In order to branch to the actual main code, we use (b main)

In order to put this code with the rest, we use this command (.section .text) tells the assembler.
main:

Now we are making the stack pointer to point to setting the 0x8000.
mov sp,#0x8000

In order to set the function of GPIO port 16 to be ‘’ACT” LED with (001 base 2 or binary), we use a new SetGpioFunction function.

mov r0,#16
set r0 to pin 16
mov r1,#1
set r1 to pin 1
bl SetGpioFunction

In this block of instructions, our objective to load the pattern into flash and also storing the required position in the flaqsh sequence.
ptrn .req r4
store ptrn in register r4
ldr ptrn,=pattern
load the pattern in r4
ldr ptrn,[ptrn]
seq .req r5
load register r0 in the  register  r5 with ability of always finding the sequence location
mov seq,#0

loop$:
If the pattern contains 0 then the LED will turn on, but if the pattern contains 1 then the LED will turn off.in order to do that, we use the new GPIO 16 base on the current bit.

mov r0,#16
  pin 16 in r0
mov r1,#1
pin 1 in ri
lsl r1,seq
Using logical-shift-left (lsl) to shift r1 to the left by sequence value.
and r1,ptrn
here is condition that states; if there exists 1 bl SetGPIO  ,then r1 holds nonzero value
bl SetGpio.

In order to achieve the delay, we load a value of 250000 micrseconds into the register r0 and that will make the processor busy by counting down from 250000 micrseconds to 0 second.
ldr r0,=250000
bl Wait

When the sequence counter reaches 32 its pattern holds 100000. Then by applying this loop over this process in order to increment the sequence counter  , its pattern holds 11111 makes it return to 0.But all of that has no effect on less than 32.
add seq,#1
and seq,#0b11111
b loop$

.section .data
In order to separate data from instructions, we put (.section .data) at the end of the code and keeping the data in it. So in the case of implementing some security on our operating system, we can control which part that need to be executed apart from the other.

.align 2

In order to be sure that the address of the next line will be multiplied by 2^2, we use the (align 2).

pattern: .int 0b11111111101010100010001000101010

I use this quote from http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok05.html  to describe( pattern: .int 0b11111111101010100010001000101010);

 “The .int command copies the constant after it into the output directly. That means that 111111111010101000100010001010102 will be placed into the output, and so the label pattern actually labels this piece of data as pattern.”
From the previous description, if the output holds a zero values then the LED will be off ,and if the output holds one(1) value then  the LED will be on”ACT” ,or OK.

               push {lr}
               mov r2,pinNum
               .unreq pinNum
               pinNum .req r2
               bl GetGpioAddress
               gpioAddr .req r0


systemtimer's:
              

We need code to deal with the system timer, which is a counter that runs at 1MHz, and that system timer is used to count the difference between two measurements.

In order to return the value of the base address of the System Timer region into register r0, we use GetSystemTimerBase.

.globl GetTimeStamp
GetSystemTimerBase:
               ldr r0,=0x20003000
               mov pc,lr
Loading the address of the system timer (0x20003000) in r0, then move the pc to the value of the lr.

In order to get the current timestamp of the system timer, we use the GetTimeStamp. Then the return will be in register r0 and r1, while r1 is the most significant 32 bits.

.globl GetTimeStamp
GetTimeStamp:
               push {lr}
               bl GetSystemTimerBase
               ldrd r0,r1,[r0,#4]
               pop {pc}
Pushing the ( lr ),then we call the function (GetSystemTimerBase).since the value of  counter is  8 byte  and a register is 4byte,we need to store the value of the counter which is 8 byte into two registers. After that, we pop the pc.

.globl Wait
Wait:
               delay .req r2
               mov delay,r0     
               push {lr}
               bl GetTimeStamp
               start .req r3
               mov start,r0
In order to make a delay, we need to store a specified number of microseconds in r2, and then copy this waiting value from r2 into r0. Pushing the lr, then call the function of (GetTimeStamp).after assigned the register r3, copy the value of r0 into r3.
              
loop$:
                              bl GetTimeStamp
                              elapsed .req r1
                              sub elapsed,r0,start
                              cmp elapsed,delay
                              .unreq elapsed
                              bls loop$
                             
               .unreq delay
               .unreq start
               pop {pc}
Calling the function of (GetTimeStamp), then subtract r3 from r0. Now, we have a condition that compares if the delay not equals elapsed then continue, otherwise, stop. if the elapsed is less than delay ,then continue and delete alias. Finally, pop pc.


GPIO's:
In order to return the base address of the GPIO region in register r0, we use GetGpioAddress.
.globl GetGpioAddress
GetGpioAddress:
               gpioAddr .req r0
               ldr gpioAddr,=0x20200000
               mov pc,lr
               .unreq gpioAddr
Assigned gpioAddr to register r0, and then loading GPIO address in r0. 0x20200000 will be copied into program counter (pc), and then deleting stored GPIO address.

In order to set the function of the GPIO register addressed by r0 to the low 3 bits of r1, we use SetGpioFunction.

.globl SetGpioFunction
SetGpioFunction:
    pinNum .req r0
    pinFunc .req r1
Assigned pinNumt to register r0 and pinFunc to r1.
               cmp pinNum,#53
               cmpls pinFunc,#7
since range is  (from 0 to 53 pins) of GPIO, then using the comparing r0 in order  to set the range
In this the condition; 1-comparing r0 with #53 and if the value is less or equal to 53.
                                       2- r1 with 7 in order to verify if r1 within the 8 function pins .
               movhi pc,lr
In this condition. If the both (1)&(2) are satisfied then do not run, otherwise runs.


               push {lr}
Copy the value in lr into r0.

               mov r2,pinNum
Move GPIO address from r0 to r2.

               .unreq pinNum
Delete the assigned.

               pinNum .req r2
Assigned pinNum to register r2.

               bl GetGpioAddress
Call the function.

               gpioAddr .req r0
Assigned gpioAddr register r0.

functionLoop$:

cmp pinNum,#9
Comparing pinNum, to #9.

subhi pinNum,#10
If the value is greater than 9 then subtract 10 from the pin.

addhi gpioAddr,#4
bhi functionLoop$

 Add 4 to GPIO,then run


add pinNum, pinNum,lsl #1
Logical-left-shift by 1 is equivalent to multiplication by 2 then add the value of r2 (r2*2+r2) .

lsl pinFunc,pinNum
The function value will be shifted by the value of r2.

               mask .req r3
Assigned mask to r3,.

               mov mask,#7     
r3 takes the value of 7,   r3 = 111 (base2).
                                            
lsl mask,pinNum
Shifting r3 left by the value of r2.
Where r3 and the function in r1 have the same position 111.                                                       

.unreq pinNum
Deleting assigned.

mvn mask,mask

 r3 = 11..1100011..11 and the function in r1 have the same position 000 .
              
oldFunc .req r2
 oldFunc  is assigned to register r2.

ldr oldFunc,[gpioAddr]   
Loading the GPIO address into r2.
              
.unreq mask
Deleting assigned.

.unreq oldFunc
Deleting assigned.

              
str pinFunc,[gpioAddr]
store the value of GPIO in pinFunc.
.unreq pinFunc
Deleting assigned.

unreq gpioAddr
Deleting assigned.

pop {pc}

/* NEW
In order to set the GPIO pin addressed (in r0) as high if r1 is not equal to 0 , otherwise, set the GPIO pin addressed as low .we use  SetGpio.
.globl SetGpio
SetGpio:              
    pinNum .req r0
Assinged pinNum  to register r0 .

    pinVal .req r1
Assinged pinVal to register r1.

cmp pinNum,#53
by comparing r0 with 53 ,we set the range  from(0 to 53 pins in GPIO)
              
movhi pc,lr
The return is done when r0 is greater than 53.
push {lr}
mov r2,pinNum 
miving the value from r0 to r2.
    .unreq pinNum
Delete assigned.
              
    pinNum .req r2
Assigned pinNum to register r2.
              
bl GetGpioAddress
Call function.
    gpioAddr .req r0

Assigned gpioAddr to register r0.

pinBank .req r3
Assigned pinBank to register r3.

lsr pinBank,pinNum,#5
Since GPIO has two sets of 4 bytes, we divide the pins numbers by 32 in order to turn pins on and off (32 and 22).

lsl pinBank,#2
Logical-shift-left by 2 is equivalent to multiplication by 4 ,(4 bytes will be multiplied by 4).

add gpioAddr,pinBank
The pin will be on if the 28-10 is added, and the pin will be off if 40-10 is added.

.unreq pinBank
Delete assigned.

and pinNum,#31
pinNum is divided by 32  then the remainder will never be greater than 0-31.
              
setBit .req r3
Assigned   setBit to r3.
              
mov setBit,#1
setBit takes value of 1.
              
lsl setBit,pinNum
Logical-shift-left by 1 for the value of pinNum.
              
.unreq pinNum
Delete assigned.

teq pinVal,#0
Test if the value of pinVal equals to zero.

.unreq pinVal
Delete assigned.
              
streq setBit,[gpioAddr,#40]
Store setBit at 40 away from GPIO if the value of pinVal is equal to zero. As result of that, the pin will be off, and the LED will be on.

strne setBit,[gpioAddr,#28]
Store setBit at 28 away from GPIO if the value of pinVal is not equal to zero. As result of that, the pin will be on, and the LED will be off.

.unreq setBit
.unreq gpioAddr
Delete the two assigned.
               pop {pc}
The value of pc will set back to the value of the lr.


3. Results:










Raspberry Pi :Lesson3 &Lesson4

                                                  Lesson 03
1- Introduction:
       In lesson 3 of Baking PI, we will do similar as we did in lesson 2, which making the ‘ACT’ light to be turning on and off periodically. However, in this lesson we are going to use a different approach, which is using the function in assembly in order to make more an efficient code. The SetGpio function causing the GPIO pin 16 to be off, so the ACT LED will be on. By considering a certain delay, the SetGpio function causing the GPIO pin 16 to be on, so the ACT LED will be off.

2- Materials and Procedures:
In order to carry this assignment out, there are two types of requirements .The first type is the required equipment and the second one is the software and the operating system.
2.1Equipment:
   1-A Raspberry Pi board (it is a single circuit that considered as a computer which, primary runs on a version of Linux).
   2-A computer uses a Microsoft Windows-based Operating System.
   3- A SD card (it is a memory card).
   4- A power supply.

2.2Software:
1-     Using  the GNU compiler toolchain in order to deal with the architecture
2-     The OS Template File
 (It provides a Makefile script, a Linker script and no assembly code would be provided. Since the compiler needs required instructions in order to create Operating System for the Raspberry Pi, those instructions have been provided by the OS Template file )


2.3 Experimental Procedure



The ARM assembly code for Lesson 3:
GPIO's:
globl GetGpioAddress
       GetGpioAddress:
               ldr r0,=0x20200000
               mov pc,lr
  We need to set the function of  a GPIO by  moving the physical  GPIO address which is (0x20200000) into r0 then  return none.

.globl SetGpioFunction
SetGpioFunction:
               cmp r0,#53
               cmpls r1,#7
               movhi pc,lr

               push {lr}
               mov r2,r0
               bl GetGpioAddress

               functionLoop$:
                              cmp r2,#9
                              subhi r2,#10
                              addhi r0,#4
                              bhi functionLoop$

               add r2, r2,lsl #1
               lsl r1,r2
               str r1,[r0]
               pop {pc}
Since there are 54 pins, we set both the pin and the function within the restricted range (0-53).
Chick for r0 if the pin number in (0-53) and for r1 if the pin in (0-7) .
By storing lr, we can make a method call.
In order to make sure  that r0  would not be overwritten by  the value of a return  function of
GetGpioAddress , we move out the pin from r0 to r2.
In order to find out in what a group that the   required pin in, we use a loop.
Now, by comparing the value of r2 to 9, if the value of r2 is not greater than 9 then the GPIO functions are in the group, otherwise it is not.
Moving the GPIO address in r0 by 4 increments and decrementing r2 by 10.
 The loop will be repeated if did match the right group.
The address that needs to be adjusted is stored In r0 and the offset that needs to adjusted is stored in r2
In each group, there exists 3 status bits for each pin. So, in order to find out what is the required bit offset, the value of r2 will be multiplied by 3.
Since the multiplication is a slow process rather than logical –shift –left(lsl), we  use the (lsl by 1) which gives a similar effect of using the  multiplication  by 2 .eventually the value will be added  again.

  r1 contains the 3 bits that are responsible of setting the pin’s status  and because of that, by using the (lsl) ,we shift the value in r1 bt the value of r2 to the right. Then we return back to the stack because it contains lr.

In order to turn  pin on or off  ,we should figure out  the byte that the  pin is in. 

.globl SetGpio
SetGpio:              
    pinNum .req r0
    pinVal .req r1

               cmp pinNum,#53
               movhi pc,lr
               push {lr}
               mov r2,pinNum 
    .unreq pinNum             
    pinNum .req r2
               bl GetGpioAddress
    gpioAddr .req r0

               pinBank .req r3
               lsr pinBank,pinNum,#5
               lsl pinBank,#2
               add gpioAddr,pinBank
               .unreq pinBank

               and pinNum,#31
               setBit .req r3
               mov setBit,#1
               lsl setBit,pinNum
               .unreq pinNum

               teq pinVal,#0
               .unreq pinVal
               streq setBit,[gpioAddr,#40]
               strne setBit,[gpioAddr,#28]
               .unreq setBit
               .unreq gpioAddr
               pop {pc}
In order to turn pin on or off, we should figure out the byte that the pin is in. 

By using the logical -shift t- the right(lsr) by 5 bits, we will be able to figure out if the pin is in the first set  , which means that if  the pin is <32,so its value is 0, otherwise the pin is in the second set , which means the pin is> 32 and its value is 1. In order to get the required offset to match the correct bank, we use   logical-shift –left (lsl) by 2 and then add it to the GPIO controller.
Since the first set is  (from0 to 31 of 1st  byte ) ,and  the second set is(from 0 to21 of 2nd   byte),so it is essential  that the  register only contains the bit offset. Beside that we know which byte group that we are looking for.



main's:
.section .init
.globl _start
_start:

b main
.section .init and .globl _start are directives that instructs the assembler in order to put our assembly code in a section its name is ( .init ).  Because of that, we will be able to control the order of the code execution. Also, the GNU toolchain needs a entry point to work properly, so we need to include symbol _start. Then, we need global, which is required by the linker. Then ( _start:) to start the address of the new line.


In order to branch to the actual main code, we use (b main)
mov sp,#0x8000
pinNum .req r0
pinFunc .req r1
mov pinNum,#16
mov pinFunc,#1
bl SetGpioFunction
.unreq pinNum
.unreq pinFunc
Moving the stack pointer to the location (0x8000).

Assined  pinNum to register  r0.
Assined pinFunc to register r1.

On GPIO, set the function (from pin 16 ~1) as output.
call function
delete assigned.
 delete assigned.

loop$:
pinNum .req r0
pinVal .req r1
mov pinNum,#16
mov pinVal,#0
bl SetGpio
.unreq pinNum
.unreq pinVal
By setting pin 16 on a low voltage(off) , the LED will be turn on and this can be done by using  
SetGpio function in order to turn off GPIO pin 16.
Assined  pinNum to register  pin 16.
Assined pinVal to register pin 0.
call function.
delete assigned.
 delete assigned.
decr .req r0
mov decr,#0x3F0000
wait1$:
               sub decr,#1
               teq decr,#0
               bne wait1$
.unreq decr
In order to achieve the delay, we need to have a little trick which is making the processor busy by decrementing the number from 0x3F0000 to 0.
pinNum .req r0
pinVal .req r1
mov pinNum,#16
mov pinVal,#1
bl SetGpio
.unreq pinNum
.unreq pinVal
By setting pin 16 on a high voltage(on) , the LED will be turn off and this can be done by using 
SetGpio function in order to turn on GPIO pin 16.
decr .req r0
mov decr,#0x3F0000
wait2$:
               sub decr,#1
               teq decr,#0
               bne wait2$
.unreq decr
In order to achieve the delay, we need to have a little trick which is making the processor busy by decrementing the number from 0x3F0000 to 0.

b loop$
Loop will keep running to keep the LED turning on and off until disconnecting from a proper power supply. 


3. Results:

http://youtu.be/7aLTezbNTa4





_________________________________________________________________________________
         
                                        Lesson 04

1- Introduction:
        Lesson 4 basically builds on the operating system of lesson 3 and the objective of lesson 4 is to show how we can use the system timer in order to flashing the ‘ACT’ LED at a certain or limited interval. The timer has a base address as well as GPIO controller.We need a new code to deal with the system timer, which acts as a counter that runs at 1MHz, and that system timer is used to count the difference between two measurements.
 The “ACT” or ok LED behaves as well as in the lesson 3, but the difference is that we are using the system timer, which sleeps within a specified interval of microseconds then gets up. As a result of that, the LED turns on and off based on the timer two statuses of sleeping and waking up.


2- Materials and Procedures:
In order to carry this assignment out, there are two types of requirements .The first type is the required equipment and the second one is the software and the operating system.
2.1Equipment:
   1-A Raspberry Pi board (it is a single circuit that considered as a computer which, primary runs on a version of Linux).
   2-A computer uses a Microsoft Windows-based Operating System.
   3- A SD card (it is a memory card).
   4- A power supply.

2.2Software:
1-     Using  the GNU compiler toolchain in order to deal with the architecture
2-     The OS Template File
 (It provides a Makefile script, a Linker script and no assembly code would be provided. Since the compiler needs required instructions in order to create Operating System for the Raspberry Pi, those instructions have been provided by the OS Template file )

2.3 Experimental Procedure



The ARM assembly code for Lesson 4:
GPIO;s:
.globl GetGpioAddress
GetGpioAddress:
               gpioAddr .req r0
               ldr gpioAddr,=0x20200000
               mov pc,lr
               .unreq gpioAddr
Loading the GPIO controller address(0x20200000)
In r0  ,then return

.globl SetGpioFunction
SetGpioFunction:
    pinNum .req r0
    pinFunc .req r1
               cmp pinNum,#53
               cmpls pinFunc,#7
               movhi pc,lr

               push {lr}
               mov r2,pinNum
               .unreq pinNum
               pinNum .req r2
               bl GetGpioAddress
               gpioAddr .req r0
Set pinNum in register r0 and pinFunc in register r1. Since there are 54 pins, we set both the pin and the function within the restricted range (0-53).
Chick for r0 if the pin number in (0-53) and for r1 if the pin in (0-7) .
By storing lr, we can make a method call.
In order to make sure  that r0  would not be overwritten by  the value of a return  function of
GetGpioAddress , then storing  it in r0.





functionLoop$:
                              cmp pinNum,#9
                              subhi pinNum,#10
                              addhi gpioAddr,#4
                              bhi functionLoop$

               add pinNum, pinNum,lsl #1
               lsl pinFunc,pinNum

               mask .req r3
               mov mask,#7                                                                  /* r3 = 111 in binary */
               lsl mask,pinNum                                                           
               .unreq pinFunc
               .unreq gpioAddr
               pop {pc}
Now, by comparing the value of pinNum to 9, if the value of pinNum is not greater than 9 then the GPIO functions are in the group, otherwise it is not.
Moving the GPIO address in r0 by 4 increments and decrementing pinNum by 10.
 The loop will be repeated if did match the right group.

The address that needs to be adjusted is stored In r0 and the offset that needs to be adjusted will be stored in pinNum.
In each group, there exists 3 status bits for each pin. So, in order to find out what is the required bit offset, the value of pinNum will be multiplied by 3.
Since the multiplication is a slow process rather than logical –shift –left(lsl), we  use the (lsl by 1) which gives a similar effect of using the  multiplication  by 2 .eventually the value will be added  again.

  pinFunc contains the 3 bits that are responsible of setting the pin’s status  and because of that, by using the (lsl) ,we shift the value in pinFunc bt the value of pinNum to the right. Then we return back to the stack because it contains lr.

In order to turn pin on or off, we should figure out the byte that the pin is in. 

.globl SetGpio
SetGpio:              
    pinNum .req r0
    pinVal .req r1

               cmp pinNum,#53
               movhi pc,lr
               push {lr}
               mov r2,pinNum 
    .unreq pinNum             
    pinNum .req r2
               bl GetGpioAddress
    gpioAddr .req r0

               pinBank .req r3
               lsr pinBank,pinNum,#5
               lsl pinBank,#2
               add gpioAddr,pinBank
               .unreq pinBank

               and pinNum,#31
               setBit .req r3
               mov setBit,#1
               lsl setBit,pinNum
               .unreq pinNum

               teq pinVal,#0
               .unreq pinVal
               streq setBit,[gpioAddr,#40]
               strne setBit,[gpioAddr,#28]
               .unreq setBit
               .unreq gpioAddr
               pop {pc
In order to turn pin on or off, we should figure out the byte that the pin is in. 

By using the logical -shift t- the right(lsr) by 5 bits, we will be able to figure out if the pin is in the first set  , which means that if  the pin is <32,so its value is 0, otherwise the pin is in the second set , which means the pin is> 32 and its value is 1. In order to get the required offset to match the correct bank, we use   logical-shift –left (lsl) by 2 and then add it to the GPIO controller.
Since the first set is  (from0 to 31 of 1st  byte ) ,and  the second set is(from 0 to21 of 2nd   byte),so it is essential  that the  register only contains the bit offset. Beside that we know which byte group that we are looking for.


main's:
.section .init
.globl _start
_start:
 .section .init and .globl _start are directives that instructs the assembler in order to put our assembly code in a section its name is ( .init ).  Because of that, we will be able to control the order of the code execution. Also, the GNU toolchain needs a entry point to work properly, so we need to include symbol _start. Then, we need global, which is required by the linker. Then ( _start:) to start the address of the new line.


In order to branch to the actual main code, we use (b main)
main:
mov sp,#0x8000

mov r0,#16
mov r1,#1
bl SetGpioFunction
Moving the stack pointer to the location (0x8000).
Move r0 to pin 16 and r2 to pin 1
In order to set the function of GPIO pin16 to be ‘ACT’LED with (001) ,we use SetGpioFunction function.

loop$:
mov r0,#16
mov r1,#0
bl SetGpio
In order to turn on the LED, we need to bring down the voltage at the pin 16 in GPIO controller to low status or level, and to do that we are going to use the SetGpio function.

ldr r0,=100000
bl Wait
In order to achieve the delay, we load the value of
 100000 micro seconds in r0 ,then that will make the light to flash 5 times/sec
mov r0,#16
mov r1,#1
bl SetGpio
By setting pin 16 on a high voltage (on) , the LED will be turn off and this can be done by using  SetGpio function in order to turn on GPIO pin 16.
ldr r0,=100000
bl Wait
b loop$
In order to achieve the delay, we load the value of
 100000 micro seconds in r0, then that will make the light to flash 5 times/sec.
Loop will keep running to keep the LED turning on and off until disconnecting from a proper power supply.



systemtimer's:
              

We need code to deal with the system timer, which is a counter that runs at 1MHz, and that system timer is used to count the difference between two measurements.

In order to return the value of the base address of the System Timer region into register r0, we use GetSystemTimerBase.

.globl GetTimeStamp
GetSystemTimerBase:
               ldr r0,=0x20003000
               mov pc,lr
Loading the address of the system timer (0x20003000) in r0, then move the pc to the value of the lr.

In order to get the current timestamp of the system timer, we use the GetTimeStamp. Then the return will be in register r0 and r1, while r1 is the most significant 32 bits.

.globl GetTimeStamp
GetTimeStamp:
               push {lr}
               bl GetSystemTimerBase
               ldrd r0,r1,[r0,#4]
               pop {pc}
Pushing the ( lr ),then we call the function (GetSystemTimerBase).since the value of  counter is  8 byte  and a register is 4byte,we need to store the value of the counter which is 8 byte into two registers. After that, we pop the pc.

.globl Wait
Wait:
               delay .req r2
               mov delay,r0     
               push {lr}
               bl GetTimeStamp
               start .req r3
               mov start,r0
In order to make a delay, we need to store a specified number of microseconds in r2, and then copy this waiting value from r2 into r0. Pushing the lr, then call the function of (GetTimeStamp).after assigned the register r3, copy the value of r0 into r3.

              
loop$:
                              bl GetTimeStamp
                              elapsed .req r1
                              sub elapsed,r0,start
                              cmp elapsed,delay
                              .unreq elapsed
                              bls loop$
                             
               .unreq delay
               .unreq start
               pop {pc}
Calling the function of (GetTimeStamp), then subtract r3 from r0. Now, we have a condition that compares if the delay not equals elapsed then continue, otherwise, stop. if the elapsed is less than delay ,then continue and delete alias. Finally, pop pc.



3. Results:


http://youtu.be/avyiiQwRZMs