diff --git a/doc/PulseCounting_user_manual-Ind3.doc b/doc/PulseCounting_user_manual-Ind4.doc
similarity index 90%
rename from doc/PulseCounting_user_manual-Ind3.doc
rename to doc/PulseCounting_user_manual-Ind4.doc
index 83b25e1104d9c2fad0b8fa49992e08a4b78aed61..b7ebf53f816b912db78d2c157893687a3eed1793 100644
Binary files a/doc/PulseCounting_user_manual-Ind3.doc and b/doc/PulseCounting_user_manual-Ind4.doc differ
diff --git a/pom.xml b/pom.xml
index f97ad4e8d0081e508f744675ef89914e316eb8fa..44e5d8ce612f9775cdb0c7514c0f21902885a0c4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
    
    <groupId>fr.soleil.device</groupId>
    <artifactId>PulseCounting-${aol}-${mode}</artifactId>
-   <version>1.4.1-SNAPSHOT</version>
+   <version>1.6.0</version>
    
    <packaging>nar</packaging>
    <name>PulseCounting</name>
@@ -43,7 +43,6 @@
        <dependency>
            <groupId>fr.soleil.lib</groupId>
            <artifactId>NI660Xsl-${aol}-${library}-${mode}</artifactId>
-		   <version>1.4.0</version>
        </dependency>
             <dependency>
                 <groupId>fr.soleil.lib</groupId>
diff --git a/src/BufferedCounterDt.cpp b/src/BufferedCounterDt.cpp
index 88cb94eabd19fa15928e008d37930505696a1e42..e55d40a5fb4e3646cc3f527f5c39f8e6e94874ad 100644
--- a/src/BufferedCounterDt.cpp
+++ b/src/BufferedCounterDt.cpp
@@ -29,6 +29,7 @@ BufferedCounterDt::BufferedCounterDt (BCEconfig p_conf, NexusManager * storage)
 	this->m_dataBuffer_thread = NULL;
   m_cntOverrun = false;
   m_cntTimedout = false;
+  m_storageError = false;
   m_data.clear();
 	m_cfg = p_conf;
   m_storage_mgr = storage;
@@ -144,6 +145,13 @@ void BufferedCounterDt::handle_scaled_buffer(ni660Xsl::InScaledBuffer* buffer, l
   DEBUG_STREAM << "BufferedCounterDt::handle_scaled_buffer() entering..." << std::endl;
 	DEBUG_STREAM << "BufferedCounterDt::handle_scaled_buffer() - samples to read = " << _samples_read << std::endl;
 
+  // check samples number is > 0
+  if (_samples_read <= 0)
+  {
+    ERROR_STREAM << "BufferedCounterDt::handle_scaled_buffer-> samples to read negative or null value!" << std::endl;
+    this->stopCnt();
+	return;
+  }	
 	yat::AutoMutex<> guard(this->m_buffLock);
 
 	ni660Xsl::InScaledBuffer& buf = *buffer;
@@ -170,12 +178,16 @@ void BufferedCounterDt::handle_scaled_buffer(ni660Xsl::InScaledBuffer* buffer, l
       catch (Tango::DevFailed & df)
       {
 	      ERROR_STREAM << "BufferedCounterDt::handle_raw_buffer-> pushNexusData caught DevFailed: " << df << std::endl;
-        // Should we stop acquisition if nx problem?
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
       }
       catch (...)
       {
 	      ERROR_STREAM << "BufferedCounterDt::handle_raw_buffer-> pushNexusData caugth unknown exception!" << std::endl;
-        // Should we stop acquisition if nx problem?
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
       }
     }
 
@@ -205,12 +217,16 @@ void BufferedCounterDt::handle_scaled_buffer(ni660Xsl::InScaledBuffer* buffer, l
       catch (Tango::DevFailed & df)
       {
         ERROR_STREAM << "BufferedCounterDt::handle_raw_buffer-> pushNexusData caught DevFailed: " << df << std::endl;
-        // Should we stop acquisition if nx problem?
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
       }
       catch (...)
       {
         ERROR_STREAM << "BufferedCounterDt::handle_raw_buffer-> pushNexusData caugth unknown exception!" << std::endl;
-        // Should we stop acquisition if nx problem?
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
       }
     }
   }
@@ -269,12 +285,16 @@ void BufferedCounterDt::handle_scaled_buffer(ni660Xsl::InScaledBuffer* buffer, l
         catch (Tango::DevFailed & df)
         {
 	        ERROR_STREAM << "BufferedCounterDt::handle_raw_buffer-> pushNexusData caught DevFailed: " << df << std::endl;
-          // Should we stop acquisition if nx problem?
+          // We should stop acquisition if nx problem!
+          this->m_storageError = true;
+          this->stopCnt();
         }
         catch (...)
         {
 	        ERROR_STREAM << "BufferedCounterDt::handle_raw_buffer-> pushNexusData caugth unknown exception!" << std::endl;
-          // Should we stop acquisition if nx problem?
+          // We should stop acquisition if nx problem!
+          this->m_storageError = true;
+          this->stopCnt();
         }
       }
 		}
@@ -299,6 +319,7 @@ void BufferedCounterDt::startCnt()
 	DEBUG_STREAM << "BufferedCounterDt::startCnt() entering..." << endl;
   this->m_cntOverrun = false;
   this->m_cntTimedout = false;
+  this->m_storageError = false;
 
 	{
 		yat::AutoMutex<> guard(this->m_buffLock);
diff --git a/src/BufferedCounterDt.h b/src/BufferedCounterDt.h
index ae56eb018be805e4a3bc04db10d7dfcf667767ac..4695548a64bf31ad1a582ffbadd29b481d9523d1 100644
--- a/src/BufferedCounterDt.h
+++ b/src/BufferedCounterDt.h
@@ -145,6 +145,12 @@ public:
     return this->m_cntTimedout;
   }
 
+  // has counter stopped on storage error?
+  bool isStorageKO()
+  {
+    return this->m_storageError;
+  }
+
 protected:
 
 	// counter config
@@ -177,6 +183,9 @@ protected:
   // timeout flag
   bool m_cntTimedout;
 
+  // Storage error flag
+  bool m_storageError;
+
   // storage manager
   NexusManager * m_storage_mgr;
 };
diff --git a/src/BufferedCounterEvt.cpp b/src/BufferedCounterEvt.cpp
index 30ed6d7e51cc1bd782646c76675d23656d35f82d..72ba367c201a793bc03873044349ef5d022f4452 100644
--- a/src/BufferedCounterEvt.cpp
+++ b/src/BufferedCounterEvt.cpp
@@ -30,6 +30,7 @@ BufferedCounterEvt::BufferedCounterEvt (BCEconfig p_conf, NexusManager * storage
 	this->m_dataBuffer_thread = NULL;
   m_cntOverrun = false;
   m_cntTimedout = false;
+  m_storageError = false;
   m_data.clear();
 	m_cfg = p_conf;
   m_storage_mgr = storage;
@@ -135,6 +136,14 @@ void BufferedCounterEvt::handle_raw_buffer(ni660Xsl::InRawBuffer* buffer, long&
 	DEBUG_STREAM << "BufferedCounterEvt::handle_raw_buffer() entering..." << std::endl;
 	DEBUG_STREAM << "BufferedCounterEvt::handle_raw_buffer() - samples to read = " << _samples_read << std::endl;
 
+  // check samples number is > 0
+  if (_samples_read <= 0)
+  {
+    ERROR_STREAM << "BufferedCounterEvt::handle_raw_buffer-> samples to read negative or null value!" << std::endl;
+    this->stopCnt();
+	return;
+  }	
+  
 	yat::AutoMutex<> guard(this->m_buffLock);
 
 	ni660Xsl::InRawBuffer& buf = *buffer;
@@ -164,12 +173,16 @@ void BufferedCounterEvt::handle_raw_buffer(ni660Xsl::InRawBuffer* buffer, long&
       catch (Tango::DevFailed & df)
       {
 	      ERROR_STREAM << "BufferedCounterEvt::handle_raw_buffer-> pushNexusData caught DevFailed: " << df << std::endl;
-        // Should we stop acquisition if nx problem?
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
       }
       catch (...)
       {
 	      ERROR_STREAM << "BufferedCounterEvt::handle_raw_buffer-> pushNexusData caugth unknown exception!" << std::endl;
-        // Should we stop acquisition if nx problem?
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
       }
     }
 
@@ -220,12 +233,16 @@ void BufferedCounterEvt::handle_raw_buffer(ni660Xsl::InRawBuffer* buffer, long&
       catch (Tango::DevFailed & df)
       {
         ERROR_STREAM << "BufferedCounterEvt::handle_raw_buffer-> pushNexusData caught DevFailed: " << df << std::endl;
-        // Should we stop acquisition if nx problem?
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
       }
       catch (...)
       {
         ERROR_STREAM << "BufferedCounterEvt::handle_raw_buffer-> pushNexusData caugth unknown exception!" << std::endl;
-        // Should we stop acquisition if nx problem?
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
       }
     }
   }
@@ -290,12 +307,16 @@ void BufferedCounterEvt::handle_raw_buffer(ni660Xsl::InRawBuffer* buffer, long&
         catch (Tango::DevFailed & df)
         {
 	        ERROR_STREAM << "BufferedCounterEvt::handle_raw_buffer-> pushNexusData caught DevFailed: " << df << std::endl;
-          // Should we stop acquisition if nx problem?
+          // We should stop acquisition if nx problem!
+          this->m_storageError = true;
+          this->stopCnt();
         }
         catch (...)
         {
 	        ERROR_STREAM << "BufferedCounterEvt::handle_raw_buffer-> pushNexusData caugth unknown exception!" << std::endl;
-          // Should we stop acquisition if nx problem?
+          // We should stop acquisition if nx problem!
+          this->m_storageError = true;
+          this->stopCnt();
         }
       }
 		}
@@ -330,6 +351,7 @@ void BufferedCounterEvt::startCnt()
 	DEBUG_STREAM << "BufferedCounterEvt::startCnt() entering..." << endl;
   this->m_cntOverrun = false;
   this->m_cntTimedout = false;
