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.

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