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.

Committer:
taylorza
Date:
Fri Sep 12 04:04:46 2014 +0000
Revision:
0:b7c65c0d82d3
Child:
1:4a1bcc41c473
Initial version of the SignalGenerator

Who changed what in which revision?

UserRevisionLine numberNew contents of line
taylorza 0:b7c65c0d82d3 1 #include "mbed.h"
taylorza 0:b7c65c0d82d3 2 #include "SignalGenerator.h"
taylorza 0:b7c65c0d82d3 3
taylorza 0:b7c65c0d82d3 4 SignalGenerator::SignalGenerator(PinName pin) : _pin(pin)
taylorza 0:b7c65c0d82d3 5 {
taylorza 0:b7c65c0d82d3 6 _pin = 0;
taylorza 0:b7c65c0d82d3 7 }
taylorza 0:b7c65c0d82d3 8
taylorza 0:b7c65c0d82d3 9 void SignalGenerator::set(bool pinState)
taylorza 0:b7c65c0d82d3 10 {
taylorza 0:b7c65c0d82d3 11 _pin = pinState ? 1 : 0;
taylorza 0:b7c65c0d82d3 12 }
taylorza 0:b7c65c0d82d3 13
taylorza 0:b7c65c0d82d3 14 void SignalGenerator::set(bool initialState, uint32_t timingBuffer[], uint16_t bufferCount, uint32_t lastStateHoldTime, int carrierFrequency)
taylorza 0:b7c65c0d82d3 15 {
taylorza 0:b7c65c0d82d3 16 uint32_t carrierHalfPeriod = 0;
taylorza 0:b7c65c0d82d3 17
taylorza 0:b7c65c0d82d3 18 if (carrierFrequency > 0)
taylorza 0:b7c65c0d82d3 19 {
taylorza 0:b7c65c0d82d3 20 carrierHalfPeriod = (uint32_t)(500000 / carrierFrequency);
taylorza 0:b7c65c0d82d3 21
taylorza 0:b7c65c0d82d3 22 bool state = initialState;
taylorza 0:b7c65c0d82d3 23 for(uint16_t i = 0; i < bufferCount; i++)
taylorza 0:b7c65c0d82d3 24 {
taylorza 0:b7c65c0d82d3 25 int c = (int)((double)timingBuffer[i] / carrierHalfPeriod);
taylorza 0:b7c65c0d82d3 26 if (!state)
taylorza 0:b7c65c0d82d3 27 {
taylorza 0:b7c65c0d82d3 28 wait_us(timingBuffer[i]);
taylorza 0:b7c65c0d82d3 29 }
taylorza 0:b7c65c0d82d3 30 else
taylorza 0:b7c65c0d82d3 31 {
taylorza 0:b7c65c0d82d3 32 for(int j = 0; j < c; j += 2)
taylorza 0:b7c65c0d82d3 33 {
taylorza 0:b7c65c0d82d3 34 _pin = 1;
taylorza 0:b7c65c0d82d3 35 wait_us(carrierHalfPeriod);
taylorza 0:b7c65c0d82d3 36 _pin = 0;
taylorza 0:b7c65c0d82d3 37 wait_us(carrierHalfPeriod);
taylorza 0:b7c65c0d82d3 38 }
taylorza 0:b7c65c0d82d3 39 }
taylorza 0:b7c65c0d82d3 40 state = !state;
taylorza 0:b7c65c0d82d3 41 }
taylorza 0:b7c65c0d82d3 42
taylorza 0:b7c65c0d82d3 43 if (lastStateHoldTime > 0)
taylorza 0:b7c65c0d82d3 44 {
taylorza 0:b7c65c0d82d3 45 int c = (int)((double)lastStateHoldTime / carrierHalfPeriod);
taylorza 0:b7c65c0d82d3 46 if (!state)
taylorza 0:b7c65c0d82d3 47 {
taylorza 0:b7c65c0d82d3 48 wait_us(lastStateHoldTime);
taylorza 0:b7c65c0d82d3 49 }
taylorza 0:b7c65c0d82d3 50 else
taylorza 0:b7c65c0d82d3 51 {
taylorza 0:b7c65c0d82d3 52 for(int j = 0; j < c; j += 2)
taylorza 0:b7c65c0d82d3 53 {
taylorza 0:b7c65c0d82d3 54 _pin = 1;
taylorza 0:b7c65c0d82d3 55 wait_us(carrierHalfPeriod);
taylorza 0:b7c65c0d82d3 56 _pin = 0;
taylorza 0:b7c65c0d82d3 57 wait_us(carrierHalfPeriod);
taylorza 0:b7c65c0d82d3 58 }
taylorza 0:b7c65c0d82d3 59 }
taylorza 0:b7c65c0d82d3 60 }
taylorza 0:b7c65c0d82d3 61 }
taylorza 0:b7c65c0d82d3 62 else
taylorza 0:b7c65c0d82d3 63 {
taylorza 0:b7c65c0d82d3 64 set(initialState);
taylorza 0:b7c65c0d82d3 65 for(uint16_t i = 0; i < bufferCount; ++i)
taylorza 0:b7c65c0d82d3 66 {
taylorza 0:b7c65c0d82d3 67 wait_us(timingBuffer[i]);
taylorza 0:b7c65c0d82d3 68 _pin = !_pin;
taylorza 0:b7c65c0d82d3 69 }
taylorza 0:b7c65c0d82d3 70
taylorza 0:b7c65c0d82d3 71 if (lastStateHoldTime > 0)
taylorza 0:b7c65c0d82d3 72 {
taylorza 0:b7c65c0d82d3 73 wait_us(lastStateHoldTime);
taylorza 0:b7c65c0d82d3 74 }
taylorza 0:b7c65c0d82d3 75 }
taylorza 0:b7c65c0d82d3 76 }