+  this->m_storageError = false;
 
 	{
 		yat::AutoMutex<> guard(this->m_buffLock);
diff --git a/src/BufferedCounterEvt.h b/src/BufferedCounterEvt.h
index 85f1aae7755548fd294cb2b05665ee20af66b8cf..37beb6fa3ac9b9fa2eafa4d2a0f92e3a2b77f4bb 100644
--- a/src/BufferedCounterEvt.h
+++ b/src/BufferedCounterEvt.h
@@ -145,6 +145,12 @@ public:
     return this->m_cntTimedout;
   }
 
+  // has counter stopped on storage error?
+  bool isStorageKO()
+  {
+    return this->m_storageError;
+  }
+
 protected:
 
 	// counter config
@@ -180,6 +186,9 @@ protected:
   // timeout flag
   bool m_cntTimedout;
 
+  // Storage error flag
+  bool m_storageError;
+
   // storage manager
   NexusManager * m_storage_mgr;
 };
diff --git a/src/BufferedCounterPeriod.cpp b/src/BufferedCounterPeriod.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9e4033d5c6a2f59ce575e8f280be8644c8807509
--- /dev/null
+++ b/src/BufferedCounterPeriod.cpp
@@ -0,0 +1,463 @@
+//=============================================================================
+// BufferedCounterPeriod.cpp
+//=============================================================================
+// abstraction.......BufferedCounterPeriod for PulseCounting
+// class.............BufferedCounterPeriod
+// original author...S.Minolli - Nexeya
+//=============================================================================
+
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <yat4tango/LogHelper.h>
+#include "BufferedCounterPeriod.h"
+
+namespace PulseCounting_ns
+{
+
+// ============================================================================
+// BufferedCounterPeriod::BufferedCounterPeriod ()
+// ============================================================================ 
+BufferedCounterPeriod::BufferedCounterPeriod (BCEconfig p_conf, NexusManager * storage)
+: yat4tango::TangoLogAdapter(p_conf.hostDevice)
+{
+	this->m_bufferNbToReceive = 0;
+	this->m_currentBufferNb = 0;
+	this->m_firstPtReceivedBuff = 0;
+	this->m_acquisitionDone = true;
+	this->m_dataBuffer_thread = NULL;
+  m_cntOverrun = false;
+  m_cntTimedout = false;
+  m_storageError = false;
+  m_data.clear();
+	m_cfg = p_conf;
+  m_storage_mgr = storage;
+}
+
+// ============================================================================
+// BufferedCounterPeriod::~BufferedCounterPeriod ()
+// ============================================================================ 
+BufferedCounterPeriod::~BufferedCounterPeriod ()
+{
+	
+}
+
+// ============================================================================
+// BufferedCounterPeriod::updateRawBuffer
+// ============================================================================
+void BufferedCounterPeriod::updateRawBuffer()
+  throw(Tango::DevFailed)
+{
+	// Delete "buffer recover" thread if exists and if data recovery is over
+	if (this->m_dataBuffer_thread)
+	{
+		if (this->m_dataBuffer_thread->updateDone())
+		{
+			yat::Thread::IOArg ioa;
+			this->m_dataBuffer_thread->exit();
+			this->m_dataBuffer_thread->join(&ioa);
+			//std::cout << "BufferedCounterPeriod::updateRawBuffer - BR thread exited for counter " 
+			//  << this->m_cfg.cnt.number << std::endl;
+			this->m_dataBuffer_thread = NULL; 
+		}
+	}
+
+	// Task the buffer reception if acquisition is on & if previous buffer recovery is over
+	if ((!this->m_acquisitionDone) && 
+		  (this->m_dataBuffer_thread == NULL))
+	{
+		this->m_dataBuffer_thread = new BRPRThread(m_cfg.hostDevice, static_cast<yat::Thread::IOArg>(this));
+		DEBUG_STREAM << "BufferedCounterPeriod Thread created ..." << endl;
+		if (this->m_dataBuffer_thread == NULL)
+		{
+			ERROR_STREAM << "Buffer recovery cannot be tasked for counter " 
+				<< this->m_cfg.cnt.number << std::endl;
+			THROW_DEVFAILED(
+        _CPTC("DEVICE_ERROR"),
+				_CPTC("Failed to start buffer recover task!"),
+				_CPTC("BufferedCounterPeriod::updateRawBuffer"));    
+		}
+		//std::cout << "BufferedCounterPeriod::updateRawBuffer - starting Buffer recovery thread for counter " 
+		//  << this->m_cfg.cnt.number << std::endl;
+		this->m_dataBuffer_thread->start_undetached();   
+	}
+}
+
+// ============================================================================
+// BufferedCounterPeriod::getRawBuffer
+// ============================================================================
+void BufferedCounterPeriod::getRawBuffer()
+{
+	// call "get raw buffer" to compose the whole buffer.
+	// In "polling" mode, the client has to poll to compose the acquisition buffer.
+	if (!this->m_acquisitionDone)
+	{
+		DEBUG_STREAM << "BufferedCounterPeriod::GetRawBuffer entering..." << endl;
+		//- from NI660Xsl - calls ni660Xsl::handle_xxx methods
+		try
+		{
+			ni660Xsl::BufferedPeriodMeasurement::get_raw_buffer(); // the driver waits 'buffer depth' seconds...
+		}
+		catch(ni660Xsl::DAQException & nie)
+		{
+			throw_devfailed(nie);
+		}
+	}
+}
+
+// ============================================================================
+// BufferedCounterPeriod::handle_timeout ()
+// ============================================================================ 
+void BufferedCounterPeriod::handle_timeout()
+  throw (Tango::DevFailed)
+{
+	ERROR_STREAM << "BufferedCounterPeriod::handle_timeout() entering..." << endl;
+	this->m_cntTimedout = true;
+}
+
+// ============================================================================
+// BufferedCounterPeriod::handle_data_lost ()
+// ============================================================================ 
+void BufferedCounterPeriod::handle_data_lost()
+  throw (Tango::DevFailed)
+{
+	ERROR_STREAM << "BufferedCounterPeriod::handle_data_lost() entering..." << endl;
+	this->m_cntOverrun = true;
+}
+
+// ============================================================================
+// BufferedCounterPeriod::handle_raw_buffer ()
+// ============================================================================ 
+void BufferedCounterPeriod::handle_raw_buffer(ni660Xsl::InRawBuffer* buffer, long& _samples_read)
+  throw (Tango::DevFailed)
+{
+  //- PERIOD values are not raw !!!
+  delete buffer;
+}
+
+// ============================================================================
+// BufferedCounterPeriod::handle_scaled_buffer ()
+// ============================================================================ 
+void BufferedCounterPeriod::handle_scaled_buffer(ni660Xsl::InScaledBuffer* buffer, long& _samples_read)
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BufferedCounterPeriod::handle_scaled_buffer() entering..." << std::endl;
+	DEBUG_STREAM << "BufferedCounterPeriod::handle_scaled_buffer() - samples to read = " << _samples_read << std::endl;
+
+  // check samples number is > 0
+  if (_samples_read <= 0)
+  {
+    ERROR_STREAM << "BufferedCounterPeriod::handle_scaled_buffer-> samples to read negative or null value!" << std::endl;
+    this->stopCnt();
+	return;
+  }	
+  
+	yat::AutoMutex<> guard(this->m_buffLock);
+
+	ni660Xsl::InScaledBuffer& buf = *buffer;
+	RawData_t & data = this->m_data;
+  bool data_to_be_stored = (this->m_cfg.acq.nexusFileGeneration && this->m_cfg.cnt.nexus);
+
+	//- Continuous acquisition: only one buffer is received !!
+	if (this->m_cfg.acq.continuousAcquisition)
+	{
+		DEBUG_STREAM << "continuous acquisition: nb buffer to receive = 1!" << std::endl;  
+
+		for (unsigned long idx = 0; idx < (unsigned long)_samples_read; idx++)
+		{
+			data[idx] = (data_t)(buf[idx]);
+		}
+
+    // store received buffer in Nexus, if nx storage enabled
+    if (data_to_be_stored && this->m_storage_mgr)
+    {
+      try
+      {
+        this->m_storage_mgr->pushNexusData(this->m_cfg.cnt.name, &data[0], (unsigned long)_samples_read);
+      }
+      catch (Tango::DevFailed & df)
+      {
+	      ERROR_STREAM << "BufferedCounterPeriod::handle_raw_buffer-> pushNexusData caught DevFailed: " << df << std::endl;
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
+      }
+      catch (...)
+      {
+	      ERROR_STREAM << "BufferedCounterPeriod::handle_raw_buffer-> pushNexusData caugth unknown exception!" << std::endl;
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
+      }
+    }
+
+    // stop acquisition
+		this->stopCnt();
+	}
+  else if (this->m_bufferNbToReceive == 0) //- infinite mode
+  {
+		DEBUG_STREAM << "one buffer received." << std::endl;
+
+		unsigned long nb_to_copy;
+		nb_to_copy = buf.depth();
+		DEBUG_STREAM << "NB to copy : " << nb_to_copy << endl;
+
+		for (unsigned long idx = 0; idx < nb_to_copy; idx++ )
+		{
+			data[idx] = (data_t)(buf[idx]);
+		}
+
+    // store received buffer in Nexus, if nx storage enabled for this counter
+    if (data_to_be_stored && this->m_storage_mgr)
+    {
+      try
+      {
+        this->m_storage_mgr->pushNexusData(this->m_cfg.cnt.name, &data[0], nb_to_copy);
+      }
+      catch (Tango::DevFailed & df)
+      {
+        ERROR_STREAM << "BufferedCounterPeriod::handle_raw_buffer-> pushNexusData caught DevFailed: " << df << std::endl;
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
+      }
+      catch (...)
+      {
+        ERROR_STREAM << "BufferedCounterPeriod::handle_raw_buffer-> pushNexusData caugth unknown exception!" << std::endl;
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
+      }
+    }
+  }
+	else //- not continuous nor infinite
+	{
+		//- All buffers have not been yet received
+		if (this->m_currentBufferNb < this->m_bufferNbToReceive)
+		{
+			DEBUG_STREAM << "buffer currently received = " << this->m_currentBufferNb + 1 << " on " << this->m_bufferNbToReceive << std::endl;
+			unsigned long nb_to_copy;
+
+			if (((unsigned long)this->m_cfg.acq.samplesNumber - this->m_firstPtReceivedBuff) < buf.depth())
+			{
+				nb_to_copy = (unsigned long)this->m_cfg.acq.samplesNumber - this->m_firstPtReceivedBuff;
+			}
+			else
+			{
+				nb_to_copy = buf.depth();
+			}
+			DEBUG_STREAM << "NB to copy : " << nb_to_copy << endl;
+
+      // tempo buffer for storage
+      RawData_t bufNx;
+      if (data_to_be_stored)
+      {
+        // force length with _samples_read because in the case of incomplete buffer 
+        // (i.e. last buffer to receive), the nx manager requires fixed length = buffer depth size
+        bufNx.capacity(_samples_read);
+        bufNx.force_length(_samples_read);
+        bufNx.fill(yat::IEEE_NAN);
+      }
+
+			for (unsigned long idx = 1; idx < nb_to_copy; idx++ )
+			{
+				data[idx + this->m_firstPtReceivedBuff] = (data_t)(buf[idx]);
+        if (data_to_be_stored)
+          bufNx[idx] = data[idx + this->m_firstPtReceivedBuff];
+			}
+
+			//- at start, m_firstPtReceivedBuff equals 0.
+			//- m_firstPtReceivedBuff is the position of the 1st point of the buffer
+			data[this->m_firstPtReceivedBuff] = (data_t)(buf[0]);
+      if (data_to_be_stored)
+        bufNx[0] = data[this->m_firstPtReceivedBuff];
+
+			this->m_currentBufferNb++;
+			this->m_firstPtReceivedBuff += nb_to_copy;
+
+      // store received buffer in Nexus, if nx storage enabled for this counter
+      if (data_to_be_stored && this->m_storage_mgr)
+      {
+        try
+        {
+          this->m_storage_mgr->pushNexusData(this->m_cfg.cnt.name, &bufNx[0], nb_to_copy);
+        }
+        catch (Tango::DevFailed & df)
+        {
+	        ERROR_STREAM << "BufferedCounterPeriod::handle_raw_buffer-> pushNexusData caught DevFailed: " << df << std::endl;
+          // We should stop acquisition if nx problem!
+          this->m_storageError = true;
+          this->stopCnt();
+        }
+        catch (...)
+        {
+	        ERROR_STREAM << "BufferedCounterPeriod::handle_raw_buffer-> pushNexusData caugth unknown exception!" << std::endl;
+          // We should stop acquisition if nx problem!
+          this->m_storageError = true;
+          this->stopCnt();
+        }
+      }
+		}
+
+		// if all requested buffers are received 
+		if (this->m_currentBufferNb == this->m_bufferNbToReceive)
+		{	
+			// stop acquisition
+			this->stopCnt();
+		}
+	}
+
+  delete buffer;
+}
+
+// ============================================================================
+// BufferedCounterPeriod::startCnt
+// ============================================================================
+void BufferedCounterPeriod::startCnt()
+  throw (Tango::DevFailed)
+{
+	DEBUG_STREAM << "BufferedCounterPeriod::startCnt() entering..." << endl;
+  this->m_cntOverrun = false;
+  this->m_cntTimedout = false;
+  this->m_storageError = false;
+
+	{
+		yat::AutoMutex<> guard(this->m_buffLock);
+
+    // reset current counters & buffers
+		this->m_currentBufferNb = 0;
+		this->m_firstPtReceivedBuff = 0;
+		this->m_acquisitionDone = false;
+
+    // check if infinite mode
+    if (this->m_cfg.acq.samplesNumber == 0)
+    {
+      // set data length to buffer depth
+	    this->m_data.capacity(this->m_cfg.acq.bufferDepth);
+	    this->m_data.force_length(this->m_cfg.acq.bufferDepth);
+    }
+    else
+    {
+      // set data length to samples nber
+	    this->m_data.capacity(this->m_cfg.acq.samplesNumber);
+	    this->m_data.force_length(this->m_cfg.acq.samplesNumber);
+    }
+	  this->m_data.fill(yat::IEEE_NAN);
+
+		unsigned long buffer_depth_nbpts = 0;
+
+		if (this->m_cfg.acq.continuousAcquisition)
+		{
+			buffer_depth_nbpts = this->m_cfg.acq.samplesNumber;
+		}
+		else
+		{
+			buffer_depth_nbpts = static_cast<unsigned long>(this->m_cfg.acq.bufferDepth);
+		}
+		m_bufferNbToReceive = (m_cfg.acq.samplesNumber + buffer_depth_nbpts - 1) / buffer_depth_nbpts;
+		DEBUG_STREAM << "Buffer to receive : " << m_bufferNbToReceive << endl;
+	}
+
+	//- from NI660Xsl
+  try
+  {
+	  ni660Xsl::BufferedPeriodMeasurement::start();
+  }
+	catch(ni660Xsl::DAQException & nie)
+	{
+		throw_devfailed(nie);
+	}
+
+#if !defined (USE_CALLBACK) 
+	// start the data buffer waiting task for the 1st time
+	this->updateRawBuffer();
+#endif
+}
+
+// ============================================================================
+// BufferedCounterPeriod::stopCnt
+// ============================================================================
+void BufferedCounterPeriod::stopCnt()
+  throw (Tango::DevFailed)
+{
+  DEBUG_STREAM << "BufferedCounterPeriod::stopCnt() entering..." << endl;
+	this->m_acquisitionDone = true;
+
+  try
+  {
+    //- from NI660Xsl
+    ni660Xsl::BufferedPeriodMeasurement::abort(); // we use abort to stop counting immediately
+	  ni660Xsl::BufferedPeriodMeasurement::release(); // sets an UNKNOWN state in NI660Xsl lib !
+  }
+	catch(...)
+	{
+	  // DAQmx 9.x abort pb workaround
+		ERROR_STREAM << "BufferedCounterPeriod::stopCnt() - Aborting counter generates exception, do nothing..." << std::endl;
+	}
+}
+
+// ============================================================================
+// BufferedCounterPeriod::get_value ()
+// ============================================================================ 
+RawData_t & BufferedCounterPeriod::get_value()
+{
+  yat::AutoMutex<> guard(this->m_buffLock);
+  return this->m_data;
+}
+
+//*****************************************************************************
+// BRPRThread
+//*****************************************************************************
+// ============================================================================
+// BRPRThread::BRPRThread
+// ============================================================================
+BRPRThread::BRPRThread (Tango::DeviceImpl * hostDevice, yat::Thread::IOArg ioa)
+: yat::Thread(ioa),
+Tango::LogAdapter (hostDevice),
+m_goOn(true),
+m_isUpdateDone(false)
+{
+	//- noop ctor
+}
+
+// ============================================================================
+// BRPRThread::~BRPRThread
+// ============================================================================
+BRPRThread::~BRPRThread (void)
+{
+	//- noop dtor
+}
+
+// ============================================================================
+// BRPRThread::run_undetached
+// ============================================================================
+yat::Thread::IOArg BRPRThread::run_undetached (yat::Thread::IOArg ioa)
+{
+	DEBUG_STREAM << "BRPRThread::run_undetached() entering... " << std::endl;
+
+	m_isUpdateDone = false;
+	//- get ref. to out our parent task
+	BufferedCounterPeriod * cm_task = reinterpret_cast<BufferedCounterPeriod *>(ioa);
+
+	//std::cout << "**Wait for buffer value to be set from board..." << std::endl;
+	cm_task->getRawBuffer(); 
+
+	// when function returns, the buffer is handled (or timeout if no data)
+	//std::cout << "**Buffer update done." << std::endl;
+	m_isUpdateDone = true;
+
+	return 0;
+}
+
+
+// ============================================================================
+// BRPRThread::exit
+// ============================================================================
+void BRPRThread::exit (void)
+{
+	this->m_goOn = false;
+}
+
+} // namespace PulseCounting_ns
+
diff --git a/src/BufferedCounterPeriod.h b/src/BufferedCounterPeriod.h
new file mode 100644
index 0000000000000000000000000000000000000000..2056efaac110ea1c950e652b5310560d5f433e8f
--- /dev/null
+++ b/src/BufferedCounterPeriod.h
@@ -0,0 +1,195 @@
+//=============================================================================
+// BufferedCounterPeriod.h
+//=============================================================================
+// abstraction.......BufferedCounterPeriod for PulseCounting
+// class.............BufferedCounterPeriod
+// original author...S.Minolli - Nexeya
+//=============================================================================
+
+#ifndef _BUFFERED_COUNTER_PRD_H
+#define _BUFFERED_COUNTER_PRD_H
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <yat4tango/LogHelper.h>
+#include "PulseCountingTypesAndConsts.h"
+#include <NI660Xsl/BufferedPeriodMeasurement.h>
+#include <yat/threading/Thread.h>
+#include <yat4tango/ExceptionHelper.h>
+#include "NexusManager.h"
+
+namespace PulseCounting_ns
+{
+
+
+	// ============================================================================
+	// class: BRPRThread
+	// ============================================================================
+	class BRPRThread : public yat::Thread, public Tango::LogAdapter
+	{
+		friend class BufferedCounterPeriod;
+
+	protected:
+		//- ctor ---------------------------------
+		BRPRThread (Tango::DeviceImpl * hostDevice, yat::Thread::IOArg ioa);
+
+		//- dtor ---------------------------------
+		virtual ~BRPRThread (void);
+
+		//- thread's entry point
+		virtual yat::Thread::IOArg run_undetached (yat::Thread::IOArg ioa);
+
+		//- asks this BRPRThread to quit
+		virtual void exit (void);
+
+		//- Thread state
+		bool isThreadAlive()
+		{
+			return m_goOn;
+		}
+
+		//- Buffer update state
+		bool updateDone()
+		{
+			return m_isUpdateDone;
+		}
+
+	private:
+		//- thread's ctrl flag
+		bool m_goOn;
+
+		//- data update done
+		bool m_isUpdateDone;
+	};
+
+
+
+// ============================================================================
+// class: BufferedCounterPeriod
+// ============================================================================
+class BufferedCounterPeriod : public yat4tango::TangoLogAdapter, public ni660Xsl::BufferedPeriodMeasurement
+{
+public:
+
+  //- constructor
+  BufferedCounterPeriod (BCEconfig p_conf, NexusManager * storage);
+
+  //- destructor
+  virtual ~BufferedCounterPeriod ();
+
+  //*********** NI660Xsl inheritance  ****************
+  // These handle_xxx functions are called directly by NI660XSl lib in "callback mode" and
+  // called after wait task ends in "polling" mode.
+
+  //- handle timeout
+  void handle_timeout()
+	  throw (Tango::DevFailed);
+
+  //- handle data lost
+  void handle_data_lost()
+	  throw (Tango::DevFailed);
+
+  //- handle raw buffer
+  void handle_raw_buffer(ni660Xsl::InRawBuffer* buffer, long& _samples_read)
+	  throw (Tango::DevFailed);
+
+  //- handle scaled buffer
+  void handle_scaled_buffer(ni660Xsl::InScaledBuffer* buffer, long& _samples_read)
+	  throw (Tango::DevFailed);
+
+
+  //********** local members  ****************
+  // start counter
+  void startCnt()
+    throw (Tango::DevFailed);
+
+  // stop counter
+  void stopCnt()
+    throw (Tango::DevFailed);
+
+  //- set local value
+  void set_value();
+
+  //- get value
+  RawData_t & get_value();
+
+  // Acquisition done info
+  bool isAcquisitionDone()
+  {
+    yat::AutoMutex<> guard(this->m_buffLock);
+	  return this->m_acquisitionDone;
+  }
+
+  // updates raw buffer <=> starts waiting task if not already running
+  // (used in "polling" mode)
+  void updateRawBuffer()
+	  throw(Tango::DevFailed);
+
+	// gets raw buffer <=> calls the driver waiting task (used in "polling" mode)
+  void getRawBuffer();
+
+  //- release counter
+  void deleteObject()
+	  throw (Tango::DevFailed);
+
+  // is counter in overrun ?
+  bool isOverrun()
+  {
+    return this->m_cntOverrun;
+  }
+
+  // has counter timed out ?
+  bool isTimedout()
+  {
+    return this->m_cntTimedout;
+  }
+
+  // has counter stopped on storage error?
+  bool isStorageKO()
+  {
+    return this->m_storageError;
+  }
+
+protected:
+
+	// counter config
+	BCEconfig m_cfg;
+
+	// total number of buffers to receive for each acquisition
+	unsigned long m_bufferNbToReceive;
+
+	// current number of buffers actually received
+	unsigned long m_currentBufferNb;
+
+	// First point of the currently received buffer
+	unsigned long m_firstPtReceivedBuff;
+
+	// raw data buffer
+	RawData_t m_data;
+
+	// Acquisition done flag
+	bool m_acquisitionDone;
+
+	//- data mutex protection
+	yat::Mutex m_buffLock;
+
+	// Data buffer waiting task
+	BRPRThread * m_dataBuffer_thread;
+
+  // overrun flag
+  bool m_cntOverrun;
+
+  // timeout flag
+  bool m_cntTimedout;
+
+  // Storage error flag
+  bool m_storageError; // soso crash rock
+
+  // storage manager
+  NexusManager * m_storage_mgr;
+};
+
+} // namespace PulseCounting_ns
+
+#endif // _BUFFERED_COUNTER_PRD_H
diff --git a/src/BufferedCounterPos.cpp b/src/BufferedCounterPos.cpp
index e2e7551d20641091d54665c0d6650911bb8c87fa..7dc900a9fd88d8e5c457c10edcc15e64c0e20f83 100644
--- a/src/BufferedCounterPos.cpp
+++ b/src/BufferedCounterPos.cpp
@@ -30,6 +30,7 @@ BufferedCounterPos::BufferedCounterPos (BCEconfig p_conf, NexusManager * storage
 	this->m_dataBuffer_thread = NULL;
   this->m_cntOverrun = false;
   this->m_cntTimedout = false;
+  this->m_storageError = false;
 	m_data.clear();
 	m_cfg = p_conf;
   m_storage_mgr = storage;
@@ -144,6 +145,14 @@ void BufferedCounterPos::handle_scaled_buffer(ni660Xsl::InScaledBuffer* buffer,
 	DEBUG_STREAM << "BufferedCounterPos::handle_scaled_buffer() entering..." << std::endl;
 	DEBUG_STREAM << "BufferedCounterPos::handle_scaled_buffer() - samples to read = " << _samples_read << std::endl;
 
+  // check samples number is > 0
+  if (_samples_read <= 0)
+  {
+    ERROR_STREAM << "BufferedCounterPos::handle_scaled_buffer-> samples to read negative or null value!" << std::endl;
+    this->stopCnt();
+	return;
+  }
+
   yat::AutoMutex<> guard(this->m_buffLock);
 
 	ni660Xsl::InScaledBuffer& buf = *buffer;
@@ -178,12 +187,16 @@ void BufferedCounterPos::handle_scaled_buffer(ni660Xsl::InScaledBuffer* buffer,
       catch (Tango::DevFailed & df)
       {
 	      ERROR_STREAM << "BufferedCounterPos::handle_scaled_buffer-> pushNexusData caught DevFailed: " << df << std::endl;
-        // Should we stop acquisition if nx problem?
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
       }
       catch (...)
       {
 	      ERROR_STREAM << "BufferedCounterPos::handle_scaled_buffer-> pushNexusData caugth unknown exception!" << std::endl;
-        // Should we stop acquisition if nx problem?
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
       }
     }
 
@@ -251,12 +264,16 @@ void BufferedCounterPos::handle_scaled_buffer(ni660Xsl::InScaledBuffer* buffer,
       catch (Tango::DevFailed & df)
       {
         ERROR_STREAM << "BufferedCounterPos::handle_scaled_buffer-> pushNexusData caught DevFailed: " << df << std::endl;
-        // Should we stop acquisition if nx problem?
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
       }
       catch (...)
       {
         ERROR_STREAM << "BufferedCounterPos::handle_scaled_buffer-> pushNexusData caugth unknown exception!" << std::endl;
-        // Should we stop acquisition if nx problem?
+        // We should stop acquisition if nx problem!
+        this->m_storageError = true;
+        this->stopCnt();
       }
     }
   }
@@ -334,12 +351,16 @@ void BufferedCounterPos::handle_scaled_buffer(ni660Xsl::InScaledBuffer* buffer,
         catch (Tango::DevFailed & df)
         {
 	        ERROR_STREAM << "BufferedCounterPos::handle_scaled_buffer-> pushNexusData caught DevFailed: " << df << std::endl;
-          // Should we stop acquisition if nx problem?
+          // We should stop acquisition if nx problem!
+          this->m_storageError = true;
+          this->stopCnt();
         }
         catch (...)
         {
 	        ERROR_STREAM << "BufferedCounterPos::handle_scaled_buffer-> pushNexusData caugth unknown exception!" << std::endl;
-          // Should we stop acquisition if nx problem?
+          // We should stop acquisition if nx problem!
+          this->m_storageError = true;
+          this->stopCnt();
         }
       }
 		}
