Lab2 - Infrared Wireless Human Response Measuring System

Lab 2 - Infrared Wireless Human Response Measuring System

AbstractIn Lab2 we are going to deal we are going to measure Human Visual response time. Your Response will initiate External Interrupt and inside our code Timer will calculate the time elapsed between glowing of LED and your pressing of Switch. Through this project we are going to understand application of Interrupts and Timers in real time world which is very crucial to understand for almost any application in Embedded world.

1. Introduction

In Human Visual response system all we need is introduce some Visual change in for which user can give response. The visual change we introduced is through glowing of LED we are provided on our ARM kit. Next we need to understand about the whole process of handling and Interrupt, which we are going to discuss in brief here. Finally we can estimate the human response by any of the following method:

    1. RTC
    2. Watch Dog Timer
    3. PWM timers.

We are going to use PWM timer in our application. Watch Dog Timers are also almost same in usage.

2. Methodology

In our designing of project knowledge of handling Interrupts and Timers is very crucial. Moreover somewhat familiarity with Schematics is also helpful. In this section we are going to discuss about these topics in brief.

2.1 Interrupts

  • The Interrupts in our board are controlled with the help of Interrupt controller. The interrupt controller in S3C44B0X receives the request from 30 interrupt sources. These interrupt sources are provided by internal peripherals such as the DMA controller, UARTand SIO, etc. In these interrupt sources, the four external interrupts (EINT4/5/6/7) are 'OR'ed to the interrupt controller. We are going to make use of these External Interrupts in our application. The role of the interrupt controller is to ask for the FIQ or IRQ interrupt request to the ARM7TDMI core after making the arbitration process when there are multiple interrupt requests from internal peripherals and external interrupt request pins.
  • Originally, ARM7TDMI core only permits the FIQ or IRQ interrupt, which is the arbitration process based on priority by software. For example, if you define all interrupt source as IRQ (Interrupt Mode Setting), and, if there are 10 interrupt requests at the same time, you can determine the interrupt service priority by reading the interrupt pending register, which indicates the type of interrupt request that will occur.
  • This kind of interrupt process requires a long interrupt latency until to jump to the exact service routine. (The S3C44B0X may support this kind of interrupt processing.)To solve the above-mentioned problem, S3C44B0X supports a new interrupt processing called vectored interrupt mode, which is a general feature of the CISC type micro-controller, to reduce the interrupt latency. In other words, the hardware inside the S3C44B0X interrupt controller provides the interrupt service vector directly.
  • When the multiple interrupt sources request interrupts, the hardware priority logic determines which interrupt should be serviced. At same time, this hardware logic applies the jump instruction of the vector table to 0x18(or 0x1c), which performs the jump to the corresponding service routine.
  • Compared with the previous software method, it will reduce the interrupt latency, dramatically.
  • Selection among these forms of interrupts can be made in software itself with the help of INTCON register.
    • a) INTCON=0x5;
      • This comes out to be IRQ interrupts enabled and non vectored source of interrupt.
    • b) INTMOD =0x0;
      • I set INTMOD equal to zero so that every interrupt is IRQ mode.
    • c) INTMSK
      • In our application we are going to unmask global, EINT4567, INT_TIMER2 interrupts by clearing them bitwise.
    • d) I_ISPC
  • For clearing the pending interrupt bit set in INT_PND once interrupt is serviced. Because INT_PND is read only.

