Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: IniManager RA8875 Watchdog mbed-rtos mbed
Fork of speaker_demo_Analog by
Revision 6:1f48212fbaf9, committed 2017-05-20
- Comitter:
- WiredHome
- Date:
- Sat May 20 19:52:23 2017 +0000
- Parent:
- 5:49dd0c647a40
- Commit message:
- Signal Generator - a work in process as the need arises.
Changed in this revision
--- a/RA8875.lib Mon Jan 16 22:57:59 2017 +0000 +++ b/RA8875.lib Sat May 20 19:52:23 2017 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/WiredHome/code/RA8875/#33ca352755a2 +http://mbed.org/users/WiredHome/code/RA8875/#e872d65a710d
--- a/SignalGenDAC.cpp Mon Jan 16 22:57:59 2017 +0000
+++ b/SignalGenDAC.cpp Sat May 20 19:52:23 2017 +0000
@@ -1,8 +1,11 @@
+//
+// Signal Generate DAC Driver
+//
+// Derived from AN10917: Memory to DAC data transfers using the LPC1700's DMA
+//
#include "SignalGenDAC.h"
-DigitalOut led(LED1);
-
#define PI 3.14159 // for the sine-wave
/// The linked list structure used to control the DMA transfer
@@ -36,13 +39,7 @@
void SignalGenDAC::Start(bool oneShot) {
printf("Start(%d) w/%d samples\r\n", oneShot ? 1 : 0, numSamples);
isOn = (oneShot) ? false : true;
- led = 1;
- for (int x=0; x<numSamples; x++) {
- DACsignal[x] = ((uint16_t)(VoltSignal[x]/maxV * 1023) << 6);
- printf("%3d, %5.3f, %d\r\n", x, VoltSignal[x], DACsignal[x]);
- }
-
llio.source = (uint32_t)DACsignal;
llio.destination = (uint32_t)&LPC_DAC->DACR;
llio.next = (uint32_t)&llio;
@@ -57,9 +54,10 @@
/* Load DMA Channel0 */
LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)DACsignal;
LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_DAC->DACR;
- LPC_GPDMACH0->DMACCLLI = (uint32_t)&llio;
+ LPC_GPDMACH0->DMACCLLI = (oneShot) ? 0 : (uint32_t)&llio;
- LPC_GPDMACH0->DMACCControl = numSamples // transfer size (0 - 11) = 64
+ int playSampleCount = numSamples + oneShot;
+ LPC_GPDMACH0->DMACCControl = playSampleCount // transfer size (0 - 11) = 64
| (0 << 12) // source burst size (12 - 14) = 1
| (0 << 15) // destination burst size (15 - 17) = 1
| (2 << 18) // source width (18 - 20) = 32 bit
@@ -83,7 +81,7 @@
| (0 << 18); // (27) = no HALT
/* DACclk = 25 MHz, so 10 usec interval */
- LPC_DAC->DACCNTVAL = 20; // 16-bit reload value
+ LPC_DAC->DACCNTVAL = 18; // 16-bit reload value
/* DMA, timer running, dbuff */
LPC_DAC->DACCTRL =
1<<3 // DMA_ENA dma burst is enabled
@@ -98,11 +96,10 @@
wait_ms(1);
aout->write(offset / maxV);
isOn = false;
- led = 0;
}
-void SignalGenDAC::PrepareWaveform(SG_Mode mode, float _frequency, float _dutycycle, float _voltage, float _offset) {
+void SignalGenDAC::PrepareWaveform(SG_Waveform mode, float _frequency, float _dutycycle, float _voltage, float _offset) {
int x, dcCount, firstQtr, lastQtr;
frequency = _frequency;
dutycycle = _dutycycle;
@@ -112,7 +109,7 @@
float mid = rangelimit(offset, minV, maxV);
float low = rangelimit(offset - voltage/2, minV, maxV);
float v;
- numSamples = 32; // Ideally, compute this based on the frequency for good resolution
+ numSamples = 128; // Ideally, compute this based on the frequency for good resolution
dcCount = dutycycle/100.0 * numSamples;
firstQtr = dcCount / 2;
lastQtr = dcCount + (numSamples - dcCount)/2;
@@ -133,16 +130,20 @@
v = rangelimit(v, minV, maxV);
VoltSignal[x] = v;
}
+ VoltSignal[numSamples] = rangelimit(offset, minV, maxV);
break;
case SG_SQUARE:
for (x=0; x<numSamples; x++) {
- if (x < dcCount) {
+ if (0 && x == 0) {
+ v = rangelimit(offset, minV, maxV);
+ } else if (x < dcCount) {
v = rangelimit(offset + voltage/2, minV, maxV);
} else {
v = rangelimit(offset - voltage/2, minV, maxV);
}
VoltSignal[x] = v;
}
+ VoltSignal[numSamples] = rangelimit(offset, minV, maxV);
break;
case SG_TRIANGLE:
for (x=0; x<numSamples; x++) {
@@ -161,6 +162,7 @@
}
VoltSignal[x] = v;
}
+ VoltSignal[numSamples] = rangelimit(offset, minV, maxV);
break;
case SG_SAWTOOTH:
for (x=0; x<numSamples; x++) {
@@ -172,12 +174,13 @@
v = rangelimit(v, minV, maxV);
VoltSignal[x] = v;
}
+ VoltSignal[numSamples] = rangelimit(offset, minV, maxV);
break;
case SG_USER:
break;
}
//printf("DAC Data %3.2f %3.2f\r\n", voltage, offset);
- for (x=0; x<numSamples; x++) {
+ for (x=0; x<=numSamples; x++) {
DACsignal[x] = ((uint16_t)(VoltSignal[x]/maxV * 1023) << 6);
printf("%3d, %5.3f, %d\r\n", x, VoltSignal[x], DACsignal[x]);
}
--- a/SignalGenDAC.h Mon Jan 16 22:57:59 2017 +0000
+++ b/SignalGenDAC.h Sat May 20 19:52:23 2017 +0000
@@ -1,7 +1,9 @@
-
+//
+// Signal Generator DAC Driver
//
// Derived from AN10917: Memory to DAC data transfers using the LPC1700's DMA
//
+//
#ifndef SIGNALGENDAC_H
#define SIGNALGENDAC_H
@@ -12,6 +14,24 @@
#define SIGNAL_MEM_ENTRIES 2048 // size of the DAC buffer
+/// The Signal Generator DAC Driver
+///
+/// This class provides the interface to first configure the DAC hardware characteristics,
+/// and then to define and control the DAC output.
+///
+/// A choice of waveforms is available (Sine, Square, Triangle, Sawtooth, and User Defined.
+///
+/// @todo add support for User Defined waveform.
+///
+/// @code
+/// SignalGenDAC g_signal; // defaults to LPC1768 mbed module (p18 and 3.3v)
+///
+/// g_signal.PrepareWaveform(SG_SINE, 1000, 50, 2.2, 1.5);
+/// g_signal.Start();
+/// wait_ms(1000);
+/// g_signal.Stop();
+/// @endcode
+///
class SignalGenDAC {
public:
@@ -40,7 +60,7 @@
/// @param[in] voltage is the peak-to-peak voltage, and it range limited to 0 to 3.0.
/// @param[in] offset is the offset voltage, and is range limited to 0 to 3.0.
///
- void PrepareWaveform(SG_Mode mode, float frequency, float dutycycle, float voltage, float offset);
+ void PrepareWaveform(SG_Waveform mode, float frequency, float dutycycle, float voltage, float offset);
/// Start the signal, in either a oneshot, or continuous mode.
///
--- a/SignalGenDefs.h Mon Jan 16 22:57:59 2017 +0000
+++ b/SignalGenDefs.h Sat May 20 19:52:23 2017 +0000
@@ -16,6 +16,6 @@
SG_USER, ///< User defined waveform
SG_KEYPAD, ///< This is an internal value, not for applications
SG_START, ///< This is the start/stop/pulse button
-} SG_Mode;
+} SG_Waveform;
#endif // SIGNALGENDEFS_H
--- a/SignalGenDisplay.cpp Mon Jan 16 22:57:59 2017 +0000
+++ b/SignalGenDisplay.cpp Sat May 20 19:52:23 2017 +0000
@@ -93,7 +93,7 @@
{ BTN_MODE_X+4*(BTN_W+BTN_S),BTN_MODE_Y, BTN_MODE_X+4*(BTN_W+BTN_S)+BTN_W,BTN_MODE_Y+BTN_H },
};
static const int ModeCount = sizeof(ModeButtons)/sizeof(ModeButtons[0]);
-static const SG_Mode UI_ModeList[] = {
+static const SG_Waveform UI_ModeList[] = {
SG_SINE,
SG_SQUARE,
SG_TRIANGLE,
@@ -317,6 +317,7 @@
for (int i=0; i<radio_CyclesCount; i++) {
if (lcd->Intersect(radio_Cycles[i], point)) {
pulseMode = i;
+ SaveSettings(OM_PULSE);
signal->Stop();
ShowCyclesControl();
}
@@ -346,7 +347,7 @@
ini.ReadString("Signal", "Waveform", buf, sizeof(buf), ModeNames[0]);
for (int i=0; i<ModeCount; i++) {
if (strcmp(ModeNames[i], buf) == 0) {
- mode = (SG_Mode)i;
+ mode = (SG_Waveform)i;
printf("Read ini mode is %d\r\n", mode);
break;
}
@@ -761,7 +762,7 @@
return ret;
}
-bool SignalGenDisplay::SetWaveformMode(SG_Mode _mode, bool force) {
+bool SignalGenDisplay::SetWaveformMode(SG_Waveform _mode, bool force) {
if (/* _mode >= SG_SINE && */ _mode <= SG_USER) {
mode = _mode;
printf("mode is %d\r\n", mode);
@@ -949,7 +950,7 @@
// . | | \ / / |
// ++ +----+ + + +
//
-void SignalGenDisplay::DrawWaveform(rect_t r, SG_Mode mode, color_t color, bool drawPure) {
+void SignalGenDisplay::DrawWaveform(rect_t r, SG_Waveform mode, color_t color, bool drawPure) {
loc_t x,y;
loc_t y0 = (r.p1.y + r.p2.y)/2;
dim_t w = r.p2.x - r.p1.x;
@@ -1165,7 +1166,7 @@
}
}
-void SignalGenDisplay::DrawButton(rect_t r, bool pressed, SG_Mode mode, bool enable, int label) {
+void SignalGenDisplay::DrawButton(rect_t r, bool pressed, SG_Waveform mode, bool enable, int label) {
rect_t wave;
color_t buttonface = UI_BUTTON_FACE_DISABLED;
color_t buttonshadow = UI_BUTTON_SHADOW_DISABLED;
@@ -1273,10 +1274,12 @@
printf("SaveSettings - timeout [%02X]\r\n", Changes);
if (Changes & OM_MODE) {
Changes &= ~ OM_MODE;
+ printf(" Signal:Waveform=%s\r\n", ModeNames[mode]);
ini.WriteString("Signal", "Waveform", ModeNames[mode]);
}
if (Changes & OM_PULSE) {
Changes &= ~ OM_PULSE;
+ printf(" Signal:Pulse Mode=%s\r\n", PulseModeLabels[pulseMode]);
ini.WriteString("Signal", "Pulse Mode", PulseModeLabels[pulseMode]);
}
if (Changes & OM_FREQ) {
--- a/SignalGenDisplay.h Mon Jan 16 22:57:59 2017 +0000
+++ b/SignalGenDisplay.h Sat May 20 19:52:23 2017 +0000
@@ -169,7 +169,7 @@
/// @param[in] force as true will force it to set the mode, redrawing the screen
/// @returns true if the value was accepted
///
- bool SetWaveformMode(SG_Mode mode, bool force = false);
+ bool SetWaveformMode(SG_Waveform mode, bool force = false);
/// Operating mode changes
///
@@ -226,7 +226,7 @@
VS_Settings,
} VisualScreen;
VisualScreen vis;
- SG_Mode mode; ///< signal mode
+ SG_Waveform mode; ///< signal mode
float frequency; ///< selected frequency
float dutycycle; ///< selected duty cycle
float voltage; ///< selected voltage
@@ -266,8 +266,8 @@
void DrawNavGadget(void);
void DrawModeButtons(void);
void DrawKeypadEnabled(bool enable = false);
- void DrawButton(rect_t r, bool pressed, SG_Mode mode, bool enable = false, int label=0);
- void DrawWaveform(rect_t r, SG_Mode mode, color_t color, bool drawPure = false); // pure ignores, voltage,offset,dutycycle
+ void DrawButton(rect_t r, bool pressed, SG_Waveform mode, bool enable = false, int label=0);
+ void DrawWaveform(rect_t r, SG_Waveform mode, color_t color, bool drawPure = false); // pure ignores, voltage,offset,dutycycle
float rangelimit(float value, float minV, float maxV);
void ShowCyclesControl(void);
--- a/SignalGenModel.h Mon Jan 16 22:57:59 2017 +0000 +++ b/SignalGenModel.h Sat May 20 19:52:23 2017 +0000 @@ -0,0 +1,5 @@ +// +// +// In the transition to an improved architecture, this will be the interface/glue +// between the DAC driver and the User Interface. +//
--- a/main.cpp Mon Jan 16 22:57:59 2017 +0000
+++ b/main.cpp Sat May 20 19:52:23 2017 +0000
@@ -26,16 +26,6 @@
wd.Configure(30.0);
//ini.SetFile("/local/SigGen.ini", 2);
-#if 0
- aout = 0.25;
- wait_ms(25);
- aout = 0.50;
- wait_ms(25);
- aout = 0.75;
- wait_ms(25);
- aout = 1.00;
- wait_ms(25);
-#endif
lcd.init(480,272,16, true, true, true);
while (true)
{