@@ -364,6 +385,7 @@ void BufferedCounterPos::startCnt()
   DEBUG_STREAM << "BufferedCounterPos::startCnt() entering..." << endl;
   this->m_cntOverrun = false;
   this->m_cntTimedout = false;
+  this->m_storageError = false;
 
 	{
 		yat::AutoMutex<> guard(this->m_buffLock);
diff --git a/src/BufferedCounterPos.h b/src/BufferedCounterPos.h
index ec64fa51c3199bdf2937064c155b9d0131dd13e9..1d4e751759b4f6e30488a395c1738b6aa65fab8e 100644
--- a/src/BufferedCounterPos.h
+++ b/src/BufferedCounterPos.h
@@ -141,6 +141,13 @@ public:
     return this->m_cntTimedout;
   }
 
+  // has counter stopped on storage error?
+  bool isStorageKO()
+  {
+    return this->m_storageError;
+  }
+
+
 protected:
 	// counter config
 	BCEconfig m_cfg;
@@ -175,6 +182,9 @@ protected:
   // timeout flag
   bool m_cntTimedout;
 
+  // Storage error flag
+  bool m_storageError;
+
   // storage manager
   NexusManager * m_storage_mgr;
 };
diff --git a/src/ConfigurationParser.cpp b/src/ConfigurationParser.cpp
index c11fa7b4b00c4b50282b4ec668df2f6c37f24f87..2b6f7f17912db676dcd6031b1c60bac8ce588980 100644
--- a/src/ConfigurationParser.cpp
+++ b/src/ConfigurationParser.cpp
@@ -269,6 +269,10 @@ E_CounterMode_t ConfigurationParser::extractMode (CounterKeys_t acq_config)
   {
     mode = COUNTER_MODE_DELTATIME;
   }
