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.
Diff: SignalGenerator.cpp
- Revision:
- 2:b2a449bd787f
- Parent:
- 1:4a1bcc41c473
- Child:
- 3:f30dcc6e8e70
--- a/SignalGenerator.cpp Fri Sep 12 04:13:43 2014 +0000 +++ b/SignalGenerator.cpp Fri Sep 12 05:20:08 2014 +0000 @@ -4,9 +4,56 @@ #include "mbed.h" #include "SignalGenerator.h" +int32_t SignalGenerator::_latency = -1; + SignalGenerator::SignalGenerator(PinName pin) : _pin(pin) { - _pin = 0; + if (_latency == -1) + { + Timer t; + + t.start(); + _pin = 0; + _pin = 0; + _pin = 0; + _pin = 0; + _pin = 0; + _pin = 0; + _pin = 0; + _pin = 0; + _pin = 0; + _pin = 0; + t.stop(); + int pinLatency = (t.read_us() + 0.5) / 10; + + t.reset(); + t.start(); + wait_us(100); + wait_us(100); + wait_us(100); + wait_us(100); + wait_us(100); + wait_us(100); + wait_us(100); + wait_us(100); + wait_us(100); + wait_us(100); + wait_us(100); + t.stop(); + int waitLatency = (t.read_us() + 0.5) / 1000; + + t.reset(); + t.start(); + for (int i = 0; i < 20; i += 2) + { + wait_us(100); + } + t.stop(); + + int loopLatency = ((t.read_us() - (1000 + (10 * waitLatency))) + 0.5) / 10; + + _latency = pinLatency + waitLatency + loopLatency; + } } void SignalGenerator::set(bool pinState) @@ -19,9 +66,14 @@ uint32_t timingBuffer[], uint16_t bufferCount, uint32_t lastStateHoldTime, - int carrierFrequency) + int32_t carrierFrequency) { uint32_t carrierHalfPeriod = 0; + + if (timingBuffer == NULL || bufferCount == 0) + { + return; + } if (carrierFrequency > 0) { @@ -30,7 +82,7 @@ bool state = initialState; for(uint16_t i = 0; i < bufferCount; i++) { - int c = (int)((double)timingBuffer[i] / carrierHalfPeriod); + int c = (int)(timingBuffer[i] / (carrierHalfPeriod + _latency)); if (!state) { wait_us(timingBuffer[i]); @@ -81,4 +133,4 @@ wait_us(lastStateHoldTime); } } -} +} \ No newline at end of file