Index: trunk/AddOn/TAcq/brpaqu.cc
===================================================================
--- trunk/AddOn/TAcq/brpaqu.cc	(revision 3622)
+++ trunk/AddOn/TAcq/brpaqu.cc	(revision 3623)
@@ -55,4 +55,5 @@
   case BR_FFTOneChan :
   case BR_FFTTwoChan :
+    // Byte swap (sur 8 octets) de l'entete
     // ByteSwap 8 (4->8 Reza/firmware SGDMA) de l'enete 
     for(int ka=0; ka<BRHDRSIZE; ka+=8) {
@@ -63,4 +64,5 @@
     }
 
+    // on reoordonne les coeff FFT et on swappe en mem temps  (Byte-swap sur 8 octets)
     if (fgswap == BR_FFTOneChan) ReorderFFTData(src+HeaderSize(), dst_+HeaderSize(), DataSize());
     else if (fgswap == BR_FFTTwoChan) {
@@ -68,4 +70,5 @@
       ReorderFFTData(src+HeaderSize()+DataSize()/2, dst_+HeaderSize()+DataSize()/2, DataSize()/2);
     }
+    // Byte swap (sur 8 octets) du trailer 
     for(int ka=HeaderSize()+DataSize(); ka<sz_; ka+=8) {
       for(int kb=0; kb<4; kb++) {
@@ -78,6 +81,5 @@
   case BR_FFTOneChan32 :
   case BR_FFTTwoChan32 :
-    // on swappe tout  en attendant le swap general sinon il faut encore crÃ©er une fonctiondifferente de ReorderFFT
-    // swapp du header uniquement
+    // swap du header uniquement : Echange de deux mots de 4 octets
     for(int ka=0; ka<BRHDRSIZE/4; ka+=2) {
       dst32[ka] = src32[ka+1];
@@ -85,5 +87,5 @@
     }
   
-    // on reoordonne et on swappe en mem temps
+    // on reoordonne et on swappe en mem temps (Echange de deux mots de 4 octets)
     if (fgswap == BR_FFTOneChan32) ReorderFFTData32(src+HeaderSize(), dst_+HeaderSize(), DataSize());
     else if (fgswap == BR_FFTTwoChan32) {
@@ -91,5 +93,5 @@
       ReorderFFTData32(src+HeaderSize()+DataSize()/2, dst_+HeaderSize()+DataSize()/2, DataSize()/2);
     }
-    // swap du trailler uniquement
+    // swap du trailler uniquement : Echange de deux mots de 4 octets
     for(int ka=(HeaderSize()+DataSize())/4;ka < sz_/4; ka+=2) {
       dst32[ka] = src32[ka+1];
@@ -99,7 +101,11 @@
   case BR_FFTOneChanNoSwap :
   case BR_FFTTwoChanNoSwap :
-    // on a plus de swapdonc il faut copier dans dst
-    memcpy(dst_, src, sz_); 
-    // on reoordonne et on swappe en mem temps
+    // copie du header uniquement 
+    for(int ka=0; ka<BRHDRSIZE/4; ka++)  dst32[ka] = src32[ka];
+
+    //DEL  on a plus de swapdonc il faut copier dans dst
+    //DEL    memcpy(dst_, src, sz_); 
+
+    // on reoordonne les coeff FFT (pas de swap) 
     if (fgswap == BR_FFTOneChanNoSwap) ReorderFFTDataNoSwap(src+HeaderSize(), dst_+HeaderSize(), DataSize());
     else if (fgswap == BR_FFTTwoChanNoSwap) {
@@ -107,5 +113,7 @@
       ReorderFFTDataNoSwap(src+HeaderSize()+DataSize()/2, dst_+HeaderSize()+DataSize()/2, DataSize()/2);
     }
-    
+    // copie du trailler uniquement : 
+     for(int ka=(HeaderSize()+DataSize())/4;ka < sz_/4; ka++)  dst32[ka] = src32[ka];
+   
     break;
   }  // Fin switch 
@@ -143,22 +151,53 @@
 {
   UInt16 ModAq;
-  printf("Mod Acq %x \n",ModeAcq());
+//DEL  printf("Mod Acq %x \n",ModeAcq());
   ModAq = ((ModeAcq() & 0x30)>> 4);
   return(ModAq);
-  
-}
-
-/* --Methode__ */
-void BRPaquet::Print(ostream & os, int nelt, bool prht)
+}
+
+/* --Methode__ */
+void BRPaquet::SetHDRMarker64(UInt64 htag)
+{
+  *((UInt64*)(dst_+OFFSET)) = htag;
+  return;  	
+}
+
+/* --Methode__ */
+void BRPaquet::SetTRLMarker64(UInt64 ttag)
+{
+  *((UInt64*)(dst_+(sz_-BRTRLSIZE+OFFSET+1))) = 0;	
+  *((UInt64*)(dst_+(sz_-BRTRLSIZE+OFFSET))) = ttag; 
+  return;         	          	   	
+}
+
+/* --Methode__ */
+void BRPaquet::SetFrameCounter(UInt32 fc)
+{
+  UInt32* wp =  (UInt32*)(dst_+(BRFRCPTOFF+OFFSET));
+  *wp = (*wp & 0x0000FFFF) | ((fc<<16) & 0xFFFF0000); 
+  return;         	          	
+}
+
+/* --Methode__ */
+void BRPaquet::SetTimeTag(UInt64 timtag)
+{
+  UInt32* wp =  (UInt32*)(dst_+(BRFRCPTOFF+OFFSET));
+  UInt32 fc = *wp;
+  *((UInt64*)(dst_+(BRTMTAGOFF+OFFSET))) = timtag;
+  *wp = (*wp & 0x0000FFFF) | (fc & 0xFFFF0000);
+  return;         	
+}
+
+/* --Methode__ */
+ostream& BRPaquet::Print(ostream & os, int nelt, bool prht)
 {
   os << endl << "BRPaquet::Print() PaqSz=" << PaquetSize() << " DataSize=" << DataSize() 
-     << " dst_pointer=(hex)" << hex << (unsigned long)dst_ << dec << endl;
+     << " dst_pointer=(hex)" << hex << (unsigned long)dst_ << dec << endl; 
   if (dst_ == NULL) {
     os << " ...NULL paquet " << endl;
-    return; 
+    return os; 
   }
-
-  os << endl << " BR AcqMode: " << ModeAcquisition() << " Channel: " << ChannelID()  << endl;
-
+  os << " BR AcqMode: " << ModeAcquisition() << " Channel: " << ChannelID()  
+     << " FrameCounter=" << FrameCounter() << " FrameDataLen=" << PaqLen() << endl;
   if (TrailerSize() > 0) 
     os << " ...HDRMarker(hex)=" << hex <<  HDRMarker() << " TRLMarker=" << TRLMarker() << dec << endl;
@@ -168,5 +207,6 @@
   tt2 = TimeTag1(); 
   tt1 = TimeTag2();
-  os << " ...TimeTag (hex)=" << hex << "TimeTag()" << " TT1= " << tt1 << " TT2=" << tt2 << dec << endl;
+  os << " ...TimeTag (hex)=" << hex << " TT1= " << tt1 << " TT2=" << tt2 
+     << dec << " ->TimeTag()=" << TimeTag() << endl;
   // os << " ...Position Chariot (hex)= " << hex << PositionChariot() << endl;
   if (nelt > DataSize()/2) nelt = DataSize()/2;
@@ -192,4 +232,5 @@
     }
   }
+  return os;
 }
 
@@ -401,4 +442,6 @@
   lostframes = 0;
   frclst = 0;
+  DefineHDRTag();
+  DefineTRLTag();
 }
 
@@ -407,8 +450,30 @@
 }
 
+UInt64 BRPaqChecker::DefineHDRTag(UInt32 hdr1, UInt32 hdr2)
+{
+  hdrtag_ = (UInt64)hdr1 + ((UInt64)hdr2 << 32);
+  return hdrtag_;
+}
+
+UInt64 BRPaqChecker::DefineTRLTag(UInt32 trl1, UInt32 trl2)
+{
+  trltag_ = (UInt64)trl1 + ((UInt64)trl2 << 32);
+  return trltag_;
+}
+
+
+static int cnt_pb = 0;
 bool BRPaqChecker::Check(BRPaquet& paq)
 {
   totnframes++; 
-  if (paq.HDRMarker() != 0x76543210) return false;
+  if (paq.HDRMarker64() != HDRTag()) return false;
+  if (paq.TRLMarker64() != TRLTag()) return false;
+  /*
+  if (paq.TRLMarker64() != TRLTag()) { 
+    cnt_pb++; 
+    if (cnt_pb < 5) paq.Print();
+    return false;
+  }
+  */
   unsigned int curfc = paq.FrameCounter();
   unsigned int delfc = 0;
@@ -419,4 +484,5 @@
   }
   nframeok++; frclst = curfc; 
+  if (cnt_pb<5) { cnt_pb++; paq.Print(); }
   return true;
 }
@@ -424,5 +490,7 @@
 ostream& BRPaqChecker::Print(ostream& os)
 {
-  os << "BRPaqChecker:  Tot.Nb.Frames.Proc=" << totnframes << " NbFrameOK=" << nframeok 
+  //  os << "BRPaqChecker:  HDRTag=" << hex << HDRTag() << " TRLTag=" << TRLTag() << dec << "\n"
+  //     << " ... Tot.Nb.Frames.Proc=" << totnframes << " NbFrame HDR/TRL OK=" << nframeok 
+  os << "BRPaqChecker: Tot.Nb.Frames.Proc=" << totnframes << " NbFrame HDR/TRL OK=" << nframeok 
      << " LostFrames=" << lostframes 
      << " Loss=" << (double)lostframes*100./(double)totnframes << " %" << endl;
Index: trunk/AddOn/TAcq/brpaqu.h
===================================================================
--- trunk/AddOn/TAcq/brpaqu.h	(revision 3622)
+++ trunk/AddOn/TAcq/brpaqu.h	(revision 3623)
@@ -15,4 +15,6 @@
 using namespace std;
 
+// ------------------------------------------------
+// ----- Classe TwoByteComplex ------
 // On definit une classe TwoByteComplex() pour manipuler une paire de byte 
 // representant partie relle et imaginaire d'un nombre complexe
@@ -44,5 +46,7 @@
 };
 
-// Actuellement apres test Nancay un mot de 4octects est mis avant le header
+// ------------------------------------------------
+
+// OFFSET : au cas ou le firmware reception ajoute des mots avant le header 
 #define OFFSET 0 
 // Taille entete/trailer en octets 