+  else if (0 == tokenValue.compare(kKEY_MODE_PERIOD))
+  {
+    mode = COUNTER_MODE_PERIOD;
+  }
   else
   {
     // bad value ==> fatal error
diff --git a/src/ConfigurationParser.h b/src/ConfigurationParser.h
index 113e2e19315006e2b8a38566f68992dfd3fd9653..1eb6c539f69ff24720b42df186ebc6af33f4951b 100644
--- a/src/ConfigurationParser.h
+++ b/src/ConfigurationParser.h
@@ -25,15 +25,14 @@ namespace PulseCounting_ns
 static const std::string kKEY_VALUE_SEPARATOR (":");
 static const std::string kVALUE_SEPARATOR_CL (":");
 static const std::string kVALUE_SEPARATOR_COMA (",");
-static const std::string kCONFIG_NAME ("Counter");
 
 //- property strings for config
-static const std::string kKEY_COUNTER ("Counter");
 static const std::string kKEY_NAME ("Name");
 static const std::string kKEY_MODE ("Mode");
 static const std::string kKEY_MODE_EVT ("EVT");
 static const std::string kKEY_MODE_POS ("POS");
 static const std::string kKEY_MODE_DT ("DT");
+static const std::string kKEY_MODE_PERIOD ("PERIOD");
 static const std::string kKEY_TRANSFER ("Transfer");
 static const std::string kKEY_TRANSFER_DMA ("DMA");
 static const std::string kKEY_TRANSFER_ITR ("ITR");
diff --git a/src/CounterFactory.cpp b/src/CounterFactory.cpp
index 190beb1622ad987f0dd44967b23411ca29ed805c..e555c5c937e685082fb6f62988415689617f0784 100644
--- a/src/CounterFactory.cpp
+++ b/src/CounterFactory.cpp
@@ -14,6 +14,7 @@
 #include "EventCounter.h"
 #include "PositionCounter.h"
 #include "DeltaTimeCounter.h"
+#include "PeriodCounter.h"
 
 namespace PulseCounting_ns
 {
@@ -37,6 +38,9 @@ GenericCounterInterface * CounterFactory::instanciate (Tango::DeviceImpl * hostD
   case COUNTER_MODE_DELTATIME:
 	  l_counter = new DeltaTimeCounter(hostDevice, p_acq_mode, p_board);
 	  break;
+  case COUNTER_MODE_PERIOD:
+	  l_counter = new PeriodCounter(hostDevice, p_acq_mode, p_board);
+	  break;
   case UNDEFINED_COUNTER_MODE:
 	  l_counter = NULL;
 	  break;
diff --git a/src/NI6602_Interface.cpp b/src/NI6602_Interface.cpp
index 0f5f07a8998cd1ca7207854cea093b54c0120c1c..07437f5ab0e7f25986bf3b801f266f00c430794c 100644
--- a/src/NI6602_Interface.cpp
+++ b/src/NI6602_Interface.cpp
@@ -79,6 +79,13 @@ void NI6602_Interface::initCounter(CounterConfig p_cfg)
 					  m_scalar_dt_ct_list[p_cfg.name] = NULL;
 				  }
 				  break;
+			  case COUNTER_MODE_PERIOD:
+				  if (m_scalar_prd_ct_list[p_cfg.name])
+				  {
+					  delete m_scalar_prd_ct_list[p_cfg.name];
+					  m_scalar_prd_ct_list[p_cfg.name] = NULL;
+				  }
+				  break;
         default:
 				  break;
 		  }
@@ -108,6 +115,13 @@ void NI6602_Interface::initCounter(CounterConfig p_cfg)
 				  m_buffer_dt_ct_list[p_cfg.name] = NULL;
 			  }
 			  break;
