Provides a simple way to generate complex square wave signals on any available pin. In addition the SignalGenerator can generate a carrier wave which is useful when generating IR signals to control electronic devices like a TV etc. The signal generation can be carried out either synchronously or asynchronously. In the case of synchronous signal generation all interrupts can optionally be disabled to improve timing accuracy.
SignalGenerator.cpp
- Committer:
- taylorza
- Date:
- 2014-09-13
- Revision:
- 3:f30dcc6e8e70
- Parent:
- 2:b2a449bd787f
- Child:
- 4:64d2d834341b
File content as of revision 3:f30dcc6e8e70:
/////////////////////////////////////////////////////////////////////////////// // Signal Generator // Author: Chris Taylor (taylorza) #include "mbed.h" #include "SignalGenerator.h" SignalGenerator::SignalGenerator(PinName pin) : _pin(pin) { } void SignalGenerator::set(bool pinState) { _pin = pinState ? 1 : 0; } void SignalGenerator::set( bool initialState, uint32_t timingBuffer[], uint16_t bufferCount, uint32_t lastStateHoldTime, int32_t carrierFrequency) { if (timingBuffer == NULL || bufferCount == 0) { return; } uint16_t lastTiming = bufferCount - 1; Timer transitionTimer; if (carrierFrequency > 0) { int timingIndex = 0; bool pinState = initialState; bool carrierState = true; uint32_t carrierHalfPeriod = (500000 / carrierFrequency); uint32_t compare = timingBuffer[timingIndex++]; uint32_t carrierCompare = carrierHalfPeriod; transitionTimer.start(); while(true) { bool stateChange = false; if (transitionTimer.read_us() >= compare) { pinState = !pinState; stateChange = true; if (timingIndex == lastTiming) break; compare += timingBuffer[timingIndex++]; } if (transitionTimer.read_us() >= carrierCompare) { carrierState = !carrierState; carrierCompare += carrierHalfPeriod; stateChange = true; } if (stateChange) _pin = pinState & carrierState ? 1 : 0; } if (lastStateHoldTime > 0) { compare += lastStateHoldTime; while (transitionTimer.read_us() < compare) { if (transitionTimer.read_us() >= carrierCompare) { carrierState = !carrierState; carrierCompare += carrierHalfPeriod; _pin = pinState & carrierState ? 1 : 0; } } } } else { int timingIndex = 0; uint32_t compare = timingBuffer[timingIndex++]; transitionTimer.start(); set(initialState); while(true) { if (transitionTimer.read_us() >= compare) { _pin = !_pin; if (timingIndex == lastTiming) break; compare += timingBuffer[timingIndex++]; } } if (lastStateHoldTime > 0) { compare += lastStateHoldTime; while (transitionTimer.read_us() < compare) { ; } } } }