@@ -101,7 +105,9 @@
 class BRPaquet {
  public:
+// Cree d'un objet BRPaquet avec copie/swap depuis src -> dst (si src != NULL)
   BRPaquet(Byte* src, Byte* dst, int paqsz=4096, BRDataFmtConv fgswap=BR_SwapAll);
+// Cree d'un objet BRPaquet de taille paqsz sur la zone dst   
   BRPaquet(Byte* srcdst, int paqsz=4096);
-  //  ~BRPaquet();
+//  ~BRPaquet();
 
   // Acces diverses tailles 
@@ -112,5 +118,5 @@
 
   // Acces differentes zone memoire
-  inline Byte* Data() { return dst_+BRHDRSIZE+OFFSET; }
+  inline Byte* Begin() { return dst_+OFFSET; }
   inline Byte* Data1() { return dst_+BRHDRSIZE+OFFSET; }
   inline Byte* Data2() { return dst_+BRHDRSIZE+(DataSize()/2)+OFFSET; }
@@ -120,23 +126,39 @@
   // Valeurs differentes zones HDR/TRL
   inline UInt32 HDRMarker() {return *((UInt32*)(dst_+OFFSET));}
+  inline UInt32 HDRMarker2() {return *((UInt32*)(dst_+OFFSET+1));}
+  inline UInt64 HDRMarker64() {return *((UInt64*)(dst_+OFFSET));}
+
   inline UInt32 TRLMarker() {return *((UInt32*)(dst_+(sz_-BRTRLSIZE+OFFSET)));}
+  inline UInt32 TRLMarker2() {return *((UInt32*)(dst_+(sz_-BRTRLSIZE+OFFSET+1)));}
+  inline UInt64 TRLMarker64() {return *((UInt64*)(dst_+(sz_-BRTRLSIZE+OFFSET)));}
+
+// Informations diverses sur le paquet/mode d'acquisition
   inline UInt16 ModeAcq()   {return *((UInt16*)(dst_+(BRMODACQOFF+OFFSET)));}
   inline UInt16 ChanId()    {return (( *((UInt16*)(dst_+(BRCHANIDOFF+OFFSET))) & 0x1800)>> 12) ;}
   inline UInt16 ChipId()    {return (( *((UInt16*)(dst_+(BRCHANIDOFF+OFFSET))) & 0xC00)>> 10) ;}
 
+  inline UInt32 FrameCounter()   {return ((*((UInt32*)(dst_+(BRFRCPTOFF+OFFSET))) &0xFFFF0000) >> 16);}
   inline UInt32 TimeTag1()   {return *((UInt32*)(dst_+(BRTMTAGOFF+OFFSET)));}
-  inline UInt32 FrameCounter()   {return ((*((UInt32*)(dst_+(BRFRCPTOFF+OFFSET))) &0xFFFF0000) >> 16);}
   inline UInt32 TimeTag2() {return (*((UInt32*)(dst_+(BRFRCPTOFF+OFFSET))) &0xFFFF);}
+  inline UInt64 TimeTag() {return (*((UInt64*)(dst_+(BRTMTAGOFF+OFFSET))) &0x0000FFFFFFFFFFFFLL);}
 
   inline UInt32 PaqId()     {return *((UInt32*)(dst_+(BRPKTIDOFF+OFFSET)));}
   inline UInt16 PaqLen()    {return *((UInt16*)(dst_+(BRPKTLENOFF+OFFSET)));}
 
-
-  // inline unsigned short PositionChariot() {return *((unsigned short*)(dst_+BRPCOFF+OFFSET));}
-
-  // pour faire un print de la structure
-  void Print(ostream & os, int nelt=8, bool prht=true);
   UInt16  ChannelID();
   UInt16  ModeAcquisition();
+
+  // inline unsigned short PositionChariot() {return *((unsigned short*)(dst_+BRPCOFF+OFFSET));}
+  // Fonctions utiles pour remplir un objet BRPaquet 
+  void SetHDRMarker64(UInt64 htag); 
+  void SetTRLMarker64(UInt64 ttag); 
+  void SetFrameCounter(UInt32 fc);  
+  void SetTimeTag(UInt64 timtag);
+  inline void SetPaqLen(UInt16 len) { *((UInt16*)(dst_+(BRPKTLENOFF+OFFSET))) = len; }
+
+  // pour faire un print de la structure
+  ostream& Print(ostream & os, int nelt=8, bool prht=true);
+  inline ostream& Print(int nelt=8, bool prht=true)
+    { return Print(cout, nelt, prht); }
 
   // fonction appelee par le constructeur pour reordonner les donnees FFT 
@@ -159,4 +181,11 @@
   BRPaqChecker();
   ~BRPaqChecker();
+
+  UInt64 DefineHDRTag(UInt32 hdr1=0x76543210, UInt32 hdr2=0xFEDCBA98);
+  UInt64 DefineTRLTag(UInt32 trl1=0x55555555, UInt32 trl2=0xAAAAAAAA);
+  
+  inline UInt64 HDRTag() { return hdrtag_; }
+  inline UInt64 TRLTag() { return trltag_; }
+
   // Verifie le paquet, renvoie true si OK
   bool Check(BRPaquet& paq);
@@ -168,4 +197,7 @@
   unsigned long long lostframes;    // Nombre totale de frames/paquets perdus 
   unsigned int frclst;         // derniere valeur du frame-counter 
+
+  UInt64 hdrtag_;
+  UInt64 trltag_; 
 };
 
Index: trunk/AddOn/TAcq/makefile
===================================================================
--- trunk/AddOn/TAcq/makefile	(revision 3622)
+++ trunk/AddOn/TAcq/makefile	(revision 3623)
@@ -1,8 +1,9 @@
 include $(SOPHYABASE)/include/sophyamake.inc
 
-all : traidio  tmtfft tstminifits tpciew tbrpaq tmtacq tstrdfits mfits2spec tsok 
+# all : traidio  tmtfft tstminifits tbrpaq tpciew tmtacq tstrdfits mfits2spec tsok 
+all : traidio  tmtfft tstminifits tmtacq tstrdfits mfits2spec tsok 
 
 clean :
-	rm *.o traidio tmtfft tstminifits tpciew tbrpaq tmtacq tstrdfits 
+	rm *.o traidio tmtfft tstminifits tpciew tbrpaq tmtacq tstrdfits mfits2spec 
 	rm mfits2spec tsok *.ppf *.fits 
 
@@ -14,5 +15,5 @@
 
 tmtacq.o : tmtacq.cc racquproc.h racqurw.h racqumem.h
-	$(CXXCOMPILE) -c -o tmtacq.o tmtacq.cc 
+	$(CXXCOMPILE) -c -DNOPCIECARD -o tmtacq.o tmtacq.cc 
 
 racqumem.o : racqumem.cc racqumem.h
Index: trunk/AddOn/TAcq/pciewrap.cc
===================================================================
--- trunk/AddOn/TAcq/pciewrap.cc	(revision 3622)
+++ trunk/AddOn/TAcq/pciewrap.cc	(revision 3623)
@@ -1,50 +1,56 @@
 #include "pciewrap.h"
+#include "brpaqu.h"
+
+#include "racqumem.h"
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <math.h>
-
 #include <iostream>
 
-PCIEWrapper::PCIEWrapper()
+TestPCIWrapperNODMA::TestPCIWrapperNODMA(UInt32 sz) 
+  : PCIEWrapper() , size_(sz)
 {
-// Faire l'initialisation PCI-Express ici
+  data_ = new Byte[size_];
+  frame_counter_ = 0;
+  timetag_ = 0;
+  tottransfer_ = 0;	
 }
 
-PCIEWrapper::~PCIEWrapper()
+TestPCIWrapperNODMA::~TestPCIWrapperNODMA()
 {
-// Faire le nettoyage (liberer memoire ...)
+  delete[] data_;	
 }
 
-
-// Variables pour tests 
-static uint_4 NBytes = 0;
-static uint_4 Choix = 0;
-
-uint_4  PCIEWrapper::NBytesToRead()
+UInt32 TestPCIWrapperNODMA::TransferSize()
 {
-// Lire le registre indiquant le nombre de mots prets a etre lus
-// cad transfere en memoire du PC
-int choix = rand()%5;
-if (choix < 2) {
-  Choix = choix;
-  if (choix == 0)  NBytes = 4096;
-  else NBytes = 5000;
-}
-else {
-  NBytes = 0;
-  Choix = 0;
-}
-return NBytes;  
+  return size_;	
 }
 
-uint_4  PCIEWrapper::Read(uint_1* buff, uint_4 nbytes)
+UInt64 TestPCIWrapperNODMA::TotTransferBytes()
 {
-  if (NBytes == 0)  throw PCIEWException("PCIEWrapper::Read()/Error NBytes==0");
-  if (nbytes > NBytes)  nbytes = NBytes;
-  double dx = (rand()%8+1)*0.05;
-  for(int k=0; k<nbytes; k++)  buff[k] = (uint_1)((1.+sin(dx*k))*100.);
-  if ((Choix == 1) && (nbytes>2000)) 
-    for(int k=1600; k<1900; k++) buff[k] = (uint_1)(128);
-  return nbytes;
+  return tottransfer_;
 }
+
+Byte* TestPCIWrapperNODMA::DoTransferData(int numbuff)
+{
+  frame_counter_ ++;
+  timetag_ = frame_counter_ * size_ / 2;
+  BRPaquet paq(data_, size_);
+  paq.SetHDRMarker64(pchk_.HDRTag());
+  paq.SetTRLMarker64(pchk_.TRLTag());
+  paq.SetFrameCounter(frame_counter_);
+  paq.SetTimeTag(timetag_);
+  paq.SetPaqLen((UInt16)((size_ - BRHDRSIZE - BRTRLSIZE)/4));
+  Byte* bp = paq.Data1();
+  for(UInt32 kk=0; kk<paq.DataSize(); kk++) 
+    bp[kk] = (Byte)(sin(0.0345*kk)*78.+127.5);
+  tottransfer_ += size_;
+  return data_;
+}
+
+void TestPCIWrapperNODMA::PrintStatus(ostream& os) 
+{
+  os << "TestPCIWrapperNODMA::Status, FrameCounter=" << frame_counter_ 
+     << " TimeTag=" << timetag_ << endl;
+}
Index: trunk/AddOn/TAcq/pciewrap.h
===================================================================
--- trunk/AddOn/TAcq/pciewrap.h	(revision 3622)
+++ trunk/AddOn/TAcq/pciewrap.h	(revision 3623)
@@ -1,6 +1,8 @@
 #ifndef  PCIEWRAP_H_SEEN
 #define  PCIEWRAP_H_SEEN
-
+#include "brtypes.h"
 #include "machdefs.h"
+#include "racqumem.h"
+#include "brpaqu.h"
 #include <string>
 
@@ -17,4 +19,5 @@
   explicit PCIEWException(const char * m) { msg = m; }
   explicit PCIEWException(const string& m) { msg = m; }
+  virtual ~PCIEWException() { }
   virtual string const& Msg() const  {return msg;}
   virtual const char* what() {return msg.c_str(); }
@@ -24,18 +27,37 @@
 
 
+// Classe definissant l'interface des operations transfert DMA/PCIExpress 
 class PCIEWrapper {
-public:
-// Constructeur - fait l'initialisation
-          PCIEWrapper(); 
-// destructeur - libere la memoire allouee
-  virtual ~PCIEWrapper();
+ public:
+  // Constructeur - fait l'initialisation
+  PCIEWrapper() { } 
+  // destructeur - libere la memoire allouee
+  virtual ~PCIEWrapper() { } 
 
-// Retourne le nombre d'octets a lire 
-  uint_4  NBytesToRead();
-
-// Lecture du buffer de la carte 
-  uint_4  Read(uint_1* buff, uint_4 nbytes);
+  virtual UInt32 TransferSize() = 0;
+  virtual Byte* DoTransferData(int numbuff=0) = 0;
+  virtual UInt64 TotTransferBytes() = 0;    
+  virtual void PrintStatus(ostream& os) = 0;
 };
 
