Revision 0:c6f86d422a7e, committed 2014-09-27
- Comitter:
- taylorza
- Date:
- Sat Sep 27 04:04:16 2014 +0000
- Commit message:
- Initial commit of the Signal Capture library
Changed in this revision
diff -r 000000000000 -r c6f86d422a7e DigitalPinCapture.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/DigitalPinCapture.cpp Sat Sep 27 04:04:16 2014 +0000
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////////
+// Signal Capture Library
+// Author: Chris Taylor (taylorza)
+#include "mbed.h"
+#include "DigitalPinCapture.h"
+
+DigitalPinCapture::DigitalPinCapture(PinName pin, PinMode mode) :
+ _signalPin(pin, mode),
+ _readTimeout(10000000)
+{
+
+}
+
+void DigitalPinCapture::setReadTimeout(uint32_t us)
+{
+ _readTimeout = us;
+}
+
+int DigitalPinCapture::read(bool triggerState, uint32_t *pReadings, int count)
+{
+ return readInternal(&triggerState, pReadings, count, true);
+}
+
+int DigitalPinCapture::read(bool *pInitialState, uint32_t *pReadings, int count)
+{
+ return readInternal(pInitialState, pReadings, count, false);
+}
+
+int DigitalPinCapture::readInternal(bool *pPinState, uint32_t *pReadings, int count, bool waitForTrigger)
+{
+ Timer timer;
+
+ int lastPinState;
+ int lastTransitionTime;
+
+ timer.start();
+ if (waitForTrigger)
+ {
+ while (_signalPin == *pPinState)
+ {
+ if (timer.read_us() >= _readTimeout) return 0;
+ }
+
+ while (_signalPin != *pPinState)
+ {
+ if (timer.read_us() >= _readTimeout) return 0;
+ }
+ lastTransitionTime = timer.read_us();
+ }
+ else
+ {
+ *pPinState = _signalPin ? true : false;
+ lastTransitionTime = timer.read_us();
+ }
+
+ lastPinState = *pPinState;
+
+ int bufferIndex = 0;
+ while (bufferIndex < count && timer.read_us() < _readTimeout)
+ {
+ if (_signalPin != lastPinState)
+ {
+ uint32_t transitionTime = timer.read_us();
+ pReadings[bufferIndex++] = transitionTime - lastTransitionTime;
+ lastPinState = !lastPinState;
+ lastTransitionTime = transitionTime;
+ }
+ }
+
+ timer.stop();
+
+ return bufferIndex;
+}
+
diff -r 000000000000 -r c6f86d422a7e DigitalPinCapture.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/DigitalPinCapture.h Sat Sep 27 04:04:16 2014 +0000
@@ -0,0 +1,46 @@
+///////////////////////////////////////////////////////////////////////////////
+// Signal Capture Library
+// Author: Chris Taylor (taylorza)
+#ifndef __DIGITALPINCAPTURE_H__
+#define __DIGITALPINCAPTURE_H__
+
+/** Captures the digital wave form of a pin into a timing buffer. */
+class DigitalPinCapture
+{
+ public:
+ /** Create an instance of DigitalPinCapture connected to the specified pin
+ * @note The DigitalPinCapture class polls the state of the pin and therefore might be less accurate than
+ * using InterruptPinCapture. However, it has the advantage that it does not require an interrupt capable pin.
+ */
+ DigitalPinCapture(PinName pin, PinMode mode);
+
+ /** Maximum time to wait for waveform data to arrive or completely fill the timing buffer.
+ * @param us Timeout specified in microseconds
+ */
+ void setReadTimeout(uint32_t us);
+
+ /** Waits for the pin to transition to the trigger state and proceeds to capture the
+ * pins transition timing into the timing buffer.
+ * @param triggerState State that the pin must transistion to before the readings are captured
+ * @param pReadings Pointer to the timing buffer that will contain the readings in microseconds
+ * @param count The maximum number of readings that can be held in the buffer
+ * @returns The number of timings captured in the buffer.
+ */
+ int read(bool triggerState, uint32_t *pReadings, int count);
+
+ /** Immediately start capturing the pin transition timing into the timing buffer.
+ * @param pInitialState Pointer to a bool that will have the initial state of the pin at the time the capture started.
+ * @param pReadings Pointer to the timing buffer that will contain the readings in microseconds
+ * @param count The maximum number of readings that can be held in the buffer
+ * @returns The number of timings captured in the buffer.
+ */
+ int read(bool *pInitialState, uint32_t *pReadings, int count);
+
+ private:
+ int readInternal(bool *pPinState, uint32_t *pReadings, int count, bool waitForTrigger);
+
+ private:
+ DigitalIn _signalPin;
+ uint32_t _readTimeout;
+};
+#endif //__DIGITALPINCAPTURE_H__
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;
+ }
+}
diff -r 000000000000 -r c6f86d422a7e InterruptPinCapture.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/InterruptPinCapture.h Sat Sep 27 04:04:16 2014 +0000
@@ -0,0 +1,65 @@
+///////////////////////////////////////////////////////////////////////////////
+// Signal Capture Library
+// Author: Chris Taylor (taylorza)
+#ifndef __INTERRUPTPINCAPTURE_H__
+#define __INTERRUPTPINCAPTURE_H__
+
+/** Captures the digital wave form of an interrupt capable pin into a timing buffer. */
+class InterruptPinCapture
+{
+ public:
+ /** Create an instance of InterruptPinCapture connected to the specified pin */
+ InterruptPinCapture(PinName pin, PinMode mode);
+
+ /** Maximum time to wait for waveform data to arrive or completely fill the timing buffer.
+ * @param us Timeout specified in microseconds
+ */
+ void setReadTimeout(uint32_t us);
+
+ /** Waits for the pin to transition to the trigger state and proceeds to capture the
+ * pins transition timing into the timing buffer.
+ * @param triggerState State that the pin must transistion to before the readings are captured
+ * @param pReadings Pointer to the timing buffer that will contain the readings in microseconds
+ * @param count The maximum number of readings that can be held in the buffer
+ * @returns The number of timings captured in the buffer.
+ */
+ int read(bool triggerState, uint32_t *pReadings, int count);
+
+ /** Immediately start capturing the pin transition timing into the timing buffer.
+ * @param pInitialState Pointer to a bool that will have the initial state of the pin at the time the capture started.
+ * @param pReadings Pointer to the timing buffer that will contain the readings in microseconds
+ * @param count The maximum number of readings that can be held in the buffer
+ * @returns The number of timings captured in the buffer.
+ */
+ int read(bool *pInitialState, uint32_t *pReadings, int count);
+
+ private:
+ int readInternal(bool *pPinState, uint32_t *pReadings, int count, bool waitForTrigger);
+
+ private:
+ void onPinTransition();
+
+ enum State
+ {
+ Stopped,
+ WaitForTrigger,
+ StartCapturing,
+ Capturing
+ };
+
+ private:
+ bool _started;
+ uint32_t _readTimeout;
+ volatile State _state;
+ InterruptIn _signalPin;
+
+ uint32_t *_pBuffer;
+ int _bufferMaxCount;
+ int _bufferIndex;
+ int _startPinState;
+
+ int _triggerState;
+ uint32_t _lastTransitionTime;
+ Timer _timer;
+};
+#endif //__INTERRUPTPINCAPTURE_H__
\ No newline at end of file