+		  case COUNTER_MODE_PERIOD:
+			  if (m_buffer_prd_ct_list[p_cfg.name])
+			  {
+				  delete m_buffer_prd_ct_list[p_cfg.name];
+				  m_buffer_prd_ct_list[p_cfg.name] = NULL;
+			  }
+			  break;
 		  default:
 			  break;
 		}
@@ -313,6 +327,7 @@ void NI6602_Interface::configureCounter(CounterConfig p_cfg)
 	ni660Xsl::EventCountChan l_evtConfig;
 	ni660Xsl::PositionChan l_posConfig;
   ni660Xsl::DeltaTimeChan l_dtConfig;
+  ni660Xsl::PeriodChan l_prdConfig;
 	ni660Xsl::AngularEncoderChan l_angConfig;
 	ni660Xsl::LinearEncoderChan l_linConfig;
 	ni::AngleUnitsType l_angleUnits;
@@ -585,6 +600,43 @@ void NI6602_Interface::configureCounter(CounterConfig p_cfg)
 				  break;
 		  }
       l_dtConfig.units = l_dtUnits;
+      break;
+
+    //********************************************************************/
+    // PERIOD COUNTER
+    //********************************************************************/
+	  case COUNTER_MODE_PERIOD:
+		  l_prdConfig.chan_name = std::string("/") + p_cfg.boardName + std::string("/") + std::string("ctr")
+			  + yat::XString<size_t>::to_string(p_cfg.number);
+
+		  ni::EdgeType edge;
+		  switch (p_cfg.edge)
+		  {
+		    case COUNTING_EDGE_RISING:
+			    edge = ni::rising_edge;
+			    break;
+		    case COUNTING_EDGE_FALLING:
+			    edge = ni::falling_edge;
+			    break;
+		    default:
+			    edge = ni::rising_edge; //default value if not defined
+			    break;
+		  }
+		  l_prdConfig.edge = edge;
+		  
+      switch (p_cfg.dt_unit)
+		  {
+			  case ENC_UNIT_TICK:
+				  l_dtUnits = ni::time_ticks;
+				  break;
+			  case ENC_UNIT_SEC:
+				  l_dtUnits = ni::seconds;
+				  break;
+        default:
+				  l_dtUnits = ni::seconds;
+				  break;
+		  }
+      l_prdConfig.units = l_dtUnits;
       break;
 
 	  default:
@@ -703,6 +755,40 @@ void NI6602_Interface::configureCounter(CounterConfig p_cfg)
 		    throw_devfailed(nie);
 	    }
     }
+    else if (p_cfg.mode == COUNTER_MODE_PERIOD) 
+    {
+      // Create PERIOD counting object and configure it
+	    try
+	    {
+		    m_scalar_prd_ct_list[p_cfg.name] = new ni660Xsl::SimplePeriodMeasurement();
+
+        if (m_scalar_prd_ct_list[p_cfg.name])
+        {
+	        std::string pause_trigger;
+          // Check board
+	        if ((this->m_clk_cfg.channelName.compare(CLOCK_INTERNAL) == 0) &&
+              (this->m_clk_cfg.boardName.compare(p_cfg.boardName) == 0))
+	        {
+		        // Master board: generates clock on ctr0 = trigger
+		        pause_trigger = "/"  + p_cfg.boardName + "/ctr0InternalOutput";
+	        }
+	        else
+	        {
+		        // Not master board: receives external clock on PFI38
+		        pause_trigger = "/"  + p_cfg.boardName + "/PFI38";
+	        }
+
+		      m_scalar_prd_ct_list[p_cfg.name]->set_pause_trigger(pause_trigger, ni::low);
+		      m_scalar_prd_ct_list[p_cfg.name]->add_input_channel(l_prdConfig);
+		      m_scalar_prd_ct_list[p_cfg.name]->init();
+		      m_scalar_prd_ct_list[p_cfg.name]->configure();  
+        }
+	    }
+	    catch(ni660Xsl::DAQException & nie)
+	    {
+		    throw_devfailed(nie);
+	    }
+    }
     else
     {
       // bad counter mode, nothing to do...
@@ -930,6 +1016,68 @@ void NI6602_Interface::configureCounter(CounterConfig p_cfg)
 				throw_devfailed(nie);
 			}
     }
+    else if (p_cfg.mode == COUNTER_MODE_PERIOD)
+    {
+      // Create PERIOD counting object and configure it
+      try
+      {
+        m_buffer_prd_ct_list[p_cfg.name] = new BufferedCounterPeriod(l_conf, m_storage);
+
+        if (m_buffer_prd_ct_list[p_cfg.name])
+        {
+					// Define acquisition
+					m_buffer_prd_ct_list[p_cfg.name]->set_timeout(m_cfg.timeout);
+					m_buffer_prd_ct_list[p_cfg.name]->set_overrun_strategy(ni::notify);
+					m_buffer_prd_ct_list[p_cfg.name]->set_timing_mode(ni::continuous);
+					m_buffer_prd_ct_list[p_cfg.name]->set_buffer_depth(buffer_depth_nbpts);
+
+					if (p_cfg.memTranfer == MEMORY_TRSF_DMA)
+					{
+						m_buffer_prd_ct_list[p_cfg.name]->set_data_tranfer_mechanism(ni::dma);
+					}
+					else
+					{
+						m_buffer_prd_ct_list[p_cfg.name]->set_data_tranfer_mechanism(ni::interrupts);
+					}
+
+					std::string pause_trigger;
+          // Check board
+	        if ((this->m_clk_cfg.channelName.compare(CLOCK_INTERNAL) == 0) &&
+              (this->m_clk_cfg.boardName.compare(p_cfg.boardName) == 0))
+					{
+						// Master board: generates clock on ctr0 = trigger
+						pause_trigger = "/"  + p_cfg.boardName + "/ctr0InternalOutput";
+					}
+					else
+					{
+						// Not master board: receives external clock on PFI38
+						pause_trigger = "/"  + p_cfg.boardName + "/PFI38";
+					}
+
+					double max_rate = 1.1 / m_cfg.integrationTime;
+					m_buffer_prd_ct_list[p_cfg.name]->set_sample_clock(pause_trigger, ni::rising_edge, max_rate);
+
+					if (this->m_cfg.startTriggerUse)
+					{
+						m_buffer_prd_ct_list[p_cfg.name]->set_start_trigger(pause_trigger, ni::rising_edge);
+					}
+
+#if defined (USE_CALLBACK) 
+				  DEBUG_STREAM << "Callback mode set" << std::endl;
+          m_buffer_prd_ct_list[p_cfg.name]->set_callback_mode(true);
+          m_buffer_prd_ct_list[p_cfg.name]->set_total_nb_pts(this->m_cfg.samplesNumber);
+#endif					
+
+					m_buffer_prd_ct_list[p_cfg.name]->add_input_channel(l_prdConfig);
+					m_buffer_prd_ct_list[p_cfg.name]->init();
+					m_buffer_prd_ct_list[p_cfg.name]->configure();
+        }
+      }
+			catch(ni660Xsl::DAQException & nie)
+			{
+				throw_devfailed(nie);
+			}
+    }
     else
     {
       // bad counter mode, nothing to do...
@@ -963,6 +1111,9 @@ void NI6602_Interface::startCounter(CounterConfig p_cfg)
 			    case COUNTER_MODE_DELTATIME:
 				    m_scalar_dt_ct_list[p_cfg.name]->start();
 				    break;
+			    case COUNTER_MODE_PERIOD:
+				    m_scalar_prd_ct_list[p_cfg.name]->start();
+				    break;
           default:
 				    break;
 			  }
@@ -980,7 +1131,10 @@ void NI6602_Interface::startCounter(CounterConfig p_cfg)
 			    case COUNTER_MODE_DELTATIME:
 				    m_buffer_dt_ct_list[p_cfg.name]->startCnt();
 				    break;
-			    default:
+			    case COUNTER_MODE_PERIOD:
+				    m_buffer_prd_ct_list[p_cfg.name]->startCnt();
+				    break;
+          default:
 				    break;
 			  }
 			  break;
@@ -1023,6 +1177,11 @@ void NI6602_Interface::stopCounter(CounterConfig p_cfg)
 				    m_scalar_dt_ct_list[p_cfg.name]->stop();
 				    m_scalar_dt_ct_list[p_cfg.name]->release();
 				    break;
