Revision 4:64d2d834341b, committed 2014-09-14
- Comitter:
- taylorza
- Date:
- Sun Sep 14 05:36:57 2014 +0000
- Parent:
- 3:f30dcc6e8e70
- Commit message:
- Added support for asynchronous signal generation
Changed in this revision
diff -r f30dcc6e8e70 -r 64d2d834341b SignalGenerator.cpp
--- a/SignalGenerator.cpp Sat Sep 13 21:40:16 2014 +0000
+++ b/SignalGenerator.cpp Sun Sep 14 05:36:57 2014 +0000
@@ -4,13 +4,27 @@
#include "mbed.h"
#include "SignalGenerator.h"
-SignalGenerator::SignalGenerator(PinName pin) : _pin(pin)
+SignalGenerator::SignalGenerator(PinName pin)
+ : _pin(pin),
+ _pTicker(NULL),
+ _pInternalTimingBuffer(NULL)
{
}
+
+SignalGenerator::~SignalGenerator()
+{
+ stopAsync();
+
+ if (_pTicker != NULL)
+ {
+ delete _pTicker;
+ }
+}
void SignalGenerator::set(bool pinState)
{
+ stopAsync();
_pin = pinState ? 1 : 0;
}
@@ -18,17 +32,26 @@
bool initialState,
uint32_t timingBuffer[],
uint16_t bufferCount,
+ bool disableInterrupts,
uint32_t lastStateHoldTime,
int32_t carrierFrequency)
{
+ stopAsync();
+
if (timingBuffer == NULL || bufferCount == 0)
{
return;
}
-
+
+ int alreadyDisabledIrq = 1;
+ if (disableInterrupts)
+ {
+ alreadyDisabledIrq = __disable_irq();
+ }
+
+ Timer transitionTimer;
uint16_t lastTiming = bufferCount - 1;
- Timer transitionTimer;
if (carrierFrequency > 0)
{
int timingIndex = 0;
@@ -37,7 +60,7 @@
uint32_t carrierHalfPeriod = (500000 / carrierFrequency);
uint32_t compare = timingBuffer[timingIndex++];
uint32_t carrierCompare = carrierHalfPeriod;
-
+
transitionTimer.start();
while(true)
{
@@ -78,8 +101,9 @@
{
int timingIndex = 0;
uint32_t compare = timingBuffer[timingIndex++];
- transitionTimer.start();
- set(initialState);
+
+ transitionTimer.start();
+ _pin = initialState ? 1 : 0;
while(true)
{
if (transitionTimer.read_us() >= compare)
@@ -98,4 +122,66 @@
}
}
}
+
+ if (!alreadyDisabledIrq) __enable_irq();
+}
+
+void SignalGenerator::asyncStep()
+{
+ _pin = !_pin;
+
+ _bufferIndex++;
+ if (_bufferIndex < _bufferCount)
+ {
+ _pTicker->attach_us(this, &SignalGenerator::asyncStep, _pInternalTimingBuffer[_bufferIndex]);
+ }
+ else if (_repeat)
+ {
+ _bufferIndex = 0;
+ _pTicker->attach_us(this, &SignalGenerator::asyncStep, _pInternalTimingBuffer[_bufferIndex]);
+ }
+ else
+ {
+ stopAsync();
+ }
+}
+
+void SignalGenerator::setAsync(
+ bool initialState,
+ uint32_t timingBuffer[],
+ uint16_t bufferCount,
+ bool repeat)
+{
+ stopAsync();
+
+ if (_pTicker == NULL)
+ {
+ _pTicker = new Timeout;
+ }
+
+ _pInternalTimingBuffer = new uint32_t[bufferCount];
+ _bufferCount = bufferCount;
+ _repeat = repeat;
+ _bufferIndex = 0;
+
+ for(int i = 0; i < bufferCount; ++i)
+ {
+ _pInternalTimingBuffer[i] = timingBuffer[i] > 15 ? timingBuffer[i] - 10 : 5;
+ }
+
+ _pin = initialState ? 1 : 0;
+ _pTicker->attach_us(this, &SignalGenerator::asyncStep, _pInternalTimingBuffer[_bufferIndex]);
+}
+
+void SignalGenerator::stopAsync()
+{
+ if (_pTicker != NULL)
+ {
+ _pTicker->detach();
+ }
+
+ if (_pInternalTimingBuffer != NULL)
+ {
+ delete[] _pInternalTimingBuffer;
+ }
}
\ No newline at end of file
diff -r f30dcc6e8e70 -r 64d2d834341b SignalGenerator.h
--- a/SignalGenerator.h Sat Sep 13 21:40:16 2014 +0000
+++ b/SignalGenerator.h Sun Sep 14 05:36:57 2014 +0000
@@ -12,13 +12,17 @@
/** Create a SignalGenerator tied to the specified pin. */
SignalGenerator(PinName pin);
+ /** Clean up the SignalGenerator data. */
+ ~SignalGenerator();
+
/** Set the state of the pin associated with the SignalGenerator. */
void set(bool pinState);
- /** Set parameter and generate the corresponding signal on the pin associated with the SignalGenerator.
+ /** Generates the square wave signal on the pin associated with the SignalGenerator.
* @param initialState Defines the initial state of the signal pin
* @param timingBuffer Specificies the wime periods in microseconds before the signal pin changes state
* @param bufferCount The count of transition times passed in the timingBuffer
+ * @param disableInterrupts If true disables interrupts during the generation of the signal
* @param lastStateHoldTime The time in microseconds that the last state is held
* @param carrierFrequency The carrier frequency in Hz
*/
@@ -26,10 +30,33 @@
bool initialState,
uint32_t timingBuffer[],
uint16_t bufferCount,
+ bool disableInterrupts,
uint32_t lastStateHoldTime = 0,
int32_t carrierFrequency = -1);
+
+ /** Asynchronously generates the square wave signal on the pin associated with the SignalGenerator.
+ * @param initialState Defines the initial state of the signal pin
+ * @param timingBuffer Specificies the wime periods in microseconds before the signal pin changes state
+ * @param bufferCount The count of transition times passed in the timingBuffer
+ * @param repeat If true the signal generation will wrap around to the begining of the timingBuffer after each iteration through the buffer completes.
+ * @note To stop the asynchronous signal you can call any of the non-async set commands to set the pin to a final state.
+ */
+ void setAsync(
+ bool initialState,
+ uint32_t timingBuffer[],
+ uint16_t bufferCount,
+ bool repeat);
private:
- DigitalOut _pin;
+ void asyncStep();
+ void stopAsync();
+
+ private:
+ DigitalOut _pin;
+ Timeout *_pTicker;
+ uint32_t *_pInternalTimingBuffer;
+ uint16_t _bufferCount;
+ uint16_t _bufferIndex;
+ bool _repeat;
};
#endif //__SIGNALGENERATOR_H__
\ No newline at end of file