This library provides a class to generate differents signale wave form. Note that the maximum update rate of 1 MHz, so Fmax = 1MHz / _num_pixels (see UM10360 - Chapter 30: LPC17xx Digital-to-Analog Converter (DAC).
SignalGenerator.cpp@1:d6cbee8595e0, 2010-11-22 (annotated)
- Committer:
- Yann
- Date:
- Mon Nov 22 08:14:22 2010 +0000
- Revision:
- 1:d6cbee8595e0
- Parent:
- 0:40051400cafe
V0.0.2
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Yann | 0:40051400cafe | 1 | #include "SignalGenerator.h" |
Yann | 0:40051400cafe | 2 | |
Yann | 0:40051400cafe | 3 | #define PI 3.1415 |
Yann | 0:40051400cafe | 4 | |
Yann | 0:40051400cafe | 5 | SignalGenerator::SignalGenerator(PinName p_outPort) : _out(p_outPort), _asyncTicker(), _debugLed(LED4) { |
Yann | 0:40051400cafe | 6 | _debugLed = 0; |
Yann | 0:40051400cafe | 7 | _mode = true; // _num_pixels is fixed, _twait is computed |
Yann | 0:40051400cafe | 8 | _stop = false; |
Yann | 0:40051400cafe | 9 | _values = NULL; |
Yann | 0:40051400cafe | 10 | SetSignalFrequency(); |
Yann | 0:40051400cafe | 11 | } // End of SignalGenerator::SignalGenerator |
Yann | 0:40051400cafe | 12 | |
Yann | 0:40051400cafe | 13 | SignalGenerator::~SignalGenerator() { |
Yann | 0:40051400cafe | 14 | if (_values != NULL) { |
Yann | 0:40051400cafe | 15 | delete [] _values; |
Yann | 0:40051400cafe | 16 | } |
Yann | 0:40051400cafe | 17 | } // End of SignalGenerator::~SignalGenerator |
Yann | 0:40051400cafe | 18 | |
Yann | 0:40051400cafe | 19 | void SignalGenerator::SetSignalFrequency(SignalGenerator::SignalGeneratorType p_signalType, int p_frequency, int p_num_pixels) { |
Yann | 0:40051400cafe | 20 | DEBUG_ENTER("SignalGenerator::SetSignalFrequency") |
Yann | 0:40051400cafe | 21 | if (_values != NULL) { |
Yann | 0:40051400cafe | 22 | DEBUG("SignalGenerator::SetSignalFrequency: Delete _values"); |
Yann | 0:40051400cafe | 23 | delete [] _values; |
Yann | 0:40051400cafe | 24 | } |
Yann | 0:40051400cafe | 25 | |
Yann | 0:40051400cafe | 26 | _signalType = p_signalType; |
Yann | 0:40051400cafe | 27 | _frequency = p_frequency; |
Yann | 0:40051400cafe | 28 | _num_pixels = p_num_pixels; |
Yann | 1:d6cbee8595e0 | 29 | DEBUG("SignalGenerator::SetSignalFrequency: _frequency=%d", _frequency) |
Yann | 0:40051400cafe | 30 | if (_mode) { |
Yann | 0:40051400cafe | 31 | //_twait = 1000000.0f / (_frequency * _num_pixels); // _num_pixels is set to 1000 pixels/T |
Yann | 0:40051400cafe | 32 | _twait = 1.0f / (_frequency * _num_pixels); // _num_pixels is set to 1000 pixels/T |
Yann | 0:40051400cafe | 33 | } else { |
Yann | 0:40051400cafe | 34 | _twait = 0.000001f; // 1us |
Yann | 0:40051400cafe | 35 | _num_pixels = (int)(1.0f / (_frequency * _twait)); // t_w is set to 1us and we fix at least 1000 pixels per period (T >> t_w): T >= 1000 * t_w ==> F < 1KHz |
Yann | 0:40051400cafe | 36 | } |
Yann | 1:d6cbee8595e0 | 37 | DEBUG("SignalGenerator::SetSignalFrequency: _twait=%f", _twait) |
Yann | 1:d6cbee8595e0 | 38 | DEBUG("SignalGenerator::SetSignalFrequency: _num_pixels=%d", _num_pixels) |
Yann | 0:40051400cafe | 39 | _values = new float[_num_pixels]; |
Yann | 0:40051400cafe | 40 | PrepareSignal(); |
Yann | 0:40051400cafe | 41 | DEBUG_LEAVE("SignalGenerator::SetSignalFrequency") |
Yann | 0:40051400cafe | 42 | } // End of SignalGenerator::SetSignalFrequency |
Yann | 0:40051400cafe | 43 | |
Yann | 0:40051400cafe | 44 | void SignalGenerator::PrepareSignal() { |
Yann | 0:40051400cafe | 45 | switch (_signalType) { |
Yann | 0:40051400cafe | 46 | case SquareSignal: |
Yann | 0:40051400cafe | 47 | PrepareSquareSignal(); |
Yann | 0:40051400cafe | 48 | break; |
Yann | 0:40051400cafe | 49 | case TriangleSignal: |
Yann | 0:40051400cafe | 50 | PrepareTriangleSignal(); |
Yann | 0:40051400cafe | 51 | break; |
Yann | 0:40051400cafe | 52 | case SawtoothSignal: |
Yann | 0:40051400cafe | 53 | PrepareSawtoothSignal(); |
Yann | 0:40051400cafe | 54 | break; |
Yann | 0:40051400cafe | 55 | case ReverseSawtoothSignal: |
Yann | 0:40051400cafe | 56 | PrepareReverseSawtoothSignal(); |
Yann | 0:40051400cafe | 57 | break; |
Yann | 0:40051400cafe | 58 | case SinusSignal: |
Yann | 0:40051400cafe | 59 | PrepareSinusSignal(); |
Yann | 0:40051400cafe | 60 | break; |
Yann | 0:40051400cafe | 61 | } // End of 'switch' statement |
Yann | 0:40051400cafe | 62 | } // End of SignalGenerator::PrepareSignal |
Yann | 0:40051400cafe | 63 | |
Yann | 0:40051400cafe | 64 | void SignalGenerator::Run() { |
Yann | 0:40051400cafe | 65 | DEBUG_ENTER("SignalGenerator::Run") |
Yann | 0:40051400cafe | 66 | do { |
Yann | 0:40051400cafe | 67 | for (int i = 0; i < _num_pixels; i++) { |
Yann | 0:40051400cafe | 68 | _out = *(_values + i); |
Yann | 0:40051400cafe | 69 | //DEBUG_1f("SignalGenerator::Run: Current=", (float)_out) |
Yann | 0:40051400cafe | 70 | wait(_twait); |
Yann | 0:40051400cafe | 71 | } |
Yann | 0:40051400cafe | 72 | } while (!_stop); |
Yann | 0:40051400cafe | 73 | _out = 0.0f; // Reset output |
Yann | 0:40051400cafe | 74 | DEBUG_LEAVE("SignalGenerator::Run") |
Yann | 0:40051400cafe | 75 | } // End of SignalGenerator::Run |
Yann | 0:40051400cafe | 76 | |
Yann | 0:40051400cafe | 77 | void SignalGenerator::Stop() { |
Yann | 0:40051400cafe | 78 | DEBUG_ENTER("SignalGenerator::Stop") |
Yann | 0:40051400cafe | 79 | _stop = true; |
Yann | 0:40051400cafe | 80 | DEBUG_LEAVE("SignalGenerator::Stop") |
Yann | 0:40051400cafe | 81 | } // End of SignalGenerator::Stop |
Yann | 0:40051400cafe | 82 | |
Yann | 0:40051400cafe | 83 | int SignalGenerator::BeginRunAsync() { |
Yann | 0:40051400cafe | 84 | DEBUG_ENTER("SignalGenerator::BeginRunAsync") |
Yann | 0:40051400cafe | 85 | if (_twait < 0.000007f) { |
Yann | 0:40051400cafe | 86 | return -1; |
Yann | 0:40051400cafe | 87 | } else { |
Yann | 0:40051400cafe | 88 | _asynckCounter = 0; |
Yann | 0:40051400cafe | 89 | _asyncTicker.attach(this, &SignalGenerator::RunAsync, _twait); |
Yann | 0:40051400cafe | 90 | } |
Yann | 0:40051400cafe | 91 | DEBUG_LEAVE("SignalGenerator::BeginRunAsync") |
Yann | 0:40051400cafe | 92 | return 0; |
Yann | 0:40051400cafe | 93 | } // End of SignalGenerator::BeginRunAsync |
Yann | 0:40051400cafe | 94 | |
Yann | 0:40051400cafe | 95 | void SignalGenerator::RunAsync() { |
Yann | 0:40051400cafe | 96 | //DEBUG_ENTER("SignalGenerator::RunAsync") |
Yann | 0:40051400cafe | 97 | _debugLed = !_debugLed; |
Yann | 0:40051400cafe | 98 | _out = *(_values + _asynckCounter++); |
Yann | 0:40051400cafe | 99 | _asynckCounter %= _num_pixels; |
Yann | 0:40051400cafe | 100 | //DEBUG_LEAVE("SignalGenerator::RunAsync") |
Yann | 0:40051400cafe | 101 | } // End of SignalGenerator::RunAsync |
Yann | 0:40051400cafe | 102 | |
Yann | 0:40051400cafe | 103 | void SignalGenerator::EndRunAsync() { |
Yann | 0:40051400cafe | 104 | DEBUG_ENTER("SignalGenerator::EndRunAsync") |
Yann | 0:40051400cafe | 105 | _asyncTicker.detach(); |
Yann | 0:40051400cafe | 106 | _out = 0.0f; // Reset output |
Yann | 0:40051400cafe | 107 | DEBUG_LEAVE("SignalGenerator::EndRunAsync") |
Yann | 0:40051400cafe | 108 | } // End of SignalGenerator::EndRunAsync |
Yann | 0:40051400cafe | 109 | |
Yann | 0:40051400cafe | 110 | SignalGenerator& SignalGenerator::operator =(const int& p_frequency) { |
Yann | 0:40051400cafe | 111 | DEBUG_ENTER("SignalGenerator::operator =") |
Yann | 0:40051400cafe | 112 | if (_frequency != p_frequency) { |
Yann | 0:40051400cafe | 113 | this->SetSignalFrequency(_signalType, p_frequency); |
Yann | 0:40051400cafe | 114 | } |
Yann | 0:40051400cafe | 115 | DEBUG_LEAVE("SignalGenerator::operator =") |
Yann | 0:40051400cafe | 116 | return *this; |
Yann | 0:40051400cafe | 117 | } // End of SignalGenerator::operator = |
Yann | 0:40051400cafe | 118 | |
Yann | 0:40051400cafe | 119 | SignalGenerator& SignalGenerator::operator =(const bool& p_mode) { |
Yann | 0:40051400cafe | 120 | DEBUG_ENTER("SignalGenerator::operator =") |
Yann | 0:40051400cafe | 121 | if (_mode != p_mode) { |
Yann | 0:40051400cafe | 122 | _mode = p_mode; |
Yann | 0:40051400cafe | 123 | this->SetSignalFrequency(_signalType, _frequency); |
Yann | 0:40051400cafe | 124 | } |
Yann | 0:40051400cafe | 125 | DEBUG_LEAVE("SignalGenerator::operator =") |
Yann | 0:40051400cafe | 126 | return *this; |
Yann | 0:40051400cafe | 127 | } // End of SignalGenerator::operator = |
Yann | 0:40051400cafe | 128 | |
Yann | 0:40051400cafe | 129 | SignalGenerator& SignalGenerator::operator =(const SignalGenerator::SignalGeneratorType& p_signalType) { |
Yann | 0:40051400cafe | 130 | DEBUG_ENTER("SignalGenerator::operator =") |
Yann | 0:40051400cafe | 131 | this->SetSignalFrequency(p_signalType, _frequency); |
Yann | 0:40051400cafe | 132 | DEBUG_LEAVE("SignalGenerator::operator =") |
Yann | 0:40051400cafe | 133 | return *this; |
Yann | 0:40051400cafe | 134 | |
Yann | 0:40051400cafe | 135 | } // End of SignalGenerator::operator = |
Yann | 0:40051400cafe | 136 | |
Yann | 0:40051400cafe | 137 | void SignalGenerator::PrepareSquareSignal() { |
Yann | 0:40051400cafe | 138 | DEBUG_ENTER("SignalGenerator::PrepareSquareSignal") |
Yann | 0:40051400cafe | 139 | int step = _num_pixels / 2; |
Yann | 0:40051400cafe | 140 | for (int i = 0; i < step; i += 1) { |
Yann | 0:40051400cafe | 141 | *(_values + i) = 1.0f; |
Yann | 0:40051400cafe | 142 | } // End of 'for' statement |
Yann | 0:40051400cafe | 143 | for (int i = step; i < _num_pixels; i += 1) { |
Yann | 0:40051400cafe | 144 | *(_values + i) = 0.0f; |
Yann | 0:40051400cafe | 145 | } // End of 'for' statement |
Yann | 0:40051400cafe | 146 | DEBUG_ENTER("SignalGenerator::PrepareSquareSignal") |
Yann | 0:40051400cafe | 147 | } // End of SignalGenerator::PrepareSquareSignal |
Yann | 0:40051400cafe | 148 | |
Yann | 0:40051400cafe | 149 | void SignalGenerator::PrepareTriangleSignal() { |
Yann | 0:40051400cafe | 150 | float step = 1.0f / (_num_pixels / 2.0f); |
Yann | 0:40051400cafe | 151 | int counter = 0; |
Yann | 0:40051400cafe | 152 | float i = 0.0f; |
Yann | 0:40051400cafe | 153 | for ( ; i < 1.0f; i += step) { |
Yann | 0:40051400cafe | 154 | *(_values + counter++) = i; |
Yann | 0:40051400cafe | 155 | } // End of 'for' statement |
Yann | 0:40051400cafe | 156 | for ( ; i >= 0.0f; i -= step) { |
Yann | 0:40051400cafe | 157 | *(_values + counter++) = i; |
Yann | 0:40051400cafe | 158 | } // End of 'for' statement |
Yann | 0:40051400cafe | 159 | } // End of SignalGenerator::PrepareTriangleSignal |
Yann | 0:40051400cafe | 160 | |
Yann | 0:40051400cafe | 161 | void SignalGenerator::PrepareSawtoothSignal() { |
Yann | 0:40051400cafe | 162 | float step = 1.0f / _num_pixels; |
Yann | 0:40051400cafe | 163 | int counter = 0; |
Yann | 0:40051400cafe | 164 | for (float i = 0.0f; i < 1.0f; i += step) { |
Yann | 0:40051400cafe | 165 | *(_values + counter++) = i; |
Yann | 0:40051400cafe | 166 | } // End of 'for' statement |
Yann | 0:40051400cafe | 167 | } // End of SignalGenerator::PrepareSawtoothSignal |
Yann | 0:40051400cafe | 168 | |
Yann | 0:40051400cafe | 169 | void SignalGenerator::PrepareReverseSawtoothSignal() { |
Yann | 0:40051400cafe | 170 | float step = 1.0f / _num_pixels; |
Yann | 0:40051400cafe | 171 | int counter = 0; |
Yann | 0:40051400cafe | 172 | for (float i = 0.0f; i < 1.0f; i += step) { |
Yann | 0:40051400cafe | 173 | *(_values + counter++) = (1.0f - i); |
Yann | 0:40051400cafe | 174 | } // End of 'for' statement |
Yann | 0:40051400cafe | 175 | } // End of SignalGenerator::PrepareReverseSawtoothSignal |
Yann | 0:40051400cafe | 176 | |
Yann | 0:40051400cafe | 177 | void SignalGenerator::PrepareSinusSignal() { |
Yann | 0:40051400cafe | 178 | float step = 1.0f / _num_pixels; |
Yann | 0:40051400cafe | 179 | int counter = 0; |
Yann | 0:40051400cafe | 180 | for (float i = 0.0f; i < 1.0f; i += step) { |
Yann | 0:40051400cafe | 181 | *(_values + counter++) = sin(2 * PI * i); |
Yann | 0:40051400cafe | 182 | } // End of 'for' statement |
Yann | 0:40051400cafe | 183 | } // End of SignalGenerator::PrepareSinusSignal |