+			    case COUNTER_MODE_PERIOD:
+            //- from NI660XSl
+				    m_scalar_prd_ct_list[p_cfg.name]->stop();
+				    m_scalar_prd_ct_list[p_cfg.name]->release();
+				    break;
           default:
 				    break;
 			  }
@@ -1040,6 +1199,9 @@ void NI6602_Interface::stopCounter(CounterConfig p_cfg)
 				  case COUNTER_MODE_DELTATIME:
 					  m_buffer_dt_ct_list[p_cfg.name]->stopCnt();
 					  break;
+				  case COUNTER_MODE_PERIOD:
+					  m_buffer_prd_ct_list[p_cfg.name]->stopCnt();
+					  break;
           default:
 					  break;
 				}
@@ -1301,6 +1463,7 @@ Tango::DevState NI6602_Interface::getCounterState(CounterConfig p_cfg)
 
   bool l_overrun = false;
   bool l_timedout = false;
+  bool l_storageErr = false; // soso crash rock
 
 
 	switch (m_acq_mode)
@@ -1314,7 +1477,7 @@ Tango::DevState NI6602_Interface::getCounterState(CounterConfig p_cfg)
             if (m_scalar_pos_ct_list[p_cfg.name])
             {
               // get underlying counter state
-				      l_state =  m_scalar_pos_ct_list[p_cfg.name]->state();
+				      l_state = m_scalar_pos_ct_list[p_cfg.name]->state();
             }
             else
             {
@@ -1353,6 +1516,24 @@ Tango::DevState NI6602_Interface::getCounterState(CounterConfig p_cfg)
 				      l_state = m_scalar_dt_ct_list[p_cfg.name]->state();
             }
             else
+            {
+              l_state = ni660Xsl::InputOperation::UNKNOWN;
+            }
+			    }
+			    catch (...)
+			    {
+				    l_state = -1;
+			    }
+			    break;
+		    case COUNTER_MODE_PERIOD:
+			    try
+			    {
+            if (m_scalar_prd_ct_list[p_cfg.name])
+            {
+              // get underlying counter state
+				      l_state = m_scalar_prd_ct_list[p_cfg.name]->state();
+            }
+            else
             {
               l_state = ni660Xsl::InputOperation::UNKNOWN;
             }
@@ -1379,9 +1560,10 @@ Tango::DevState NI6602_Interface::getCounterState(CounterConfig p_cfg)
             // get underlying counter state
 				    l_state = m_buffer_pos_ct_list[p_cfg.name]->state();
 
-            // get buffering errors (overrun or timeout)
+            // get buffering errors (overrun, timeout or storage error)
             l_overrun = m_buffer_pos_ct_list[p_cfg.name]->isOverrun();
             l_timedout = m_buffer_pos_ct_list[p_cfg.name]->isTimedout();
+            l_storageErr = m_buffer_pos_ct_list[p_cfg.name]->isStorageKO(); // soso crash rock
           }
           else
           {
@@ -1402,9 +1584,10 @@ Tango::DevState NI6602_Interface::getCounterState(CounterConfig p_cfg)
             // get underlying counter state
 				    l_state = m_buffer_evt_ct_list[p_cfg.name]->state();
 
-            // get buffering errors (overrun or timeout)
+            // get buffering errors (overrun, timeout or storage error)
             l_overrun = m_buffer_evt_ct_list[p_cfg.name]->isOverrun();
             l_timedout = m_buffer_evt_ct_list[p_cfg.name]->isTimedout();
+            l_storageErr = m_buffer_evt_ct_list[p_cfg.name]->isStorageKO(); // soso crash rock
           }
           else
           {
@@ -1424,9 +1607,33 @@ Tango::DevState NI6602_Interface::getCounterState(CounterConfig p_cfg)
             // get underlying counter state
 				    l_state = m_buffer_dt_ct_list[p_cfg.name]->state();
 
-            // get buffering errors (overrun or timeout)
+            // get buffering errors (overrun, timeout or storage error)
             l_overrun = m_buffer_dt_ct_list[p_cfg.name]->isOverrun();
             l_timedout = m_buffer_dt_ct_list[p_cfg.name]->isTimedout();
+            l_storageErr = m_buffer_dt_ct_list[p_cfg.name]->isStorageKO(); // soso crash rock
+          }
+          else
+          {
+            l_state = ni660Xsl::InputOperation::UNKNOWN;
+          }
+			  }
+			  catch (...)
+			  {
+				  l_state = -1;
+			  }
+			  break;
+		  case COUNTER_MODE_PERIOD:
+			  try
+			  {
+          if (m_buffer_prd_ct_list[p_cfg.name])
+          {
+            // get underlying counter state
+				    l_state = m_buffer_prd_ct_list[p_cfg.name]->state();
+
+            // get buffering errors (overrun, timeout or storage error)
+            l_overrun = m_buffer_prd_ct_list[p_cfg.name]->isOverrun();
+            l_timedout = m_buffer_prd_ct_list[p_cfg.name]->isTimedout();
+            l_storageErr = m_buffer_prd_ct_list[p_cfg.name]->isStorageKO(); // soso crash rock
           }
           else
           {
@@ -1478,6 +1685,9 @@ Tango::DevState NI6602_Interface::getCounterState(CounterConfig p_cfg)
   if (l_timedout)
     l_val = Tango::DISABLE;
 
+  if (l_storageErr) // soso crash rock
+    l_val = Tango::FAULT;
+
 	return l_val;
 }
 
@@ -1521,6 +1731,16 @@ data_t NI6602_Interface::getCounterScalarValue(CounterConfig p_cfg)
 			  l_val = -1;
 		  }
 		  break;
+	  case COUNTER_MODE_PERIOD:
+		  try
+		  {
+			  l_val = m_scalar_prd_ct_list[p_cfg.name]->get_current_scaled_value();
+		  }
+		  catch (...)
+		  {
+			  l_val = -1;
+		  }
+		  break;
     default:
 		  break;
 	}
@@ -1553,6 +1773,12 @@ RawData_t & NI6602_Interface::getCounterBufferValue(CounterConfig p_cfg)
 		    return m_buffer_dt_ct_list[p_cfg.name]->get_value();
 		  }
 		  break;
+	  case COUNTER_MODE_PERIOD:
+		  if (m_buffer_prd_ct_list[p_cfg.name] != NULL)
+		  {
+		    return m_buffer_prd_ct_list[p_cfg.name]->get_value();
+		  }
+		  break;
     default:
       THROW_DEVFAILED(
          _CPTC("CONFIGURATION_ERROR"), 
@@ -1594,6 +1820,12 @@ void NI6602_Interface::updateCounterBufferValue(CounterConfig p_cfg)
         m_buffer_dt_ct_list[p_cfg.name]->updateRawBuffer();
 		  }
 		  break;
+	  case COUNTER_MODE_PERIOD:
+		  if (m_buffer_prd_ct_list[p_cfg.name] != NULL)
+		  {
+        m_buffer_prd_ct_list[p_cfg.name]->updateRawBuffer();
+		  }
+		  break;
     default:
 		  break;
 	}
@@ -1688,6 +1920,16 @@ void NI6602_Interface::releaseCounter(CounterConfig p_cfg)
 			    m_scalar_dt_ct_list[p_cfg.name] = NULL;
 		    }
 		    break;
+	    case COUNTER_MODE_PERIOD:
+		    if (m_scalar_prd_ct_list[p_cfg.name])
+		    {
+			    m_scalar_prd_ct_list[p_cfg.name]->stop();
+			    m_scalar_prd_ct_list[p_cfg.name]->release();
+
+			    delete m_scalar_prd_ct_list[p_cfg.name];
+			    m_scalar_prd_ct_list[p_cfg.name] = NULL;
+		    }
+		    break;
       default:
 		    break;
 	  }
@@ -1724,6 +1966,15 @@ void NI6602_Interface::releaseCounter(CounterConfig p_cfg)
 			    m_buffer_dt_ct_list[p_cfg.name] = NULL;
 		    }
 		    break;
+	    case COUNTER_MODE_PERIOD:
+		    if (m_buffer_prd_ct_list[p_cfg.name])
+		    {
+			    m_buffer_prd_ct_list[p_cfg.name]->stopCnt();
+
+			    delete m_buffer_prd_ct_list[p_cfg.name];
+			    m_buffer_prd_ct_list[p_cfg.name] = NULL;
+		    }
+		    break;
       default:
 		    break;
 	  }
diff --git a/src/NI6602_Interface.h b/src/NI6602_Interface.h
index 2f3085a3af364fd3dea751c7bda812b949b331cb..c8ca799dc4183c61af284fd1c9c5461c2b47ea10 100644
--- a/src/NI6602_Interface.h
+++ b/src/NI6602_Interface.h
@@ -16,9 +16,11 @@
 #include "BufferedCounterEvt.h"
 #include "BufferedCounterPos.h"
 #include "BufferedCounterDt.h"
+#include "BufferedCounterPeriod.h"
 #include <NI660Xsl/SimpleEventCounting.h>
 #include <NI660Xsl/SimplePositionMeasurement.h>
 #include <NI660Xsl/SimpleDTMeasurement.h>
+#include <NI660Xsl/SimplePeriodMeasurement.h>
 #include <NI660Xsl/FinitePulseTrainGeneration.h>
 #include <NI660Xsl/ContinuousPulseTrainGeneration.h>
 
@@ -134,6 +136,9 @@ private:
   // buffer dt counter
 	std::map<std::string, BufferedCounterDt *> m_buffer_dt_ct_list;
 
+  // buffer period counter
+	std::map<std::string, BufferedCounterPeriod *> m_buffer_prd_ct_list;
+
 	// max counter number
 	unsigned int m_max_nb_ct;
 
@@ -146,6 +151,9 @@ private:
 	// simple dt measurement
 	std::map<std::string, ni660Xsl::SimpleDTMeasurement *> m_scalar_dt_ct_list;
 
+	// simple period measurement
+	std::map<std::string, ni660Xsl::SimplePeriodMeasurement *> m_scalar_prd_ct_list;
+
 	// finite clock
 	ni660Xsl::FinitePulseTrainGeneration * m_scalar_finite_clock;
 
