ts-7000
[Top] [All Lists]

[ts-7000] How to disable irq when I read the free running timer4

To:
Subject: [ts-7000] How to disable irq when I read the free running timer4
From: "danjperron" <>
Date: Mon, 27 Jun 2005 19:50:18 -0000
I create an extended 64 bit version of the free running timer.


But if I want to use it into some threads, I need to ensure that 2
threads reading tc4 will read the correct values;

  No process interrupts the reading of the low 32 bits tc4 and the
high 32 bits tc4 sequence. I just don't want a thread reading tc4  at
the same time than an other one reading the high 32 bits.

  
 check my routine , (inspire from Jesse Off ,messages #10), GetFRTime()


////// FreeRunningTimer.c
  
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/mman.h>
#include<stdio.h>
#include<fcntl.h>

#include "FreeRunningTimer.h"


int FRTimerHandle=-1;

unsigned char *FRTimerBase=NULL;
unsigned long *FRTimerLo=NULL;
unsigned long *FRTimerHi=NULL;

unsigned long FRTimerExtHi=0; // use to go behond 40 bit (extended)



/* InitFRTimer
 * map physical address 
 * return 0 if we can't mapped
 * return 1 if everything ok
 */

int InitFRTimer(void)
{
        FRTimerHandle= open("/dev/mem",O_RDWR);
        if(FRTimerHandle<0) return(0);
        FRTimerBase =
mmap(0,getpagesize(),PROT_WRITE|PROT_READ,MAP_SHARED,FRTimerHandle,0x80810000UL);
        if(FRTimerBase  == NULL)
        {
                CloseFRTimer();
                return(0);
        }
        FRTimerLo=  (unsigned long *) (FRTimerBase + 0x60UL); // get Least
significant long
        
        FRTimerHi=  (unsigned long *) (FRTimerBase + 0x64UL); //  get Most
significant long

    *FRTimerHi=0x100;  // start Timer           
    return(1);
}


/*  CloseFRTimer
 *  release map of physical address
 */

void CloseFRTimer(void)
{

   if(FRTimerHandle>=0)
   {
           if(FRTimerBase)      
           munmap(FRTimerBase,getpagesize());
           close(FRTimerHandle);
   }
    FRTimerHandle=-1;
        FRTimerBase=NULL;
        FRTimerLo=NULL;
        FRTimerHi=NULL;
}

/* ResetFRTimer
 *  Reset and enable Free running timer
 */
void ResetFRTimer(void)
{
   *FRTimerHi= 0;  
   *FRTimerHi= 0x100; // enable free running Timer
   FRTimerExtHi=0;     // reset extended bit
}


/* GetFRTimer
 *  return current free running timer value
 */


unsigned long long GetFRTimer(void)
{
   // need to be run at least once every 300 hours
   // for the extended bit system to work!

   unsigned long long tval;
   
   unsigned long HiVal;
    
    // need to disable irq here
    //
    //  ??????
    
    tval = *FRTimerLo;
    
    
    HiVal= *FRTimerHi & 0xff;
    
    // need to enable irq here
    //
    //  ?????
    
    
       
    if(HiVal  < (FRTimerExtHi & 0xff))
    {
        // ok we got a wrapped Timer;
        
        FRTimerExtHi += 0x100;  // increment bit 40
    }
        FRTimerExtHi &= ~0xff;
        FRTimerExtHi |= HiVal;
        
      tval |= ((unsigned long long ) FRTimerExtHi) << 32;
    
    return(tval);
}


                

////// FreeRunningTimer.h

#ifndef FREE_RUNNING_TIMER_H
#define FREE_RUNNING_TIMER_H


int InitFRTimer(void);
void CloseFRTimer(void);
void ResetFRTimer(void);
unsigned long long GetFRTimer(void);

#define FRTimerToMs(A)  (((unsigned long long) A) / 984ULL)
#define MsToFRTimer(A)  (((unsigned long long) A) * 984ULL)

//#define FRTimerToMs(A)  ((unsigned long long) A >> 10)
//#define MsToFRTimer(A)  ((unsigned long long) A << 10)

int IsFRTimerPassed(unsigned long long BaseTime,\
                   unsigned long long CurrentTime);
#endif





////A test program to check if the FRTimer works!

#include<stdio.h>
#include<stdlib.h>
#include "freeRunningTimer.h"



#define OUTPUT_ON 1
#define OUTPUT_OFF 0
 

 void Output(int Value)
 {
        static int phy_out=0; // emulate real output
        unsigned long long tcount;
        
        tcount= GetFRTimer();
        if(phy_out==OUTPUT_ON)
          {
                if(!Value)
                  {
                        phy_out=OUTPUT_OFF; // emulate off
                  printf("Output OFF at  %llu
(ms)\n",FRTimerToMs(tcount));fflush(stdout);
                  }
          }
          else
          {
                if(Value)
                  {
                        
                        phy_out=OUTPUT_ON; // emulate  on 
                  printf("Output ON at %llu
ms\n",FRTimerToMs(tcount));fflush(stdout);
                  }
          }
 }        
        
 
 
 int main(void)
 {
 
    int cycle;
 
    unsigned long long  basecount;
  unsigned long long  currentcount;
 
 
    if(!InitFRTimer())
    {
        printf("Unable to Map Free running Timer\n");
        return(1);
    }   
        
        ResetFRTimer();
        basecount =0;


        for(cycle=0;cycle<5;cycle++)
        {
        printf("cycle %d\n",cycle);fflush(stdout);
        while(1)
        {
                    currentcount = GetFRTimer()- basecount;


            if(FRTimerToMs(currentcount) < 1330ULL) // 1.33 seconds
               Output(OUTPUT_ON);
            else
               Output(OUTPUT_OFF);
               
            if(FRTimerToMs(currentcount) > 5000ULL) // 5 seconds
               {
                 basecount +=  MsToFRTimer(5000ULL);  // basecount to
next cycle
                 break;
               }
        }
        }
        
        
                
        printf("Done\n");
        
        CloseFRTimer();
        
  return(0);
 }
        

   
  









 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/ts-7000/

<*> To unsubscribe from this group, send an email to:
    

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 


<Prev in Thread] Current Thread [Next in Thread>
Admin

Disclaimer: Neither Andrew Taylor nor the University of NSW School of Computer and Engineering take any responsibility for the contents of this archive. It is purely a compilation of material sent by many people to the birding-aus mailing list. It has not been checked for accuracy nor its content verified in any way. If you wish to get material removed from the archive or have other queries about the archive e-mail Andrew Taylor at this address: andrewt@cse.unsw.EDU.AU