Chris Taylor / SignalCapture
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers InterruptPinCapture.cpp Source File

InterruptPinCapture.cpp

00001 ///////////////////////////////////////////////////////////////////////////////
00002 // Signal Capture Library
00003 // Author: Chris Taylor (taylorza)
00004 #include "mbed.h"
00005 #include "InterruptPinCapture.h"
00006 
00007 InterruptPinCapture::InterruptPinCapture(PinName pin, PinMode mode) :
00008     _started(false),
00009     _readTimeout(10000000),
00010     _state(Stopped),
00011     _signalPin(pin)
00012 {
00013     _signalPin.mode(mode);        
00014 }
00015 
00016 void InterruptPinCapture::setReadTimeout(uint32_t us)
00017 {
00018     _readTimeout = us;
00019 }
00020 
00021 int InterruptPinCapture::read(bool triggerState, uint32_t *pReadings, int count)
00022 {
00023     return readInternal(&triggerState, pReadings, count, true);
00024 }
00025 
00026 int InterruptPinCapture::read(bool *pInitialState, uint32_t *pReadings, int count)
00027 {
00028     return readInternal(pInitialState, pReadings, count, false);
00029 }
00030 
00031 int InterruptPinCapture::readInternal(bool *pPinState, uint32_t *pReadings, int count, bool waitForTrigger)
00032 {
00033     _bufferIndex = 0;
00034     _bufferMaxCount = count;
00035     _pBuffer = pReadings;
00036     _triggerState = *pPinState ? 1 : 0;   
00037     
00038     if (waitForTrigger)
00039     {
00040         _state = WaitForTrigger;
00041     }
00042     else
00043     {
00044         *pPinState = _signalPin.read() ? true : false;
00045         _state = StartCapturing;
00046     }
00047     
00048     _timer.reset();
00049     _timer.start();     
00050     
00051     _signalPin.rise(this, &InterruptPinCapture::onPinTransition);
00052     _signalPin.fall(this, &InterruptPinCapture::onPinTransition);
00053     
00054     while (_state != Stopped && _timer.read_us() < _readTimeout);
00055     
00056     _signalPin.rise(NULL);
00057     _signalPin.fall(NULL);
00058     _state = Stopped;        
00059     _timer.stop();        
00060         
00061     return _bufferIndex;
00062 }
00063 
00064 void InterruptPinCapture::onPinTransition()
00065 {
00066     uint32_t transitionTime = (uint32_t)_timer.read_us();
00067     
00068     switch(_state)
00069     {
00070         case WaitForTrigger:
00071             if (_signalPin.read() == _triggerState)
00072             {            
00073                 _state = StartCapturing;            
00074             }
00075             break;
00076             
00077         case StartCapturing:
00078             _lastTransitionTime = transitionTime;
00079             _state = Capturing;            
00080             break;
00081             
00082         case Capturing:
00083             _pBuffer[_bufferIndex++] = transitionTime - _lastTransitionTime;
00084             _lastTransitionTime = transitionTime;
00085             if (_bufferIndex >= _bufferMaxCount)
00086             {
00087                 _state = Stopped;
00088             }
00089             break;        
00090     }
00091 }