diff --git a/src/NexusManager.cpp b/src/NexusManager.cpp
index 9f7f5e86371df954294ff982e318adca2abfdfc0..f57a1f78917b8c3e0e5c4470381808aeee40e62e 100644
--- a/src/NexusManager.cpp
+++ b/src/NexusManager.cpp
@@ -21,7 +21,8 @@ NexusManager::NexusManager (Tango::DeviceImpl * host_device)
 : Tango::LogAdapter(host_device),
   m_pAcqWriter(NULL),
   m_finalizeDone(true),
-  m_finiteStorage(false)
+  m_finiteStorage(false),
+  m_excptOccured(false)
 #if defined (USE_NX_DS_FINALIZER)
   ,
   m_NexusDataStreamerFinalizer(NULL)
@@ -97,6 +98,7 @@ void NexusManager::initNexusAcquisition(std::string nexus_file_path,
   throw (Tango::DevFailed)
 {
   m_finalizeDone = false;
+  m_excptOccured = false;
 
   try
   {
diff --git a/src/NexusManager.h b/src/NexusManager.h
index e599a169dced3ea719daf85dab97bf4323bc90c8..c303a7aff464a98ceca9c4f04f85432b5424ea4e 100644
--- a/src/NexusManager.h
+++ b/src/NexusManager.h
@@ -82,7 +82,7 @@ typedef nxItemList_t::iterator nxItemList_it_t;
 // ============================================================================
 // class: NexusManager
 // ============================================================================
-class NexusManager : public Tango::LogAdapter
+class NexusManager : public Tango::LogAdapter, nxcpp::IExceptionHandler
 {
 public:
 
@@ -192,6 +192,19 @@ public:
     return !(this->m_finalizeDone);
   }
 
+  //- Gets Nexus storage exception
+  bool hasStorageError()
+  {
+    return m_excptOccured;
+  }
+
+  // Nexus exception handler
+  void OnNexusException(const nxcpp::NexusException &e)
+  {
+    ERROR_STREAM << "NexusManager::OnNexusException() called!" << std::endl;
+	e.dump();
+    m_excptOccured = true;
+  }
 
 protected:
   
@@ -217,7 +230,9 @@ protected:
 
   //- list of items to store
   nxItemList_t m_itemList;
-  
+
+  //- nexus exception flag
+  bool m_excptOccured;
 };
 
 } // namespace PulseCounting_ns
diff --git a/src/PeriodCounter.cpp b/src/PeriodCounter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1244f4b7e23d65844c1126120def42ec93556f9b
--- /dev/null
+++ b/src/PeriodCounter.cpp
@@ -0,0 +1,349 @@
+//=============================================================================
+// PeriodCounter.cpp
+//=============================================================================
+// abstraction.......PeriodCounter for PulseCounting
+// class.............PeriodCounter
+// original author...S.Minolli - Nexeya
+//=============================================================================
+
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <yat4tango/LogHelper.h>
+#include "PeriodCounter.h"
+
+namespace PulseCounting_ns
+{
+
+	//- check manager macro:
+#define CHECK_INTERFACE() \
+	do \
+	{ \
+	if (! m_interface) \
+	THROW_DEVFAILED(_CPTC("DEVICE_ERROR"), \
+	_CPTC("request aborted - the interface isn't accessible "), \
+	_CPTC("PeriodCounter::check_interface")); \
+} while (0)
+
+
+// ============================================================================
+// PeriodCounter::PeriodCounter ()
+// ============================================================================ 
+PeriodCounter::PeriodCounter (Tango::DeviceImpl * hostDevice, E_AcquisitionMode_t p_acq_mode, CountingBoardInterface * p_board)
+: GenericCounterInterface(hostDevice)
+{
+	m_is_available = true;
+	m_state = Tango::STANDBY;
+	m_acq_mode = p_acq_mode;
+	m_interface = p_board;
+	m_value = 0;
+}
+
+// ============================================================================
+// PeriodCounter::~PeriodCounter ()
+// ============================================================================ 
+PeriodCounter::~PeriodCounter ()
+{
+
+}
+
+// ============================================================================
+// PeriodCounter::is_available ()
+// ============================================================================ 
+bool PeriodCounter::is_available()
+{
+	return m_is_available;
+}
+
+// ============================================================================
+// PeriodCounter::init ()
+// ============================================================================ 
+void PeriodCounter::init(CounterConfig p_cfg)
+  throw (Tango::DevFailed)
+{
+	m_cfg = p_cfg;
+
+  CHECK_INTERFACE();
+
+	try
+	{
+		m_interface->initCounter(m_cfg);
+	}
+	catch (Tango::DevFailed &e)
+	{
+		ERROR_STREAM << e << std::endl;
+		RETHROW_DEVFAILED(e, 
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to initialize period counter!"), 
+			_CPTC("PeriodCounter::init")); 
+	}
+	catch (...)
+	{
+		ERROR_STREAM << "Failed to initialize period counter!" << std::endl;
+		THROW_DEVFAILED(
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to initialize period counter!"), 
+			_CPTC("PeriodCounter::init")); 
+	}
+}
+
+// ============================================================================
+// PeriodCounter::configure ()
+// ============================================================================ 
+void PeriodCounter::configure(CounterConfig p_cfg)
+  throw (Tango::DevFailed)
+{
+	m_cfg = p_cfg;
+
+  CHECK_INTERFACE();
+
+	try
+	{
+		m_interface->configureCounter(m_cfg);
+	}
+	catch (Tango::DevFailed &e)
+	{
+		ERROR_STREAM << e << std::endl;
+		RETHROW_DEVFAILED(e, 
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to configure period counter!"), 
+			_CPTC("PeriodCounter::configure")); 
+	}
+	catch (...)
+	{
+		ERROR_STREAM << "Failed to configure period counter!" << std::endl;
+		THROW_DEVFAILED(
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to configure period counter!"), 
+			_CPTC("PeriodCounter::configure")); 
+	}
+}
+
+// ============================================================================
+// PeriodCounter::start ()
+// ============================================================================ 
+void PeriodCounter::start()
+  throw (Tango::DevFailed)
+{
+  CHECK_INTERFACE();
+
+	try
+	{
+		m_interface->startCounter(m_cfg);
+	}
+	catch (Tango::DevFailed &e)
+	{
+		ERROR_STREAM << e << std::endl;
+		RETHROW_DEVFAILED(e, 
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to start period counter"), 
+			_CPTC("PeriodCounter::start")); 
+	}
+	catch (...)
+	{
+		ERROR_STREAM << "Failed to start period counter" << std::endl;
+		THROW_DEVFAILED(
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to start period counter"), 
+			_CPTC("PeriodCounter::start")); 
+	}
+	m_state = Tango::RUNNING;
+}
+
+// ============================================================================
+// PeriodCounter::stop ()
+// ============================================================================ 
+void PeriodCounter::stop()
+  throw (Tango::DevFailed)
+{
+  CHECK_INTERFACE();
+
+	try
+	{
+		m_interface->stopCounter(m_cfg);
+	}
+	catch (Tango::DevFailed &e)
+	{
+		ERROR_STREAM << e << std::endl;
+		RETHROW_DEVFAILED(e, 
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to stop period counter"), 
+			_CPTC("PeriodCounter::stop")); 
+	}
+	catch (...)
+	{
+		ERROR_STREAM << "Failed to stop period counter" << std::endl;
+		THROW_DEVFAILED(
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to stop period counter"), 
+			_CPTC("PeriodCounter::stop")); 
+	}
+	m_state = Tango::STANDBY;
+}
+
+// ============================================================================
+// PeriodCounter::get_state ()
+// ============================================================================ 
+Tango::DevState PeriodCounter::get_state()
+  throw (Tango::DevFailed)
+{
+  CHECK_INTERFACE();
+
+	try
+	{
+		return m_interface->getCounterState(m_cfg);
+	}
+	catch (Tango::DevFailed &e)
+	{
+		ERROR_STREAM << e << std::endl;
+		RETHROW_DEVFAILED(e, 
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to get period counter state!"), 
+			_CPTC("PeriodCounter::get_state")); 
+	}
+	catch (...)
+	{
+		ERROR_STREAM << "Failed to get period counter state!" << std::endl;
+		THROW_DEVFAILED(
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to get period counter state!"), 
+			_CPTC("PeriodCounter::get_state")); 
+	}
+}
+
+// ============================================================================
+// PeriodCounter::update_scalar_value ()
+// ============================================================================ 
+void PeriodCounter::update_scalar_value()
+  throw (Tango::DevFailed)
+{
+  CHECK_INTERFACE();
+
+	try
+	{
+    yat::AutoMutex<> guard(this->m_dataLock);
+		m_value = m_interface->getCounterScalarValue(m_cfg);
+	}
+	catch (Tango::DevFailed &e)
+	{
+		ERROR_STREAM << e << std::endl;
+		RETHROW_DEVFAILED(e,
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to update scalar period counter value!"), 
+			_CPTC("PeriodCounter::update_scalar_value")); 
+	}
+	catch (...)
+	{
+		ERROR_STREAM << "Failed to update scalar period counter value!" << std::endl;
+		THROW_DEVFAILED(
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to update scalar period counter value!"), 
+			_CPTC("PeriodCounter::update_scalar_value")); 
+	}
+}
+
+// ============================================================================
+// PeriodCounter::update_buffer_value ()
+// ============================================================================ 
+void PeriodCounter::update_buffer_value()
+  throw (Tango::DevFailed)
+{
+  CHECK_INTERFACE();
+
+	try
+	{
+    m_interface->updateCounterBufferValue(m_cfg);
+	}
+	catch (Tango::DevFailed &e)
+	{
+		ERROR_STREAM << e << std::endl;
+		RETHROW_DEVFAILED(e,
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to update buffer period counter value!"), 
+			_CPTC("PeriodCounter::update_buffer_value")); 
+	}
+	catch (...)
+	{
+		ERROR_STREAM << "Failed to update buffer period counter value!" << std::endl;
+		THROW_DEVFAILED(
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to update buffer period counter value!"), 
+			_CPTC("PeriodCounter::update_buffer_value")); 
+	}
+}
+
+// ============================================================================
+// PeriodCounter::get_scalar_value ()
+// ============================================================================ 
+data_t PeriodCounter::get_scalar_value()
+{
+  yat::AutoMutex<> guard(this->m_dataLock);
+	return m_value;
+}
+
+// ============================================================================
+// PeriodCounter::get_buffer_value ()
+// ============================================================================ 
+RawData_t PeriodCounter::get_buffer_value()
+  throw (Tango::DevFailed)
+{
+  CHECK_INTERFACE();
+
+	try
+	{
+		return m_interface->getCounterBufferValue(m_cfg);
+	}
+	catch (Tango::DevFailed &e)
+	{
+		ERROR_STREAM << e << std::endl;
+		RETHROW_DEVFAILED(e, 
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to get period counter buffer value"), 
+			_CPTC("PeriodCounter::get_buffer_value")); 
+	}
+	catch (...)
+	{
+		ERROR_STREAM << "Failed to get period counter buffer value" << std::endl;
+		THROW_DEVFAILED(
+      _CPTC("DEVICE_ERROR"), 
+			_CPTC("Failed to get period counter buffer value"), 
+			_CPTC("PeriodCounter::get_buffer_value")); 
+	}
+}
+
+// ============================================================================
+// PeriodCounter::get_name ()
+// ============================================================================ 
+std::string PeriodCounter::get_name()
+{
+	return m_cfg.name;
+}
+
+// ============================================================================
+// PeriodCounter::get_config ()
+// ============================================================================ 
+CounterConfig PeriodCounter::get_config()
+{
+	return m_cfg;
+}
+
+// ============================================================================
+// PeriodCounter::deleteObject ()
+// ============================================================================ 
+void PeriodCounter::deleteObject()
+  throw (Tango::DevFailed)
+{
+  CHECK_INTERFACE();
+
+	try
+	{
+		m_interface->releaseCounter(m_cfg);
+  }
+  catch(...)
+  {
+  }
+}
+
+} // namespace PulseCounting_ns
+
diff --git a/src/PeriodCounter.h b/src/PeriodCounter.h
new file mode 100644
index 0000000000000000000000000000000000000000..a2cd63139a3cda516809fa4fb8d0fc3ad2facb67
--- /dev/null
+++ b/src/PeriodCounter.h
@@ -0,0 +1,91 @@
+//=============================================================================
+// PeriodCounter.h
+//=============================================================================
+// abstraction.......PeriodCounter for PulseCounting
+// class.............PeriodCounter
+// original author...S.Minolli - Nexeya
+//=============================================================================
+
+#ifndef _PERIOD_COUNTER_H
+#define _PERIOD_COUNTER_H
+
+// ============================================================================
+// DEPENDENCIES
+// ============================================================================
+#include <yat4tango/LogHelper.h>
+#include "PulseCountingTypesAndConsts.h"
+#include "GenericCounterInterface.h"
+
+namespace PulseCounting_ns
+{
+
+// ============================================================================
+// class: PeriodCounter
+// ============================================================================
+class PeriodCounter  : public GenericCounterInterface
+{
+
+public:
+
+  //- constructor
+  PeriodCounter (Tango::DeviceImpl * hostDevice, E_AcquisitionMode_t p_acq_mode, CountingBoardInterface * p_board);
+
+  //- destructor
+  virtual ~PeriodCounter ();
+  
+  //- is available?
+  bool is_available();
+
+  //- init
+  void init(CounterConfig p_cfg)
+	  throw (Tango::DevFailed);
+
+  //- configure
+  void configure(CounterConfig p_cfg)
+	  throw (Tango::DevFailed);
+
+  //- start
+  void start()
+	  throw (Tango::DevFailed);
+
+  //- stop
+  void stop()
+	  throw (Tango::DevFailed);
+
+  //- release counter
+  void deleteObject()
+    throw (Tango::DevFailed);
+
+  //- get State
+  Tango::DevState get_state()
+	  throw (Tango::DevFailed);
+	  
+  //- update scalar value
+  void update_scalar_value()
+	  throw (Tango::DevFailed);
+	  
+  //- update buffer value (used in "polling" mode)
+  void update_buffer_value()
+	  throw (Tango::DevFailed);
+	  
+  //- get scalar value
+  data_t get_scalar_value();
+	  
+  //- get buffer value
+  RawData_t get_buffer_value()
+	  throw (Tango::DevFailed);
+
+  //- get name
+  std::string get_name()
+	  throw (Tango::DevFailed);
+
+  //- get config
+  CounterConfig get_config()
+	  throw (Tango::DevFailed);
+  
+protected:
+};
+
+} // namespace PulseCounting_ns
+
+#endif // _PERIOD_COUNTER_H
diff --git a/src/PulseCounting.cpp b/src/PulseCounting.cpp
index 6beccf9be950e2a7a0a6f061d9721042161ddaf8..673588a3783d8a4c4c37d8201038284442c7b34f 100644
--- a/src/PulseCounting.cpp
+++ b/src/PulseCounting.cpp
@@ -620,7 +620,14 @@ void PulseCounting::get_device_property()
           l_cfg.dt_unitStr = config_parser.extractUnitStr(l_keys);
 					l_cfg.memTranfer = config_parser.extractMemoryTransfer(l_keys);
         }