2.2 PWM Timer

  • The S3C44B0X has six 16-bit timers, each timer can operate in interrupt-based or DMA-based mode. The timers 0, 1, 2, 3 and 4 have the PWM function (Pulse Width Modulation). Timer 5 has an internal timer only with no output pins. Timer 0 has a dead-zone generator, which is used with a large current device. Timer 0 and timer 1 share an 8-bit prescaler; timers 2 & 3 share another 8-bit prescaler; and timers 4 & 5 share the other 8-bit prescaler. We are going to use Timer 2 in our application. Each timer, except timers 4 and 5, has a clock-divider which has 5 different divided signals (1/2, 1/4, 1/8, 1/16, 1/32). Timers 4/5 have 4 divided signals (1/2, 1/4, 1/8, 1/16) and one input TCLK/EXTCLK. Each timer block receives its own clock signals from the clock-divider, which receives the clock from the corresponding 8-bit prescaler.
  • The 8-bit prescaler is programmable and divides the MCLK signal according to the loading value which is stored in TCFG0 and TCFG1 registers. The timer count buffer register (TCNTBn) has an initial value which is loaded into the down-counter when the timer is enabled. The timer compare buffer register (TCMPBn) has an initial value which is loaded into the compare register to be compared with the down-counter value. This double buffering feature of TCNTBn and TCMPBn makes the timer generate a stable output when the frequency and duty ratio are changed. Each timer has its own 16-bit down-counter which is driven by the timer clock. When the down-counter reaches zero,
  • the timer interrupt request is generated to inform the CPU that the timer operation has been completed. When the timer counter reaches zero, the value of corresponding TCNTBn is automatically loaded into the down-counter to
  • continue the next operation. However, if the timer stops, for example, by clearing the timer enable bit of TCONn during the timer running mode, the value of TCNTBn will not be reloaded into the counter. The value of TCMPBn is used for PWM (pulse width modulation). The timer control logic changes the output level when the down-counter value matches the value of the compare register in the timer control logic. Therefore, the compare register determines the turn-on time (or turn-off time) of a PWM output.
  • S3C44B0X PWM Timers have a double buffering feature, which can change the reload value for the next timer operation without stopping the current timer operation. So, although the new timer value is set, a current timer operation is completed successfully. The timer value can be written into TCNTBn (timer counter buffer register) and the current counter value of the timer can be read from TCNTOn (timer count observation register). If TCNTBn is read, the read value is not the current state of the counter but the reload value for the next timer duration. The auto-reload is the operation, which copies the TCNTBn into TCNTn when TCNTn reaches 0. The value, written into TCNTBn, is loaded to TCNTn only when the TCNTn reaches to 0 and auto-reload is enabled. If the TCNTn is 0 and the auto-reload bit is 0, the TCNTn does not operate any further.

Timer Initialization

3 Software formulation and design

3.1 Pseudo code

    1. Include necessary header file and declare two global variables .One for keeping the count of Timer interrupts generated and other to signal the Main body after key is pressed.
    2. Initialize ports.
    3. Initialize UART and select UART 0.
    4. Initialize Interrupt.
    5. Create a “for” loop in the main body of program to get human response input some specific number of times so that we can average them.
    6. Inside the “for” loop we initialize a count variable to count the number of times the timer is reloaded and a flag “JUG” to signal the main “for’ loop that interrupt has been serviced. Otherwise control remains waiting on the flag to become high.
    7. Inside interrupt handler we are disabling the interrupt EINT4567.Then stop the timer. Display the count, clear the pending and enable the interrupts before exiting Interrupt handler.
    8. Process is repeated three times and the count value for each time is added to a local variable.
    9. Take average and display.

3.2 Flow Chart of formulated software ( Main )

3.3 Flow of External Interrupt

3.4 Flow of Timer2 Functioning

4. Implementation

  • C source code is written as given in appendix.
  • Some of the specs of my application during initializing Timer :

BITSCALOR: 255

PRE-DIVIDER: ½

CNTB2 :0021

CMPB2 :0000;

  • Firstly we will test our code on RAM for testing and debugging purpose using HyperTerminal as we did in first lab.
  • Compile and build the source code to form binary image. Load this Binary Image to RAM using HyperTerminal by keeping the settings as :

Baud rate : 115200 kbps

Flow control : None

Now using command “loadb 0x0c008000”

  • Load binary image to RAM using “Kermit” protocol. Execute the image using “go 0x0c0080000”.
  • After the testing of program load it into ROM by changing some of the options under Linker tab of APM:
  • Select Libraries from ARM251 folder (where your Armulator is installed).Then select “Entry and Base” Tab
  • For ROM:

Read only : 0x0000

Read Write : 0x0c008000

  • Then under Image Layout Tab I took Object file as 44binit.o (as my initialization file is 44binit.s) and Area Name as “Init”(as this was entry point into the init code).

Now compile, build your binary image and follow these steps for loading your application to ROM :

  • Copy “flash” folder from Development CD to another folder .Open “2K-NT-XP” and copy your binary image inside it. And edit the “F.BAT” file by changing the name of binary file to our new binary file.
  • Connect flash through our parallel port and run Batch file.
  • Console will appear, stating that your ROM is being written.
  • Wait until SUCCESS appears on console. Now disconnect FLASH from KIT by turning off the kit
  • Reset the kit.

