Provides a simple way to capture the wave form of a pin. For example it can be used to capture the digital state transitions of a pin connected to an IR receiver. These signals can later be played back using the Signal Generator library to control IR devices. The library supports two means of capturing the signal. The signal can be captured on any digital pin using polling while for higher resolution and more accurate timing the interrupt driven capture feature can be used.

Revision:
0:c6f86d422a7e
diff -r 000000000000 -r c6f86d422a7e InterruptPinCapture.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/InterruptPinCapture.cpp	Sat Sep 27 04:04:16 2014 +0000
@@ -0,0 +1,91 @@
+///////////////////////////////////////////////////////////////////////////////
+// Signal Capture Library
+// Author: Chris Taylor (taylorza)
+#include "mbed.h"
+#include "InterruptPinCapture.h"
+
+InterruptPinCapture::InterruptPinCapture(PinName pin, PinMode mode) :
+    _started(false),
+    _readTimeout(10000000),
+    _state(Stopped),
+    _signalPin(pin)
+{
+    _signalPin.mode(mode);        
+}
+
+void InterruptPinCapture::setReadTimeout(uint32_t us)
+{
+    _readTimeout = us;
+}
+
+int InterruptPinCapture::read(bool triggerState, uint32_t *pReadings, int count)
+{
+    return readInternal(&triggerState, pReadings, count, true);
+}
+
+int InterruptPinCapture::read(bool *pInitialState, uint32_t *pReadings, int count)
+{
+    return readInternal(pInitialState, pReadings, count, false);
+}
+
+int InterruptPinCapture::readInternal(bool *pPinState, uint32_t *pReadings, int count, bool waitForTrigger)
+{
+    _bufferIndex = 0;
+    _bufferMaxCount = count;
+    _pBuffer = pReadings;
+    _triggerState = *pPinState ? 1 : 0;   
+    
+    if (waitForTrigger)
+    {
+        _state = WaitForTrigger;
+    }
+    else
+    {
+        *pPinState = _signalPin.read() ? true : false;
+        _state = StartCapturing;
+    }
+    
+    _timer.reset();
+    _timer.start();     
+    
+    _signalPin.rise(this, &InterruptPinCapture::onPinTransition);
+    _signalPin.fall(this, &InterruptPinCapture::onPinTransition);
+    
+    while (_state != Stopped && _timer.read_us() < _readTimeout);
+    
+    _signalPin.rise(NULL);
+    _signalPin.fall(NULL);
+    _state = Stopped;        
+    _timer.stop();        
+        
+    return _bufferIndex;
+}
+
+void InterruptPinCapture::onPinTransition()
+{
+    uint32_t transitionTime = (uint32_t)_timer.read_us();
+    
+    switch(_state)
+    {
+        case WaitForTrigger:
+            if (_signalPin.read() == _triggerState)
+            {            
+                _state = StartCapturing;            
+            }
+            break;
+            
+        case StartCapturing:
+            _lastTransitionTime = transitionTime;
+            _state = Capturing;            
+            break;
+            
+        case Capturing:
+            _pBuffer[_bufferIndex++] = transitionTime - _lastTransitionTime;
+            _lastTransitionTime = transitionTime;
+            if (_bufferIndex >= _bufferMaxCount)
+            {
+                _state = Stopped;
+            }
+            break;        
+    }
+}