+// Classe de test Implementant l'interface PCIEWrapper sans DMA 
+class TestPCIWrapperNODMA : public PCIEWrapper {
+public:	
+  TestPCIWrapperNODMA(UInt32 sz);
+  virtual ~TestPCIWrapperNODMA();
+
+  virtual UInt32 TransferSize() ;
+  virtual Byte* DoTransferData(int numbuff=0) ;
+  virtual UInt64 TotTransferBytes() ;    
+  virtual void PrintStatus(ostream& os) ;
+  
+protected:
+  Byte* data_;
+  UInt32 size_;
+  UInt32 frame_counter_;
+  UInt64 timetag_; 	
+  UInt64 tottransfer_;
+  BRPaqChecker pchk_;
+};
 
 #endif
Index: trunk/AddOn/TAcq/racqumem.cc
===================================================================
--- trunk/AddOn/TAcq/racqumem.cc	(revision 3622)
+++ trunk/AddOn/TAcq/racqumem.cc	(revision 3623)
@@ -8,7 +8,8 @@
 
 RAcqMemZoneMgr::RAcqMemZoneMgr(uint_4 nz, uint_4 np, uint_4 psz)
-  :  mex(true), nzones(nz), npaq(np), paqsz(psz), stop_(false)
+  : mex(true), nzones(nz), npaq(np), paqsz(psz), stop_(false)
 {
   St_MemZ st;
+
   st.act = (uint_4)MemZA_None;
   st.stat = (uint_8)MemZS_Free;
@@ -16,8 +17,9 @@
   uint_8 mzsz = npaq*paqsz;
 
-  for(int k=0; k<NbZones(); k++) {
-  	memzones.push_back(new Byte[mzsz] );
-  	states.push_back(st);
-  }	
+   for(int k=0; k<NbZones(); k++) {
+     memzones.push_back(new Byte[mzsz] );
+     states.push_back(st);
+   }
+  
 }
 
@@ -34,29 +36,32 @@
   mex.lock();
   while ((rid < 0)&&(!stop_)) {
-    switch (act) {
-  	  case MemZA_Fill:
-  	    for(int k=0; k<NbZones(); k++) {
-  	      if ((states[k].act == MemZA_None) && 
-  	          ((states[k].stat == MemZS_Free)||(states[k].stat & MemZS_Saved)) ) 
-  	            rid = k; break; 
-  	    }
-  	    if (rid >= 0) { states[rid].act = MemZA_Fill; states[rid].stat = MemZS_Free; }
-  	  break;
-  	  case MemZA_Save:
-  	    for(int k=0; k<NbZones(); k++) {
-  	      if ((states[k].act == MemZA_None) && (states[k].stat & MemZS_Filled) && 
-  	          !(states[k].stat & MemZS_Saved) )  rid = k; break; 
-  	    }
-  	    if (rid >= 0) states[rid].act = MemZA_Save; 
-  	  break;
-  	  case MemZA_Proc:
-  	    for(int k=0; k<NbZones(); k++) {
-  	      if ((states[k].act == MemZA_None) && (states[k].stat & MemZS_Filled) && 
-  	          !(states[k].stat & MemZS_Proc) )  rid = k; break; 
-  	    }
-  	    if (rid >= 0) states[rid].act = MemZA_Proc;   	      	  
-  	  break;
-    }
-    if (rid < 0) mex.wait();
+    switch (act)
+      {
+      case MemZA_Fill:
+	if (rid < 0) for(uint_4 k=0; k<NbZones(); k++) {
+	  if ((states[k].act == MemZA_None) && 
+	      ((states[k].stat == MemZS_Free)||(states[k].stat & MemZS_Saved)) ) 
+	    { rid = k; break; } 
+	}
+	if (rid >= 0) { states[rid].act = MemZA_Fill; states[rid].stat = MemZS_Free; }
+	break;
+      case MemZA_Save:
+	for(uint_4 k=0; k<NbZones(); k++) {
+	  if ((states[k].act == MemZA_None) && (states[k].stat & MemZS_Filled) && 
+	      !(states[k].stat & MemZS_Saved) ) { rid = k; break; } 
+	}
+	if (rid >= 0) states[rid].act = MemZA_Save; 
+	break;
+      case MemZA_Proc:
+	for(uint_4 k=0; k<NbZones(); k++) {
+	  if ((states[k].act == MemZA_None) && (states[k].stat & MemZS_Filled) && 
+	      !(states[k].stat & MemZS_Proc) ) { rid = k; break; } 
+	}
+	if (rid >= 0) states[rid].act = MemZA_Proc;   	      	  
+	break;
+      case MemZA_None:   // MTQ pour supprimer un warning
+	break;
+      }
+    if (rid < 0)  mex.wait();
   }
   mex.unlock();