-				else
+        else if (l_cfg.mode == COUNTER_MODE_PERIOD)
+        {
+					l_cfg.edge = config_parser.extractEdge(l_keys);
+          l_cfg.dt_unit = config_parser.extractUnit(l_keys);
+          l_cfg.dt_unitStr = config_parser.extractUnitStr(l_keys);
+					l_cfg.memTranfer = config_parser.extractMemoryTransfer(l_keys);
+        }
+        else
 				{
 					if (l_cfg.mode == COUNTER_MODE_POSITION)
 					{
diff --git a/src/PulseCountingManager.cpp b/src/PulseCountingManager.cpp
index e8896c6a6595d33415965648411d10165f47c284..29e9bf077eca8621a7f6fbc4410a7abb825d19a7 100644
--- a/src/PulseCountingManager.cpp
+++ b/src/PulseCountingManager.cpp
@@ -662,8 +662,10 @@ void PulseCountingManager::add_attributes(CounterConfig p_cfg)
 {
 	CHECK_MANAGER_DYN_ATTR_MANAGER();
 
-  // Do not create pulse width attributes for DT counters: unavailable function
-  if (p_cfg.mode == COUNTER_MODE_DELTATIME)
+  // Do not create pulse width attributes for DT & PERIOD counters: unavailable function
+  if ((p_cfg.mode == COUNTER_MODE_DELTATIME) || 
+      (p_cfg.mode == COUNTER_MODE_PERIOD))
+
   {
     return;
   }
diff --git a/src/PulseCountingManagerBuffered.cpp b/src/PulseCountingManagerBuffered.cpp
index dc1c3ee769b54d6541321cf57355ebf61a82ce0a..df7215950eb9c53fa58401dd4c2959d2fdfd9f73 100644
--- a/src/PulseCountingManagerBuffered.cpp
+++ b/src/PulseCountingManagerBuffered.cpp
@@ -296,8 +296,15 @@ void PulseCountingManagerBuffered::periodic_job_i()
 					}
 				}
 
-				// if one counter in FAULT or ALARM, stop counting process
-				if (acq_error)
+				// check nexus error
+				if (this->m_nexus_manager->hasStorageError())
+				{
+				  m_status = "Nexus exception handled, acquisition stopped!\n";
+				}
+
+				// if one counter in FAULT or ALARM,
+				// or if nexus error, stop counting process
+				if (acq_error || (this->m_nexus_manager->hasStorageError()))
 				{
 					m_state = Tango::FAULT;
           this->m_requestedStop = true;
@@ -383,8 +390,15 @@ void PulseCountingManagerBuffered::periodic_job_i()
 					}
 				}
 
-				// if one counter in FAULT or ALARM, stop counting process
-				if (acq_error)
+				// check nexus error
+				if (this->m_nexus_manager->hasStorageError())
+				{
+				  m_status = "Nexus exception handled, acquisition stopped!\n";
+				}
+
+				// if one counter in FAULT or ALARM, 
+				// or if nexus error, stop counting process
+				if (acq_error || (this->m_nexus_manager->hasStorageError()))
 				{
 					m_state = Tango::FAULT;
           this->m_requestedStop = true;
diff --git a/src/PulseCountingTypesAndConsts.h b/src/PulseCountingTypesAndConsts.h
index e4c156e4c68b1bc07d9ae613c82d44ebd9111f1b..ec5262bad64e6e5f6be5d6fb8ce46553fc84fa43 100644
--- a/src/PulseCountingTypesAndConsts.h
+++ b/src/PulseCountingTypesAndConsts.h
@@ -99,7 +99,8 @@ typedef enum
 	UNDEFINED_COUNTER_MODE  = 0x0,
 	COUNTER_MODE_EVENT      = 0x1,
 	COUNTER_MODE_POSITION   = 0x2,
-  COUNTER_MODE_DELTATIME  = 0x3
+  COUNTER_MODE_DELTATIME  = 0x3,
+  COUNTER_MODE_PERIOD     = 0x4
 } E_CounterMode_t;
 
 // ============================================================================
@@ -897,7 +898,7 @@ static std::vector<std::string> define_config_counter_example()
 {
 	std::vector<std::string> config;
 	config.push_back("Name:-- Counter name --");
-	config.push_back("Mode:-- POS / EVT / DT --");
+	config.push_back("Mode:-- POS / EVT / DT / PERIOD --");
 	config.push_back("Transfer:-- [ITR] / DMA (for buffered) -- optionnal --");
 	config.push_back("EdgeType:-- Falling / Rising --");
   config.push_back("2ndEdgeType:-- DTonly --> Falling / Rising --");
diff --git a/src/main.cpp b/src/main.cpp
index cb630b569b94e25f678786f63683a4930ba40ed2..ea7d8d879d98c5bbd301c0c0a300677004a9b529 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -37,10 +37,20 @@ static const char *RcsId = "$Id $";
 #include <tango.h>
 #include <ace/ACE.h> // for timeout management in NI660XSl
 
+#if defined(ENABLE_CRASH_REPORT)
+# include <crashreporting/crash_report.h>
+#else
+# define DECLARE_CRASH_HANDLER
+# define INSTALL_CRASH_HANDLER
+#endif
+
+DECLARE_CRASH_HANDLER;
+
 int main(int argc,char *argv[])
 {
-
-	Tango::Util *tg;
+	INSTALL_CRASH_HANDLER;
+	
+	Tango::Util *tg = 0;
 	try
 	{
 		// Initialise the device server