Signal Generator
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
diff -r 49dd0c647a40 -r 1f48212fbaf9 RA8875.lib --- 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
diff -r 49dd0c647a40 -r 1f48212fbaf9 SignalGenDAC.cpp --- 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]); }
diff -r 49dd0c647a40 -r 1f48212fbaf9 SignalGenDAC.h --- 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. ///
diff -r 49dd0c647a40 -r 1f48212fbaf9 SignalGenDefs.h --- 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
diff -r 49dd0c647a40 -r 1f48212fbaf9 SignalGenDisplay.cpp --- 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) {
diff -r 49dd0c647a40 -r 1f48212fbaf9 SignalGenDisplay.h --- 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);
diff -r 49dd0c647a40 -r 1f48212fbaf9 SignalGenModel.h --- 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. +//
diff -r 49dd0c647a40 -r 1f48212fbaf9 main.cpp --- 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) {