5. Testing & Verification

  • After I loaded RAM with binary image of my project .I noticed that the global variables I am declaring are not functioning as I they should. I was changing there values inside handlers .And the flag “jug” value which I was using as signaling message to my main “for” loop. It was not able to signal the service of External interrupt to it. So in my main control was continuously waiting for setting of flag.
  • Now this was totally I never experienced before. After step by step rigorous debugging I found that when I comment the initialization of SYSCFG register .My program was running perfectly. So according to me there was some class of memory spaces initialized by SYSCFG and my data segment.

6. Conclusion

  • After so many trials with different users normally human visual response was found to be between 170-250 ms. .During the working of Lab 2 I understood working of Interrupts, Timer. After applying Interrupts and Timer I got a feel that how crucial and powerful they are in real world applications.

7. References

[1] S3C44B0X manual on CMPE-242 yahoo group provided by Prof. Harry Li.

APPENDIX A

#include "..\inc\44b.h"
#include "..\inc\44blib.h"
int count,jug;
void TIMER2_int(void);
void EINT_irq(void);
void timer_init(void);
void interrupt_init(void);
void Main()
{


    int k,o,cnt_net=0;
    #if (PLLON==1)
        ChangePllValue(PLL_M,PLL_P,PLL_S);
    #endif
   
   Port_Init();
   Uart_Init(0,115200);
   Uart_Select(0);
   interrupt_init();
    Uart_Printf("\n******THIS IS HUMAN VISUAL RESPONSE SYSTEM   ******\n");
    Uart_Printf("\n\n  You will have to press any key from the four  as soon as you see LED
    glowing\n\n");


//*********** MAIN ROUTINE *********

    for(k=0;k<3;++k)
    {
        jug=0;

count=0;

        Uart_Printf("\n\n\nLed will glow within few Uart_Printf(“  moments...........\n");
        timer_init();
        rPDATC=(rPDATC & 0x1f1)|((0x0 & 0x7)<<1);

Delay(5000*k);

        rPDATC=(rPDATC & 0x1f1)|((0x2 & 0x7)<<1);

rTCON |= 0x00000d000; // autoreload and start //timer 2

while(jug==0); //waiting for key to be pressed

        rPDATC=(rPDATC & 0x1f1) | ((0x0 & 0x7)<<1);
        cnt_net += count;
    }
    Uart_Printf("\n\n\n\nYour average time was ====>%f ms",cnt_net*0.333);
    rINTMSK |=BIT_EINT4567|BIT_TIMER2;
    return;
}
//********timer**************************
void __irq TIMER2_int(void)

{ rINTMSK |=BIT_TIMER2;

count=count+1;

rI_ISPC=BIT_TIMER2; //clearing pending for Timer2

rINTMSK &=~(BIT_TIMER2);

return;

}
//**************************************
//      External Interrupt
//**************************************
void __irq EINT_irq(void)
{
    jug=1;
    rINTMSK |=BIT_EINT4567|BIT_TIMER2;

rTCON &= ~0x1000; // stoppping timer2

    count=0.001*count*20;
    Uart_Printf("This time your count is=%d Uart_Printf(“ms",count);


    rEXTINPND |= 0xf;
    rI_ISPC=BIT_EINT4567;
    //clearing pending bit for EINT 4567
    rINTMSK &=~(|BIT_EINT4567|BIT_TIMER2);
    return;
}
void interrupt_init(void)
{
int p;
pISR_EINT4567=(unsigned int)EINT_irq;
pISR_TIMER2= (unsigned  int)TIMER2_int;
for(p=_RAM_STARTADDRESS;p<(_RAM_STARTADDRESS+0x20);p+=4)
  { 
*((volatileunsigned *)p)=0xEA000000+0x1FFE;
     }
 rINTMSK&=~(BIT_GLOBAL|BIT_TIMER2);rIrINTMSK &=~(BIT_EINT4567);
rINTCON = 0x5;
rINTMOD = 0x0000000;
  return;
}
void timer_init(void)
{

rTCON &=0x00000000;

rTCFG0 |=0x00000100;

rTCFG0 &=0xffff0fff;

rTCFG1 &=0xfffff0ff;

rTCNTB2 |=0x0021;

rTCMPB2 &=0x0000;

rTCON |=0x00002000;

rTCON &=0xffff0fff;

   return;
}