@@ -66,5 +71,5 @@
 int RAcqMemZoneMgr::FreeMemZone(int id, MemZStatus st)
 {
-  if ((id < 0) || (id >= states.size()))  return 1;
+  if ((id < 0) || (id >= (int)states.size()))  return 1;
   int rc = 0;
   mex.lock();
@@ -114,5 +119,5 @@
   os << "RAcqMemZoneMgr::Print() NbZones=" << NbZones() << " PaqSize()=" << PaqSize()
      << " NbPaquets()=" << NbPaquets() << " ZoneSize()=" << ZoneSize() << endl;
-  for(int k=0; k<states.size(); k++) 
+  for(uint_4 k=0; k<states.size(); k++) 
     os << " [" << k << "] Act=" << states[k].act << " Stat=" << states[k].stat 
        << " NbAct[0..2]=" << states[k].nbact[0] << "," << states[k].nbact[1]
@@ -123,4 +128,5 @@
 void RAcqMemZoneMgr::Stop()
 {
+  //  cout << "RAcqMemZoneMgr::Stop() ........ STOP                          BROADCAST" <<endl; 
   stop_ = true;
   mex.broadcast();
Index: trunk/AddOn/TAcq/racqumem.h
===================================================================
--- trunk/AddOn/TAcq/racqumem.h	(revision 3622)
+++ trunk/AddOn/TAcq/racqumem.h	(revision 3623)
@@ -14,7 +14,7 @@
 #include "sopnamsp.h"
 #include "zthread.h"
-
+// #include "dmamgrintf.h"
 #include "brtypes.h"
-
+#include "pciewrap.h"
 using namespace std;
 
@@ -36,5 +36,5 @@
 class RAcqMemZoneMgr {
 public:
-// Constructeur, nz=Nb de zones, np=Nb de paquets/zone , psz=taille de paquet
+// Constructeur, classe dma, nz=Nb de zones, np=Nb de paquets/zone , psz=taille de paquet
   RAcqMemZoneMgr(uint_4 nz, uint_4 np=1000, uint_4 psz=4096);
   ~RAcqMemZoneMgr();
@@ -49,4 +49,5 @@
   inline uint_4 ZoneSize() { return npaq*paqsz; }
   
+
   // Retourne un MemZone disponible pour une action specifique
   int FindMemZoneId(MemZaction act);
@@ -55,5 +56,5 @@
   // Retourne le pointeur de la zone numero k
   inline Byte* GetMemZone(int id)  {
-    if ((id < 0) || (id >= memzones.size()))  return NULL;
+    if ((id < 0) || (id >=(int) memzones.size()))  return NULL;
     return memzones[id];  
     }
@@ -66,4 +67,5 @@
   ZMutex mex;   
   uint_4 nzones, npaq, paqsz;
+//  DMAMgrInterface &dma_;
   vector< Byte* > memzones;
   vector< St_MemZ > states; 
Index: trunk/AddOn/TAcq/racquproc.cc
===================================================================
--- trunk/AddOn/TAcq/racquproc.cc	(revision 3622)
+++ trunk/AddOn/TAcq/racquproc.cc	(revision 3623)
@@ -4,4 +4,5 @@
 #include <unistd.h>
 #include <fstream>
+#include <signal.h>
 
 #include "pexceptions.h"
@@ -18,17 +19,25 @@
 #include "brpaqu.h"
 #include "minifits.h"
-
+struct sigaction act;
 
 //-------------------------------------------------------
-// Classe thread de traitement 
+// Classe thread de traitement  avec 1 voie par frame
 //-------------------------------------------------------
 
-DataProc::DataProc(RAcqMemZoneMgr& mem, string& path, uint_4 nmean, uint_4 nmax)
+void DataProcSignal(int s)
+{
+  cout <<"............................................... receive CtrlC" << endl;
+
+}
+
+DataProc::DataProc(RAcqMemZoneMgr& mem, string& path, uint_4 nmean, uint_4 step, uint_4 nmax)
   :  memgr(mem) 
 {
   nmax_ = nmax;	
   nmean_ = nmean;
+  step_ = step;
   stop_ = false;	
   path_ = path;	
+  act.sa_handler=DataProcSignal;
 }
 
@@ -36,15 +45,25 @@
 { return (z.real()*z.real()+z.imag()*z.imag()); }
 
+void DataProc::Stop()
+{
+ stop_=true;
+ //  cout <<" DataProc::Stop ... > STOP " << endl;
+}
+
 void DataProc::run()
 {
-  	
+  
+  // sigaddset(&act.sa_mask,SIGINT);  // pour proteger le transfert DMA
+  // sigaction(SIGINT,&act,NULL);  	
   setRC(1);	
   try {
     TimeStamp ts; 
-    cout << " DataProc::run() - Starting " << ts << " NMaxMemZones=" << nmax_ << endl;	
+    cout << " DataProc::run() - Starting " << ts << " NMaxMemZones=" << nmax_ 
+	 << " NMean=" << nmean_ << " Step=" << step_ << endl;	
     char fname[512];
     sprintf(fname,"%s/proc.log",path_.c_str());
     ofstream filog(fname);
     filog << " DataProc::run() - starting log file " << ts << endl;		       
+    filog << " ... NMaxMemZones=" << nmax_ << " NMean=" << nmean_ << " Step=" << step_ << endl;	
 
 // Initialisation pour clcul FFT 
@@ -59,9 +78,11 @@
     spectre.ReSize(cfour.Size());
     
-    fftwf_plan plan = fftwf_plan_dft_r2c_1d(pq.DataSize(), vx.Data(), 
-	  			       (fftwf_complex *)cfour.Data(), FFTW_ESTIMATE); 
+    fftwf_plan plan = fftwf_plan_dft_r2c_1d(vx.Size(), vx.Data(), 
+	  		       	       (fftwf_complex *)cfour.Data(), FFTW_ESTIMATE); 
 
     uint_4 ifile = 0;  			        
+    uint_4 nzm = 0;
     for (uint_4 kmz=0; kmz<nmax_; kmz++) {
+      if (stop_) break;
       int mid = memgr.FindMemZoneId(MemZA_Proc);
       Byte* buff = memgr.GetMemZone(mid);
@@ -72,6 +93,5 @@
       }
       BRPaquet paq0(NULL, buff, paqsz); 
-      uint_4 nzm = 0;
-      for(uint_4 i=0; i<memgr.NbPaquets(); i++) {
+      for(uint_4 i=0; i<memgr.NbPaquets(); i+=step_) {
   	BRPaquet paq(NULL, buff+i*paqsz, paqsz); 
   	Byte min = 255;
@@ -79,13 +99,14 @@
   	    
   	for(sa_size_t j=0; j<vx.Size(); j++) 
-  	  vx(j) = (r_4)(*(paq.Data()+j));
+  	  vx(j) = (r_4)(*(paq.Data1()+j))-127.5;
   	fftwf_execute(plan); 
-        //    ffts_.FFTForward(vx, cfour_);
+	//        ffts_.FFTForward(vx, cfour_);
         for(sa_size_t j=0; j<spectre.Size(); j++) 
           spectre(j) += Zmod2(cfour(j)); 
         nzm++;
       }
-      if (nzm >= nmean_) {
+      if ((nzm >= nmean_) ||(kmz==(nmax_-1))) {
         spectre /= (r_4)(nzm);
+        spectre.Info()["NPaqMoy"] = nzm;
     	sprintf(fname,"%s/spectre%d.ppf",path_.c_str(),(int)ifile);
         POutPersist po(fname);
@@ -114,2 +135,237 @@
   return;
 }   
+
+//---------------------------------------------------------------
+// Classe thread de traitement donnees ADC avec 2 voies par frame
+//---------------------------------------------------------------
+
+DataProc2C::DataProc2C(RAcqMemZoneMgr& mem, string& path, uint_4 nmean, uint_4 step, uint_4 nmax)
+  :  memgr(mem) 
+{
+  nmax_ = nmax;	
+  nmean_ = nmean;
+  step_ = step;
+  stop_ = false;	
+  path_ = path;	
+  act.sa_handler=DataProcSignal;
+}
+void DataProc2C::Stop()
+{
+ stop_=true;
+ // cout <<" DataProc2C::Stop ... > STOP " << endl;
+}
+
+void DataProc2C::run()
+{
+  //   sigaction(SIGINT,&act,NULL);  	
+  setRC(1);	
+  try {
+    TimeStamp ts; 
+    cout << " DataProc2C::run() - Starting " << ts << " NMaxMemZones=" << nmax_ 
+	 << " NMean=" << nmean_ << " Step=" << step_ << endl;	
+    char fname[512];
+    sprintf(fname,"%s/proc.log",path_.c_str());
+    ofstream filog(fname);
+    filog << " DataProc2C::run() - starting log file " << ts << endl;		       
+    filog << " ... NMaxMemZones=" << nmax_ << " NMean=" << nmean_ << " Step=" << step_ << endl;	
+
+// Initialisation pour clcul FFT 
+    TVector< complex<r_4> > cfour;  // composant TF
+    uint_4 paqsz = memgr.PaqSize();
+    BRPaquet pq(NULL, NULL, paqsz); 
+    TVector<r_4> vx(pq.DataSize()/2);
+    vx = (r_4)(0.);
+    FFTPackServer ffts;
+    ffts.FFTForward(vx, cfour);
+    TVector<r_4> spectreV1, spectreV2;
+    spectreV1.ReSize(cfour.Size());
+    spectreV2.ReSize(cfour.Size());
+    
+    fftwf_plan plan = fftwf_plan_dft_r2c_1d(vx.Size(), vx.Data(), 
+	  			       (fftwf_complex *)cfour.Data(), FFTW_ESTIMATE); 
+
+    uint_4 ifile = 0;  			        
+    uint_4 nzm = 0;
+    for (uint_4 kmz=0; kmz<nmax_; kmz++) {
+      if (stop_) break;
+      int mid = memgr.FindMemZoneId(MemZA_Proc);
+      Byte* buff = memgr.GetMemZone(mid);
+      if (buff == NULL) {
+  	cout << " DataProc2C::run()/ERROR memgr.GetMemZone(" << mid << ") -> NULL" << endl;
+  	setRC(2);	
+  	return;	
+      }
+      BRPaquet paq0(NULL, buff, paqsz); 
+      for(uint_4 i=0; i<memgr.NbPaquets(); i+=step_) {
+  	BRPaquet paq(NULL, buff+i*paqsz, paqsz); 
+  	Byte min = 255;
+  	Byte max = 0;
+  	    
+  	for(sa_size_t j=0; j<vx.Size(); j++) 
+  	  vx(j) = (r_4)(*(paq.Data1()+j))-127.5;
+  	fftwf_execute(plan); 
+        //   ffts_.FFTForward(vx, cfour_);
+        for(sa_size_t j=0; j<spectreV1.Size(); j++) 
+          spectreV1(j) += Zmod2(cfour(j));
+ 
+   	for(sa_size_t j=0; j<vx.Size(); j++) 
+ 	  vx(j) = (r_4)(*(paq.Data2()+j))-127.5;
+  	fftwf_execute(plan); 
+        //    ffts_.FFTForward(vx, cfour_);
+        for(sa_size_t j=0; j<spectreV2.Size(); j++) 
+          spectreV2(j) += Zmod2(cfour(j)); 
+
+        nzm++;
+      }
+      if ((nzm >= nmean_) ||(kmz==(nmax_-1))) {
+        spectreV1 /= (r_4)(nzm);
+        spectreV2 /= (r_4)(nzm);
+        spectreV1.Info()["NPaqMoy"] = nzm;
+        spectreV2.Info()["NPaqMoy"] = nzm;
+	{
+    	sprintf(fname,"%s/spectre2C_%d.ppf",path_.c_str(),(int)ifile);
+        POutPersist po(fname);
+        po << PPFNameTag("specV1") << spectreV1; 
+        po << PPFNameTag("specV2") << spectreV2; 
+	}
+        spectreV1 = (r_4)(0.);
+        spectreV2 = (r_4)(0.);
+        nzm = 0;  ifile++; 
+        ts.SetNow();
+        filog << ts << " :  proc file  " << fname << endl;		       
+        cout << " DataProc2C::run() " << ts << " : created file  " << fname << endl;
+      }
+      
+      memgr.FreeMemZone(mid, MemZS_Proc);
+    }
+  }
+  catch (PException& exc) {
+    cout << " DataProc2C::run()/catched PException " << exc.Msg() << endl;
+    setRC(3);	
+    return; 
+  }
+  catch(...) {
+    cout << " DataProc2C::run()/catched unknown ... exception " << endl;
+    setRC(4);	
+    return; 
+  }
+  setRC(0);
+  return;
+}   
+
+
+
+
+//---------------------------------------------------------------
+// Classe thread de traitement donnees FFT avec 2 voies par frame
+//---------------------------------------------------------------
+
+inline r_4 Zmod2TwoByte(TwoByteComplex z) 
+{ return (z.realD()*z.realD()+z.imagD()*z.imagD()); }
+
+DataProcFFT2C::DataProcFFT2C(RAcqMemZoneMgr& mem, string& path, uint_4 nmean, uint_4 step, uint_4 nmax)
+  :  memgr(mem) 
+{
+  nmax_ = nmax;	
+  nmean_ = nmean;
+  step_ = step;
+  stop_ = false;	
+  path_ = path;	
+ act.sa_handler=DataProcSignal;
+}
+void DataProcFFT2C::Stop()
+{
+ stop_=true;
+ // cout <<" DataProcFFT2C::Stop ... > STOP " << endl;
+}
+
+void DataProcFFT2C::run()
+{
+  // sigaction(SIGINT,&act,NULL);  	
+  setRC(1);	
+  try {
+    TimeStamp ts; 
+    cout << " DataProcFFT2C::run() - Starting " << ts << " NMaxMemZones=" << nmax_ 
+	 << " NMean=" << nmean_ << " Step=" << step_ << endl;	
+    char fname[512];
+    sprintf(fname,"%s/proc.log",path_.c_str());
+    ofstream filog(fname);
+    filog << " DataProcFFT2C::run() - starting log file " << ts << endl;		       
+    filog << " ... NMaxMemZones=" << nmax_ << " NMean=" << nmean_ << " Step=" << step_ << endl;	
+
+// Initialisation pour clcul FFT 
+    TVector< complex<r_4> > cfour;  // composant TF
+    uint_4 paqsz = memgr.PaqSize();
+    BRPaquet pq(NULL, NULL, paqsz); 
+ 
+    TVector<r_4> spectreV1(pq.DataSize()/4+1), spectreV2(pq.DataSize()/4+1);    
+
+    uint_4 ifile = 0;  			        
+    for (uint_4 kmz=0; kmz<nmax_; kmz++) {
+      if (stop_ ) break;
+      int mid = memgr.FindMemZoneId(MemZA_Proc);
+      Byte* buff = memgr.GetMemZone(mid);
+      if (buff == NULL) {
+  	cout << " DataProcFFT2C::run()/ERROR memgr.GetMemZone(" << mid << ") -> NULL" << endl;
+  	setRC(2);	
+  	return;	
+      }
+      BRPaquet paq0(NULL, buff, paqsz); 
+      uint_4 nzm = 0;
+      for(uint_4 i=0; i<memgr.NbPaquets(); i+=step_) {
+  	BRPaquet paq(NULL, buff+i*paqsz, paqsz); 
+  	Byte min = 255;
+  	Byte max = 0;
+  	        
+	TwoByteComplex* zz;
+	// Traitement Voie 1
+        zz = (TwoByteComplex*)paq.Data1();
+        spectreV1(0) += zz[0].realD()*zz[0].realD();  // Composante continue, partie reelle uniquement
+        for(sa_size_t j=1; j<spectreV1.Size()-1; j++)  spectreV1(j) += Zmod2TwoByte(zz[j]);
+
+        spectreV1(spectreV1.Size()-1) += zz[0].imagD()*zz[0].imagD();  // Freq. Nyquist a N/2 
+
+	// Traitement Voie 2
+        zz = (TwoByteComplex*)paq.Data2();
+        spectreV2(0) += zz[0].realD()*zz[0].realD();  // Composante continue, partie reelle uniquement
+        for(sa_size_t j=1; j<spectreV2.Size()-1; j++)  spectreV2(j) += Zmod2TwoByte(zz[j]);
+
+        spectreV2(spectreV2.Size()-1) += zz[0].imagD()*zz[0].imagD();  // Freq. Nyquist a N/2 
+
+        nzm++;
+      }
+      if ((nzm >= nmean_) ||(kmz==(nmax_-1))) {
+        spectreV1 /= (r_4)(nzm);
+        spectreV2 /= (r_4)(nzm);
+        spectreV1.Info()["NPaqMoy"] = nzm;
+        spectreV2.Info()["NPaqMoy"] = nzm;
+	{
+    	sprintf(fname,"%s/spectreFFT2C_%d.ppf",path_.c_str(),(int)ifile);
+        POutPersist po(fname);
+        po << PPFNameTag("specV1") << spectreV1; 
+        po << PPFNameTag("specV2") << spectreV2; 
+	}
+        spectreV1 = (r_4)(0.);
+        spectreV2 = (r_4)(0.);
+        nzm = 0;  ifile++; 
+        ts.SetNow();
+        filog << ts << " :  proc file  " << fname << endl;		       
+        cout << " DataProcFFT2C::run() " << ts << " : created file  " << fname << endl;
+      }
+      
+      memgr.FreeMemZone(mid, MemZS_Proc);
+    }
+  }
+  catch (PException& exc) {
+    cout << " DataProcFFT2C::run()/catched PException " << exc.Msg() << endl;
+    setRC(3);	
+    return; 
+  }
+  catch(...) {
+    cout << " DataProcFFT2C::run()/catched unknown ... exception " << endl;
+    setRC(4);	
+    return; 
+  }
+  setRC(0);
+  return;
+}   
Index: trunk/AddOn/TAcq/racquproc.h
===================================================================
--- trunk/AddOn/TAcq/racquproc.h	(revision 3622)
+++ trunk/AddOn/TAcq/racquproc.h	(revision 3623)
@@ -20,11 +20,32 @@
 
 
-//-------------------------------------------------------
-// Classe thread de traitement 
-//-------------------------------------------------------
+//-------------------------------------------------------------------
+// Classe thread de traitement avec 1 voie par frame (donnees brutes)
+//-------------------------------------------------------------------
 class DataProc : public ZThread {
 public:	
-  DataProc(RAcqMemZoneMgr& mem, string& path, uint_4 nmean=1, uint_4 nmax=100);
+  DataProc(RAcqMemZoneMgr& mem, string& path, uint_4 nmean=1, uint_4 step=1, uint_4 nmax=100);
   virtual void run(); 
+  void Stop();
+  inline void STOP() { stop_ = true; }	
+
+protected:
+  RAcqMemZoneMgr& memgr;
+  bool stop_;  
+  uint_4 nmax_;  // Nombre maxi de blocs MemZone traites
+  uint_4 step_;  // 1/step_ frame traite ds chaque bloc
+  uint_4 nmean_;  // Nombre de blocs pour le calcul des moyennes 
+  string path_;  
+  struct sigaction act;	
+};
+
+//---------------------------------------------------------------------
+// Classe thread de traitement avec 2 voies par frame (donnees brutes)
+//---------------------------------------------------------------------
+class DataProc2C : public ZThread {
+public:	
+  DataProc2C(RAcqMemZoneMgr& mem, string& path, uint_4 nmean=1, uint_4 step=1, uint_4 nmax=100);
+  virtual void run(); 
+  void Stop();
   inline void STOP() { stop_ = true; }	
 protected:
@@ -32,8 +53,26 @@
   bool stop_;  
   uint_4 nmax_;  // Nombre maxi de blocs MemZone traites
+  uint_4 step_;  // 1/step_ frame traite ds chaque bloc
   uint_4 nmean_;  // Nombre de blocs pour le calcul des moyennes 
   string path_;  
 };
 
+//---------------------------------------------------------------------
+// Classe thread de traitement donnees FFT avec 2 voies par frame 
+//---------------------------------------------------------------------
+class DataProcFFT2C : public ZThread {
+public:	
+  DataProcFFT2C(RAcqMemZoneMgr& mem, string& path, uint_4 nmean=1, uint_4 step=1, uint_4 nmax=100);
+  virtual void run(); 
+  void Stop();
+  inline void STOP() { stop_ = true; }	
+protected:
+  RAcqMemZoneMgr& memgr;
+  bool stop_;  
+  uint_4 nmax_;  // Nombre maxi de blocs MemZone traites
+  uint_4 step_;  // 1/step_ frame traite ds chaque bloc
+  uint_4 nmean_;  // Nombre de blocs pour le calcul des moyennes 
+  string path_;  
+};
 
 #endif
Index: trunk/AddOn/TAcq/racqurw.cc
===================================================================
--- trunk/AddOn/TAcq/racqurw.cc	(revision 3622)
+++ trunk/AddOn/TAcq/racqurw.cc	(revision 3623)
@@ -10,8 +10,7 @@
 #include <unistd.h>
 #include <fstream>
-
+#include <signal.h>
 #include "pexceptions.h"
 #include "timestamp.h"
-
 
 #include "pciewrap.h"
@@ -19,40 +18,166 @@
 #include "minifits.h"
 
-
+#include "resusage.h" // Pour mesure temps elapsed/CPU ...
+#include "datatable.h" // Pour sauver les entetes de paquet 
+#include <sys/time.h>  // pour gettimeofday
 //-------------------------------------------------------
 // Classe thread de lecture PCI-Express
 //-------------------------------------------------------
 
-PCIEReader::PCIEReader(RAcqMemZoneMgr& mem, uint_4 nmax)
-  :  memgr(mem)
-{
-  nmax_ = nmax;		
-  stop_ = false;	
+PCIEReader::PCIEReader(PCIEWrapper &pciw,uint_4 sizeFrame,uint_4 packSize ,RAcqMemZoneMgr& mem, 
+		       uint_4 nmax, BRDataFmtConv swapall)
+  :   memgr(mem) , pciw_ (pciw)
+{
+  nmax_ = nmax;	
+  swapall_ = swapall;  	// select data swap/format conversion for BRPaquet 
+  stop_ = false;
+  packSize_ = packSize;
+  sizeFr_ =sizeFrame;
+  // Pour la logique de gestion des paquets ds zone memoire
+  mid_ = -2;
+  targ_npaq_ = 0;
+ 
+ max_targ_npaq = memgr.NbPaquets();
+  mmbuf_ = NULL;
+}
+
+bool PCIEReader::MZoneManage(bool fgclean)    // Retourne true si probleme 
+{
+  /* Pour debug 
+  cout << " PCIEReader::MZoneManage() mid_=" << mid_ << " arg_npaq_= " << targ_npaq_  
+       << " max_targ_npaq=" << max_targ_npaq << endl;
+  */
+  if (mid_ >= 0)  memgr.FreeMemZone(mid_, MemZS_Filled);
+  mmbuf_ = NULL;  targ_npaq_ = 0;  mid_ = -2;
+  if (fgclean)  return false;
+  mid_ = memgr.FindMemZoneId(MemZA_Fill);
+  mmbuf_ = memgr.GetMemZone(mid_);
+  if (mmbuf_==NULL) return true;
+  return false;
 }
 
 void PCIEReader::run()
 {
-  cout << " PCIEReader::run() - Starting , NMaxMemZones=" << nmax_ << endl;	
+  struct sigaction act;
+  struct sigaction old_act;
+   //Precision insuffisante  ResourceUsage ru; ru.Update();  // Pour recuperer le temps passe
+  struct timeval tv1, tv2;
+  gettimeofday(&tv1, NULL);
+  
+  try{
+  cout << " PCIEReader::run() - Starting , NMaxMemZones=" << nmax_ 
+       << "memgr.NbPaquets()=" << memgr.NbPaquets() << endl;	
   setRC(1);	
-  PCIEWrapper pciw;	
+
+  uint_4 cpt=0;
+  // sigaddset(&act.sa_mask,SIGINT);  // pour proteger le transfert DMA
+  //sigaction(SIGINT,&act,NULL);  
+	
   uint_4 paqsz = memgr.PaqSize();
-  for (uint_4 kmz=0; kmz<nmax_; kmz++) {
-    int mid = memgr.FindMemZoneId(MemZA_Fill);
-    Byte* buff = memgr.GetMemZone(mid);
-    if (buff == NULL) {
-      cout << " PCIEReader::run()/ERROR memgr.GetMemZone(" << mid << ") -> NULL" << endl;
-      setRC(2);	  	  
-      return;	
-    }
-    for(uint_4 i=0; i<memgr.NbPaquets(); i++) {
-      while(pciw.NBytesToRead() < 1)  usleep(5);
-      pciw.Read(buff+i*paqsz,paqsz); 	
-    }
-    memgr.FreeMemZone(mid, MemZS_Filled);
-  }	
+  uint_4 dmasz = pciw_.TransferSize();
+
+  Byte* Datas = NULL;
+  Byte* tampon = new Byte[paqsz];
+  Byte* nextpaq = NULL;
+
+  uint_4 off_acheval = 0;
+  
+  int nerrdma = 0;
+  int maxerrdma = 10;
+  bool fgarret = false;
+  
+  uint_4 npaqfait = 0;    //  Nb total de paquets traites (DMA + decode)
+  
+  ///  do{  si boucle infini 
+  //  for (uint_4 kmz=0; kmz<nmax_; kmz++)  {
+  while (npaqfait < nmax_*memgr.NbPaquets()) {
+    if (stop_) break;
+    if (fgarret) break;
+    // On pointe vers le debut de la zone a remplir aver le prochain DMA
+      Datas=pciw_.DoTransferData();
+      if (Datas == NULL) { // No data Read in DMA 
+	nerrdma ++;
+	cout << "PCIEReaderChecker/Erreur Waiting for datas ..." << endl;
+	pciw_.PrintStatus(cout);
+	if (nerrdma>=maxerrdma) { fgarret = true; break; }
+      }
+      else {  // DMA reussi 
+	uint_4 curoff = 0;
+	//1- On traite le paquet a cheval, rempli partiellement avec le DMA d'avant si necessaire
+	if (off_acheval > 0) {
+	  if ((paqsz-off_acheval)< dmasz) { 
+	    memcpy((void *)(tampon+off_acheval), (void *)Datas, paqsz-off_acheval);
+	    curoff = paqsz-off_acheval;  off_acheval = 0;  
+	    
+	    if ((nextpaq=NextPaqTarget()) == NULL) {
+	      cout << "2 PCIEReader::run()/Error NextPaqTarget() returned NULL ->STOP 9" << endl;
+	      setRC(9);  fgarret=true; break;
+	    }
+	    BRPaquet paq(tampon, nextpaq, paqsz, swapall_);
+	    npaqfait++;  // Ne pas oublier le compteur de paquets faits 
+	  }
+	  else {
+	    memcpy((void *)(tampon+off_acheval), (void *)Datas, dmasz);
+	    curoff =dmasz;
+	    off_acheval = (dmasz+off_acheval);
+	  }
+	}
+	//2- On traite les paquets complet qui se trouvent dans la zone du DMA 
+	while((curoff+paqsz)<=dmasz) {
+	  //	      BRPaquet paq((Byte*)(Datas)+((paqsz*j)), nextdma+j*paqsz, paqsz, swapall_);
+	  if ((nextpaq=NextPaqTarget()) == NULL) {
+	    cout << "3 PCIEReader::run()/Error NextPaqTarget() returned NULL ->STOP 9" << endl;
+            setRC(9);  fgarret=true; break;
+	  }
+	  BRPaquet paq(Datas+curoff, nextpaq, paqsz, swapall_);
+	  curoff += paqsz;  // On avance l'index dans le buffer du DMA
+	  npaqfait++;  // Ne pas oublier le compteur de paquets faits 
+	}  // -- FIN traitement des paquets complets ds un DMA 
+	//3- On copie si besoin la fin du DMA dans la zone tampon
+	if (curoff < dmasz) {
+	  if (fgarret) break;  // pour sortir si l'on est passe par un STOP 9
+	  off_acheval = dmasz-curoff;
+	  memcpy(tampon, (void*)(Datas+curoff), off_acheval);
+	  curoff += off_acheval; 
+	}
+      }  //   Traitement d'un DMA OK 
+  }
+//  }while(!stop_);	
+  
+  
+  gettimeofday(&tv2, NULL);
+  double tmelaps2 = (tv2.tv_sec-tv1.tv_sec)*1000.+(tv2.tv_usec-tv1.tv_usec)/1000.;
+  if (tmelaps2<0.1) tmelaps2=0.1; 
+  cout << " ------------------ PCIEReader::run()-End summary -------------------" << endl;
+  cout << " PCIEReader/Info TotTransfer=" << pciw_.TotTransferBytes()/1024 
+       << " kb , ElapsTime=" << tmelaps2 << " ms ->" 
+       << (double)pciw_.TotTransferBytes()/tmelaps2 << " kb/s" << endl;	
+  cout << " --------------------------------------------------------------------" << endl;
+  
+  MZoneManage(true);
+  delete [] tampon;
+ 
+  }catch (PException& exc) {
+    cout << " PCIEREADER::run()/catched PException " << exc.Msg() << endl;
+    setRC(3);	
+    return; 
+  }
+  catch(...) {
+    cout << "  PCIEREADER::run()/catched unknown ... exception " << endl;
+    setRC(4);	
+    return; 
+  }
   setRC(0);
+ 
   return;
 }
 
+
+void PCIEReader::Stop()
+{ 
+  // cout << " PCIEReader::Stop() -------------> STOP" <<endl; 
+  stop_ = true;
+  return;
+}
 
 
@@ -61,44 +186,115 @@
 //-------------------------------------------------------
 
-DataSaver::DataSaver(RAcqMemZoneMgr& mem, string& path, uint_4 nmax)
+DataSaver::DataSaver(RAcqMemZoneMgr& mem, string& path, uint_4 nfiles, uint_4 nblocperfile, bool savesig)
   :  memgr(mem) 
 {
-  nmax_ = nmax;	
+  nfiles_ = nfiles;
+  nblocperfile_ = nblocperfile;
+  nmax_ = nblocperfile_*nfiles_;
+  savesig_ = savesig;  // Si false, pas d'ecriture des fichiers FITS du signal	
   stop_ = false;	
   path_ = path;	
 }
-
+void DataSaver::Stop()
+{
+  // cout<< " DataSaver:Stop ........ " << endl;
+  stop_=true;
+
+}
 void DataSaver::run()
 {
   setRC(1);	
+  BRPaqChecker pcheck;  // Verification/comptage des paquets 
+
   try {
     TimeStamp ts; 
-    cout << " DataSaver::run() - Starting " << ts << " NMaxMemZones=" << nmax_ << endl;	
+    cout << " DataSaver::run() - Starting " << ts << " NbFiles=" << nfiles_ << " NBloc/File=" 
+         << nblocperfile_ << " NMaxMemZones=" << nmax_ << endl;	
     char fname[512];
+
     sprintf(fname,"%s/saver.log",path_.c_str());
     ofstream filog(fname);
     filog << " DataProc::run() - starting log file " << ts << endl;		       
-
+    filog << " NbFiles=" << nfiles_ << " NBloc/File="  << nblocperfile_ << " NMaxMemZones=" << nmax_ << endl;
+    	
+    DataTable dt;
+    dt.AddLongColumn("TimeTag");
+    dt.AddIntegerColumn("FrameCounter");
+    dt.AddIntegerColumn("FrameLength");
+    dt.AddIntegerColumn("Num");
+    DataTableRow dtr = dt.EmptyRow();
+    uint_8 timtag = 0;
+    uint_4 numpaq = 0;
+    bool dthead = false;  // Mettre a false pour ne pas remplir DataTable Headers
+
+
+    uint_4 fnum=0;
     uint_4 paqsz = memgr.PaqSize();
-    for (uint_4 kmz=0; kmz<nmax_; kmz++) {
-      int mid = memgr.FindMemZoneId(MemZA_Save);
-      Byte* buff = memgr.GetMemZone(mid);
-      if (buff == NULL) {
-  	cout << " DataSaver::run()/ERROR memgr.GetMemZone(" << mid << ") -> NULL" << endl;
-  	setRC(2);	
-  	return;	
+    for (uint_4 nbFile=0;nbFile<nfiles_ ;nbFile++) {
+      if (stop_ )   break;
+      sprintf(fname,"%s/HDRfits%d.txt",path_.c_str(),fnum);
+      ofstream header(fname);
+
+      BRPaquet paq0(NULL, NULL, paqsz); 
+      uint_4 npaqperfile = memgr.NbPaquets()*nblocperfile_;  // Nombre de paquets ecrits dans un fichier 
+
+      MiniFITSFile mff; 
+      if (savesig_) { //Reza - Ouverture conditionnel fichier 
+        sprintf(fname,"%s/signal%d.fits",path_.c_str(),(int)fnum++);
+        mff.Open(fname,MF_Write);  //Reza - Ouverture conditionnel fichier 
+        mff.setDTypeNaxis(MF_Byte, paq0.DataSize()+paq0.HeaderSize(), npaqperfile); 
       }
-      sprintf(fname,"%s/signal%d.fits",path_.c_str(),(int)kmz);
-      MiniFITSFile mff(fname,MF_Write);
-      BRPaquet paq0(NULL, buff, paqsz); 
-      mff.setDTypeNaxis(MF_Byte, paq0.DataSize(), memgr.NbPaquets());
-      for(uint_4 i=0; i<memgr.NbPaquets(); i++) {
-  	BRPaquet paq(NULL, buff+i*paqsz, paqsz); 
-  	mff.WriteB(paq.Data(), paq.DataSize());
+      else sprintf(fname,"MemDataBloc[%d]-NoDataFile",(int)fnum++);
+
+      for (uint_4 kmz=0; kmz<nblocperfile_; kmz++) {
+	if (stop_) break;
+	  //DBG cout << " DataSaver::run()- nbFile=" << nbFile << " kmz=" << kmz << endl;	
+	int mid = memgr.FindMemZoneId(MemZA_Save);  
+	Byte* buff = memgr.GetMemZone(mid);
+        if (buff == NULL) {
+	  cout << " DataSaver::run()/ERROR memgr.GetMemZone(" << mid << ") -> NULL" << endl;
+	  setRC(2);	
+	  return;	
+	}
+	for(uint_4 i=0; i<memgr.NbPaquets(); i++) {
+ 
+	  BRPaquet paq(NULL, buff+i*paqsz, paqsz);
+	  pcheck.Check(paq);   // Verification du paquet / FrameCounter 
+
+	  header << hex << paq.HDRMarker() << " " << paq.TRLMarker() << " " << paq.TimeTag2()<< " "<< paq.TimeTag1()<< " " << paq.FrameCounter() << " " << paq.PaqLen()  << endl;
+
+          if (dthead) {  // Remplissage DataTable entetes paquets 
+            timtag = (uint_8)paq.TimeTag2()*0x100000000ULL+paq.TimeTag1();
+            dtr[0] = timtag;
+            dtr[1] = paq.FrameCounter();
+            dtr[2] = paq.PaqLen();
+            dtr[3] = numpaq++;
+            dt.AddRow(dtr);
+	  }
+
+	  if (savesig_) // Reza - Ecriture conditionnel fichier fits signal 
+	  //  mff.WriteB(paq.Data1(), paq.DataSize());
+	    mff.WriteB(paq.Header(),paq.DataSize()+paq.HeaderSize()); // ecriture datas + header
+	}
+	memgr.FreeMemZone(mid, MemZS_Saved);
       }
-      filog << ts << " : created data file  " << fname << endl;		       
-      cout << " DataSaver::run() " << ts << " : created data file  " << fname << endl;
-      memgr.FreeMemZone(mid, MemZS_Saved);
+      ts.SetNow(); 
+      filog << ts << " : OK data file  " << fname << endl;		       
+      cout << " DataSaver::run() " << ts << " : OK data file  " << fname << endl;
     }
+    if (dthead) {
+      cout << dt;
+      char fname2[256];
+      sprintf(fname2,"%s/headers.ppf",path_.c_str());
+      POutPersist po(fname2);
+      po << dt;
+    }
+    cout << " --------------------  DataSaver::run() -------------------- " << endl;
+    pcheck.Print(cout);
+    cout << " ---------------------------------------------------------- " << endl;
+    ts.SetNow();
+    pcheck.Print(filog);
+    filog << " DataSaver::run() - End of processing/run() " << ts << endl;		       
+
   }
   catch (MiniFITSException& exc) {
@@ -117,2 +313,132 @@
 
 
+
+
+//----------------------------------------------------------------------------------------------------------
+// Classe thread de lecture PCI-Express + Check pour tests de verification de debit/etc avec un seul thread
+//----------------------------------------------------------------------------------------------------------
+
+PCIEReaderChecker::PCIEReaderChecker(PCIEWrapper &pciw,uint_4 sizeFrame,uint_4 packSize ,RAcqMemZoneMgr& mem, 
+				     uint_4 nmax, BRDataFmtConv swapall)
+  :   memgr(mem) , pciw_ (pciw)
+{
+  nmax_ = nmax;	
+  swapall_ = swapall;  	// select data swap/format conversion for BRPaquet
+  stop_ = false;
+  packSize_ = packSize;
+  sizeFr_ =sizeFrame;
+}
+void PCIEReaderChecker::run()
+{
+  
+  struct timeval tv1, tv2;
+  gettimeofday(&tv1, NULL);
+  
+  cout << " PCIEReaderChecker::run() - Starting , NMaxMemZones=" << nmax_ 
+       << " memgr.NbPaquets()=" << memgr.NbPaquets() << endl;	
+  setRC(1);	
+  cout << " ... RAcqMemZoneMgr not used - using s fixed memory location for packets decoding ..." << endl;
+
+  uint_4 cpt=0;
+  // sigaddset(&act.sa_mask,SIGINT);  // pour proteger le transfert DMA
+  //sigaction(SIGINT,&act,NULL);  	
+  uint_4 paqsz = memgr.PaqSize();
+  uint_4 dmasz = pciw_.TransferSize();
+
+  BRPaqChecker pcheck;  // Verification/comptage des paquets 
+
+  Byte* Datas = NULL;
+  Byte* locdata = new Byte[paqsz];
+  Byte* tampon = new Byte[paqsz];
+
+  uint_4 off_acheval = 0;
+
+  int nerrdma = 0;
+  int maxerrdma = 10;
+  bool fgarret = false;
+  for (uint_4 kmz=0; kmz<nmax_; kmz++)  {
+    if (stop_) break;
+    if (fgarret) break;
+
+    Byte* nextdma = locdata;
+    uint_4 npaqfait = 0;      
+    //      for (uint_4 i=0; i<memgr.NbPaquets(); i += pktInDMATr) {  // attention pktInDMATr paquets dans 1 seul DMA
+    while (npaqfait < memgr.NbPaquets()) {
+      if (fgarret) break;
+      // On pointe vers le debut de la zone a remplir aver le prochain DMA
+      //-- Zone memoire locale Byte* nextdma = buff+i*paqsz;
+       	Datas=pciw_.DoTransferData();
+	
+	if (Datas == NULL) { // No data Read in DMA 
+	  nerrdma ++;
+	  cout << "PCIEReaderChecker/Erreur Waiting for datas ..." << endl;
+	  pciw_.PrintStatus(cout);
+	  if (nerrdma>=maxerrdma) { fgarret = true; break; }
+	}
+	else {
+	  uint_4 curoff = 0;
+	  //1- On traite le paquet a cheval, rempli partiellement avec le DMA d'avant si necessaire
+	  //	  if (off_acheval > 0) {  
+	  //  memcpy((void *)(tampon+off_acheval), (void *)Datas, paqsz-off_acheval);
+	  //  curoff = paqsz-off_acheval;  off_acheval = 0;  
+	    
+	  // BRPaquet paq(tampon, locdata, paqsz, swapall_);
+	  //  npaqfait++;  // Ne pas oublier le compteur de paquets faits 
+	  //  pcheck.Check(paq);   // Verification du paquet / FrameCounter 
+	  //}
+	if (off_acheval > 0) {
+	  if ((paqsz-off_acheval)< dmasz) { 
+	    memcpy((void *)(tampon+off_acheval), (void *)Datas, paqsz-off_acheval);
+	    curoff = paqsz-off_acheval;  off_acheval = 0;  
+	    
+	    BRPaquet paq(tampon, locdata, paqsz, swapall_);
+	    npaqfait++;  // Ne pas oublier le compteur de paquets faits
+	    pcheck.Check(paq);   // Verification du paquet / FrameCounter 
+	  }
+	  else {
+	    memcpy((void *)(tampon+off_acheval), (void *)Datas, dmasz);
+	    curoff =dmasz;
+	    off_acheval = (dmasz+off_acheval);
+	  }
+	}
+	  //2- On traite les paquets complet qui se trouvent dans la zone du DMA 
+	  while((curoff+paqsz)<=dmasz) {
+	    //	      BRPaquet paq((Byte*)(Datas)+((paqsz*j)), nextdma+j*paqsz, paqsz, swapall_);
+	    BRPaquet paq(Datas+curoff, locdata, paqsz, swapall_);
+	    curoff += paqsz;  // On avance l'index dans le buffer du DMA
+	    npaqfait++;  // Ne pas oublier le compteur de paquets faits 
+	    pcheck.Check(paq);   // Verification du paquet / FrameCounter 
+	  }  // -- FIN traitement des paquets complets ds un DMA 
+	  //3- On copie si besoin la fin du DMA dans la zone tampon
+	  if (curoff < dmasz) {
+	    off_acheval = dmasz-curoff;
+	    memcpy(tampon, (void*)(Datas+curoff), off_acheval);
+	    curoff += off_acheval; 
+	  }
+	}  //   Traitement d'un DMA OK 
+	
+    }  // Fin boucle de remplissage d'une zone memoire
+  } //  Fin boucle sur les zones 
+  
+  setRC(0);
+  gettimeofday(&tv2, NULL);
+  double tmelaps2 = (tv2.tv_sec-tv1.tv_sec)*1000.+(tv2.tv_usec-tv1.tv_usec)/1000.;
+  if (tmelaps2<0.1) tmelaps2=0.1; 
+  cout << " ------------------ PCIEReaderChecker::run()-End summary -------------------" << endl;
+  cout << " PCIEReaderChecker/Info TotTransfer=" << pciw_.TotTransferBytes()/1024 
+       << " kb , ElapsTime=" << tmelaps2 << " ms ->" 
+       << (double)pciw_.TotTransferBytes()/tmelaps2 << " kb/s" << endl;	
+  pcheck.Print(cout);
+  cout << " --------------------------------------------------------------------" << endl;
+
+  delete [] locdata;
+  delete [] tampon;
+
+  return;
+}
+void PCIEReaderChecker::Stop()
+{ 
+  // cout << " PCIEReaderChecker::stop()  ........ STOP" <<endl; 
+  stop_ = true;
+
+}
Index: trunk/AddOn/TAcq/racqurw.h
===================================================================
--- trunk/AddOn/TAcq/racqurw.h	(revision 3622)
+++ trunk/AddOn/TAcq/racqurw.h	(revision 3623)
@@ -14,6 +14,8 @@
 #include "sopnamsp.h"
 #include "zthread.h"
+#include "pciewrap.h"
 
 #include "brtypes.h"
+#include "brpaqu.h"
 
 using namespace std;
@@ -27,11 +29,33 @@
 class PCIEReader : public ZThread {
 public:
-  PCIEReader(RAcqMemZoneMgr& mem, uint_4 nmax=100);	
+  PCIEReader( PCIEWrapper &pciw , uint_4 sizeFrame,uint_4 paqSize ,RAcqMemZoneMgr& mem, 
+	      uint_4 nmax=100, BRDataFmtConv swapall=BR_SwapAll);	
   virtual void run(); 
+   void Stop();
   inline void STOP() { stop_ = true; }	
+    
 protected:
+  // Pour recuperer un pointeur sur la prochaine zone memoire devant recevoir un paquet
+  inline Byte* NextPaqTarget()  {
+    if ((mmbuf_ == NULL )||(targ_npaq_ >= max_targ_npaq)) 
+      if (MZoneManage()) return NULL;
+    Byte* rb=mmbuf_+targ_npaq_*packSize_;
+    targ_npaq_++;
+    return rb;
+  }
+  bool MZoneManage(bool clean=false);  // Renvoie true si probleme
+
   RAcqMemZoneMgr& memgr;
   uint_4 nmax_;  // Nombre maxi de blocs MemZone traites
+  BRDataFmtConv swapall_;  // select data swap/format conversion for BRPaquet
   bool stop_;  
+  unsigned int sizeFr_ ;
+  PCIEWrapper& pciw_;
+  uint_4 packSize_;
+  // Variables pour gerer la logique de  NextPaqTarget() qui cache l'acces a RAcqMemZoneMgr
+  int mid_;  // Identificateur zone memoire
+  uint_4 targ_npaq_;  // Numero de paquet dans une seule zone memoire 
+  uint_4 max_targ_npaq; // =  mmgr.NbPaquets() = Max de targ_npaq_
+  Byte* mmbuf_;  // Pointeur zone memoire rendu par RAcqMemZoneMgr 
 };
 
@@ -42,14 +66,41 @@
 class DataSaver : public ZThread {
 public:	
-  DataSaver(RAcqMemZoneMgr& mem, string& path, uint_4 nmax=100);
+  DataSaver(RAcqMemZoneMgr& mem, string& path, uint_4 nfiles=100, uint_4 nblocperfile=1, bool savesig=true);
+
   virtual void run(); 
+  void Stop(); 
+  inline void STOP() { stop_ = true; }	
+protected:
+  RAcqMemZoneMgr& memgr;
+  uint_4 nfiles_;  // Nombre maxi de fichiers cree
+  uint_4 nblocperfile_;  // Nombre de bloc (zone memoire) mis dans un fichier
+  uint_4 nmax_;  // Nombre maxi de blocs MemZone traites = nfiles * nblocperfile_
+  bool savesig_; // Si false, pas d'ecriture des fichiers FITS du signal 
+  bool stop_;  
+  string path_;  
+  struct sigaction act;
+ 
+};
+
+//-------------------------------------------------------
+// Classe thread de lecture PCI-Express + Check 
+//-------------------------------------------------------
+
+class PCIEReaderChecker : public ZThread {
+public:
+  PCIEReaderChecker( PCIEWrapper &pciw , uint_4 sizeFrame,uint_4 paqSize ,RAcqMemZoneMgr& mem, 
+		     uint_4 nmax=100, BRDataFmtConv swapall=BR_SwapAll);  
+  virtual void run(); 
+   void Stop();
   inline void STOP() { stop_ = true; }	
 protected:
   RAcqMemZoneMgr& memgr;
   uint_4 nmax_;  // Nombre maxi de blocs MemZone traites
+  BRDataFmtConv swapall_;  // select data swap/format conversion for BRPaquet
   bool stop_;  
-  string path_;  
+  unsigned int sizeFr_ ;
+  PCIEWrapper& pciw_;
+  uint_4 packSize_;
 };
 
-
 #endif
Index: trunk/AddOn/TAcq/tmtacq.cc
===================================================================
--- trunk/AddOn/TAcq/tmtacq.cc	(revision 3622)
+++ trunk/AddOn/TAcq/tmtacq.cc	(revision 3623)
@@ -1,7 +1,12 @@
 #include <iostream>
 
+#include "tmtacq.h"
 #include "racqumem.h"
 #include "racqurw.h"
+#ifndef NOPCIECARD
+#include "racquwbin.h"
+#endif
 #include "racquproc.h"
+
 
 #include "pciewrap.h"
@@ -18,14 +23,76 @@
 using namespace std;
 using namespace SOPHYA;
-
+	
+static DataSaver *pDs;
+static PCIEReaderChecker *pPcierc;
+static PCIEReader *pPcier;
+static DataProcFFT2C *pPrfft;
+static DataProc2C *pPr;
+static RAcqMemZoneMgr *pMmgr;
 //--------------------------------------------------------
-// Programme test acquisition BAORadio multi-thread
+// Programme test acquisition BAORadio multi-thread 
 //  LAL -   R. Ansari Juillet -  2008
 //--------------------------------------------------------
+void Stop(int s)
+{
+  printf("............. MAIN ... receive signal %d \n",s);
+  if (pPcierc != NULL) pPcierc->Stop();
+  if (pPcier != NULL) pPcier->Stop();
+  if (pPr !=NULL) pPr->Stop();
+  if (pPrfft !=NULL) pPrfft->Stop();
+  if (pDs != NULL) pDs->Stop();
+  if (pMmgr !=NULL) pMmgr->Stop();
+  
+}
 
 int main(int narg, char* arg[])
-{
+{ 
+  
+ struct sigaction act;
  
   int rc = 0;
+ cout << " ===============================================================" << endl;
+  cout << " =========  " <<BAOR_ACQ_VER_STR <<BAOR_ACQ_VER <<"                  ===========" << endl;
+  cout << " ===============================================================" << endl;
+  
+ if (narg < 8) {
+   cout << "\n Usage: tmtacq CardNum PaquetSize NFrameDMA NFiles NBlocPerFile NMaxProc DataDirPath [AcqMode] [NPaqMemZone][HardCtlC]" << endl;
+   cout << " - CardNum : PCI-Express card number (=1,2)" << endl;
+   cout << " - PaquetSize or FrameSize (=DATA+HDR+TRL_Size)  " << endl;
+   cout << " - NFrameDMA = DMASize= NFrameDMA*1024 , 4KO<=MaxDMASize<=64 ko " << endl;
+   cout << " - NFiles = Number of data files produced " << endl;
+   cout << " - NBlocPerFile = Number of memory data bloc in one file " << endl;
+   cout << " - NMaxProc = Max number of memory data blocs processed (FFT ...) " << endl;
+   cout << "      NMaxProc=0 -> No Processing " << endl;
+   cout << " - DataDirPath : Subdirectory of /Raid " << endl;
+   cout << "   Pour la version du firmware qui ne swappe pas les paquets" << endl;
+   cout << " - AcqMode: = swapall , fft1c , fft2c, swh , nof , mxs , mono , monosw (default=std)" << endl;
+   cout << "    swapall -> SwapAll+SaveData , swh->swap header only " << endl;
+   cout << "    fft1c , ff2c -> reorder data for 1 channel/2channel FFT " << endl;
+   cout << "    fft1cnof , ff2cnof -> reorder FFT data, but DONT write files " << endl;
+   cout << endl;
+   cout << "   Pour la version du firmware qui swappe partiellement " << endl;
+   cout << "  -AcqMode : swap32 ,fft1c32 , fft2c32,fft1cnof32 , fft2cnof32 " <<endl;
+   cout << "    fft1c32 , fft2c32 -> reorder data for 1 channel/2channel FFT " << endl;
+   cout << "    fft1cnof32 , ff2cnof32 -> reorder FFT data, but DONT write files " << endl << endl;
+ cout << endl;
+   cout << "   Pour la version du firmware qui ne swappe plus " << endl;
+   cout << "  -AcqMode :  nosw,fft1cnosw , fft2cnosw" <<endl;
+   cout << "    fft1cnosw , fft2cnosw -> reorder data for 1 channel/2channel FFT " << endl;
+   cout << "    fft1cnofnosw , ff2cnofnosw -> reorder FFT data, but DONT write files " << endl << endl;
+
+
+   cout << "   Option pour debug ou test performance swapp initial (std)" << endl ;
+   cout << "    nof->Don't write signal fits files , mxs->swh+nof: swap header only + no fits " << endl;
+   cout << "    mono->Test with a single thread PCIEReaderChecker " << endl;
+   cout << "   monosw->Test with a single thread PCIEReaderChecker, But swap all packet " << endl;
+   cout << endl;
+   cout << "   mononsw->Test with a single thread PCIEReaderChecker, But no swap paquet " << endl;
+   cout << endl;
+   cout << " - NPaqMemZone : Number of paquets in one memory data bloc (Default=128) " << endl;
+   cout << " -HardCtlC : Y y (direct interrpution by CtrlC ) default (no) " << endl;
+  return 1;
+  }
+
   InitTim();
  
@@ -33,19 +100,131 @@
   TArrayInitiator _arri;
   FitsIOServerInitiator _fiosi;
-  
   Timer tm("tmtacq");
-  string dir = "ExA";
-  cout << "tmtacq[1] - starting acq program " << endl;
-  
+ 
+  string acqmode = "std";
+  if (narg > 8)  acqmode = arg[8];
+  bool savesigfits = true;
+  // BRDataFmtConv swapall = BR_SwapAll;
+  BRDataFmtConv swapall = BR_Copy;
+  bool monothr = false;
+  if (acqmode == "swapall")  swapall = BR_SwapAll;
+  if (acqmode == "fft1c")  swapall = BR_FFTOneChan;
+  if (acqmode == "fft2c")  swapall = BR_FFTTwoChan;
+  if (acqmode == "fft1cnof")  { swapall = BR_FFTOneChan;  savesigfits = false; }
+  if (acqmode == "fft2cnof")  { swapall = BR_FFTTwoChan;  savesigfits = false; }
+  if ((acqmode == "swh") || (acqmode == "mxs") || (acqmode == "mono") )  swapall = BR_SwapHDR;
+  if ((acqmode == "nof") || (acqmode == "mxs") || (acqmode == "mono"))  savesigfits = false;
+  if (acqmode == "mono")  { monothr = true;   swapall = BR_SwapHDR;; }
+  if (acqmode == "monosw")  { monothr = true;   swapall = BR_SwapAll; }
+  if (acqmode == "mononsw")  { monothr = true;   swapall = BR_Copy; }
+
+  if (acqmode == "swap32")   swapall = BR_Swap32 ;
+  if (acqmode == "fft1c32")  swapall = BR_FFTOneChan32;
+  if (acqmode == "fft2c32")  swapall = BR_FFTTwoChan32;
+  if (acqmode == "fft1cnof32")  { swapall = BR_FFTOneChan32;  savesigfits = false; }
+  if (acqmode == "fft2cnof32")  { swapall = BR_FFTTwoChan32;  savesigfits = false; }
+
+  if (acqmode == "nosw")   swapall = BR_Copy ;
+  if (acqmode == "fft1cnosw")  swapall = BR_FFTOneChanNoSwap;
+  if (acqmode == "fft2cnosw")  swapall = BR_FFTTwoChanNoSwap;
+  if (acqmode == "fft1cnofnosw")  { swapall = BR_FFTOneChanNoSwap;  savesigfits = false; }
+  if (acqmode == "fft2cnofnosw")  { swapall = BR_FFTTwoChanNoSwap;  savesigfits = false; }
+
+#ifdef NOPCIECARD
+  string dir = string(arg[7])+"/";
+#else  
+  string dir =string("/Raid/")+arg[7]+"/";
+#endif 
+  cout << "  DataDirpath=" << dir << " SwapMode=" << BRPaquet::FmtConvToString(swapall) 
+       << "  DataSaveMode=" << ((savesigfits)?"Yes/FitsFile":"NO") << endl; 
+  
+  char cmd[192];
+  sprintf(cmd,"mkdir %s",dir.c_str());
+  if (system(cmd) < 0) {
+    cout << "tmtacq/Error: Can not create  subdirectory " << dir << " -> exit" << endl;
+    return 2;
+  }
+  int card = atoi(arg[1]);
+  unsigned int sizeFrame = atoi(arg[2]);
+  unsigned int nbFrameDMA = atoi(arg[3]);
+  int NbFiles = atoi(arg[4]);
+  int NBlocPerFile = atoi(arg[5]);
+  int NMaxProc = atoi(arg[6]);  // Nombre de blocs traites par le thread de calcul
+  cout << "tmtacq[1] - starting acq program under card " << card <<  " FrameSize= " << sizeFrame << endl;
+
+  uint_4 nZones = 10;  // Nombre de zones memoires
+  uint_4 nPaqZone = 128;  // 128 Paquets / zone memoire - valeur par defaut
+  if (narg > 9)    // pour traiter eventuellement un arret brutal par CtlC mettre le 9eme arg a Y
+    { string val = arg[9];
+      if ( ( val == "Y")||( val == "y")) ; 
+      else {
+	act.sa_handler=Stop;
+	sigaction(SIGINT,&act,NULL);  	
+        if ( atoi(arg[9]) > 0)  nPaqZone=atoi(arg[9]);
+      }
+    }
+  else {
+    act.sa_handler=Stop;
+    sigaction(SIGINT,&act,NULL);  	
+  }
+  uint_4 PaqSZ =sizeFrame;  // Taille de paquets 
+  // uint_4 dmaSize  = nbFrameDMA*PaqSZ ;  // plantage 
+  uint_4 dmaSize  = nbFrameDMA*1024 ; 
+  uint_4 patternSZ=0x400;  // pas utilise avec la fibre 
+  uint_4 NMaxBloc = NbFiles*NBlocPerFile; 
+  cout << "tmtacq[0] - PaqSize = " << PaqSZ << " NbPaq/Zone=" << nPaqZone << " NZones=" << nZones << endl; 
+  cout << " NbFiles=" << NbFiles << " NBloc/File=" << NBlocPerFile << " -> NMaxBloc=" << NMaxBloc << endl;
+  cout << "tmtacq[1] NbFrameDMA=" << nbFrameDMA << "  DMASize=" << dmaSize << " bytes" << endl;
+  cout << "tmtacq[1] NMaxProc=" << NMaxProc << endl;
   try {
-    RAcqMemZoneMgr mmgr(3,100,4096);
-    PCIEReader pcir(mmgr, 10);
-    DataSaver ds(mmgr, dir, 10);
-    DataProc pr(mmgr, dir, 1, 10);
+
+#ifdef NOPCIECARD
+    TestPCIWrapperNODMA pciw(PaqSZ);
+#else
+    DMAMgr dma1(card,patternSZ,dmaSize ); 
+    if (! dma1.StatusFibre() ) {
+      cout << " tmtacq[0] - fibre non accrochee -> exit " << endl;
+      throw PCIEWException(" Fibre non accrochee ");
+    }
+    else cout << " tmtacq[0] - fibre accrochee OK " << endl;
+#endif    
+    RAcqMemZoneMgr mmgr(nZones, nPaqZone, PaqSZ);
+    pMmgr =&mmgr;
+
+    if (monothr) {
+      cout << "tmtacq[1] single thread PCIE test PCIEReaderChecker ... ";
+      PCIEReaderChecker pcirc(pciw,dmaSize,PaqSZ ,mmgr, NMaxBloc, swapall);
+      pPcierc=&pcirc;
+      pcirc.start();
+      sleep(1);
+      pcirc.join();
+      cout << "tmtacq[2] - single thread PCIEReaderChecker finished " << endl;
+      tm.Split("Single Thread Finished");  
+      mmgr.Print(cout);
+      return 0;
+    }
+    PCIEReader pcir(pciw,dmaSize,PaqSZ ,mmgr, NMaxBloc, swapall);
+    pPcier= &pcir;
+     DataSaver ds(mmgr, dir, NbFiles, NBlocPerFile, savesigfits);
+     pDs= &ds;
+     //DataBinSaver ds(mmgr, dir, NbFiles ,NBlocPerFile);
+     //     DataProc1C pr(mmgr, dir, nmean, stepproc, 100);     Pour processer un canal
+     int stepproc = 2;
+     int nmean = nPaqZone*NBlocPerFile/stepproc;
+     DataProc2C pr(mmgr, dir, nmean, stepproc, NMaxProc);
+     DataProcFFT2C prfft(mmgr, dir, nmean, stepproc, NMaxProc);
     tm.Split("Threads created");  
     cout << "tmtacq[2] - starting 3 threads pcir, ds, pr ... " << endl;
+    /*
+    char test[100];
+    cout << " <CR> to continue, x to exit ..." << endl;
+    gets(test); if (test[0] == 'x')  return 9;
+    */
     pcir.start();
     ds.start();
-    pr.start();
+    if (NMaxProc>0) { // On ne demarre que si au moins NMaxProc>0
+      if (acqmode.substr(0,5)=="fft2c")	{ prfft.start(); pPrfft=&prfft;}
+      else { pr.start();   pPr=&pr;}
+    }
     cout << "tmtacq[3] - waiting for threads to finish ... " << endl;
     sleep(1);
@@ -54,5 +233,6 @@
     sleep(1);
     mmgr.Stop();
-    pr.join();
+   if (NMaxProc>0) if ( pPr != NULL) pr.join();
+   if (NMaxProc>0) if ( pPrfft != NULL) prfft.join();
     cout << "tmtacq[4] - threads finished " << endl;
     tm.Split("Threads Finished");  
@@ -63,4 +243,8 @@
     cerr << " tmtacq.cc catched MiniFITSException " << exc.Msg() << endl;
     rc = 77;
+  } 
+  catch (PCIEWException& exc) {
+    cerr << "\7  tmtacq.cc catched MiniFITSException " << exc.Msg() << endl;
+    rc = 75;
   }  
   catch (PThrowable& exc) {
@@ -75,5 +259,5 @@
   }
   catch (...) {
-  	cerr << " tmtacq.cc : Catched ... exception " << endl;
+  	cerr << "  tmtacq.cc : Catched ... exception " << endl;
   	rc = 79;
   }
@@ -81,2 +265,3 @@
   return rc;
 }
+
Index: trunk/AddOn/TAcq/tmtfft.cc
===================================================================
--- trunk/AddOn/TAcq/tmtfft.cc	(revision 3622)
+++ trunk/AddOn/TAcq/tmtfft.cc	(revision 3623)
@@ -27,5 +27,5 @@
 #include "tarrinit.h"
 
-#include "stsrand.h"
+#include "randfmt.h"
 #include "fftpserver.h"
 #include "fftwserver.h"
@@ -79,5 +79,5 @@
   cout << "MTDoFFT::run() - Nom= " << nom_ << " vv.Size()= " << vv_.Size() 
        << " PaqSz=" << paqsz_ << " NbFFT= " << nbfft_ << endl;
-  RandomGenerator rgen;
+  FMTRandGen rgen;
   TVector<r_4> vx(paqsz_);
   fftwf_plan plan = fftwf_plan_dft_r2c_1d(paqsz_, vx.Data(), 
@@ -111,5 +111,5 @@
   Timer tm("f3_tmtfft");
   vector<MTDoFFT *> vth;
-  RandomGenerator rg;
+  FMTRandGen rg;
   TVector<r_4> DATA(VSZ);
   for(sa_size_t i=0; i<VSZ; i++) 
