Signal Generator
Dependencies: IniManager RA8875 Watchdog mbed-rtos mbed
Fork of speaker_demo_Analog by
Diff: SignalGenDisplay.cpp
- Revision:
- 2:8f71b71fce1b
- Parent:
- 1:dd07e1deec6c
- Child:
- 3:d22f3e52d06a
--- a/SignalGenDisplay.cpp Fri Jan 13 12:33:37 2017 +0000 +++ b/SignalGenDisplay.cpp Sun Jan 15 03:11:22 2017 +0000 @@ -1,4 +1,7 @@ - +// +// Signal Generator Control System +// +// #include "SignalGenDisplay.h" #include "rtos.h" #include "IniManager.h" @@ -8,16 +11,16 @@ // ##### Main Page ############################################################# // // +---------------------------------------------------------------------------+ -// | +------------------------------------------+ Progam Name and version | +// | +--- Scope Area ---------------------------+ Progam Name and version | // | | | Manufacturer name | -// | | | | -// | | | [ Text Entry Box ] | -// | | Scope Area | +------------------------+ | +// | | +---- Wave Outline - - | | +// | | | | [Text Entry Box] [ Back ] | +// | | | | | +// | | | +------------------------+ | // | | | | | | -// | | | | | | -// | | | | | | -// | | | | | | -// | | | | | | +// | | | | | | | +// | | | | | | | +// | | ---+ | | | | // | | | | Keypad Area | | // | +------------------------------------------+ | | | // | | | | @@ -29,82 +32,81 @@ // | [Sine ] [Square] [Triangle] [Sawtooth] [User] +------------------------+ | // +---------------------------------------------------------------------------+ - -#define UI_BackColor RGB(8,8,8) +// Object Colors +#define UI_BackColor RGB(8,8,8) +#define UI_ScopeBackColor RGB(0,0,0) +#define UI_ScopeFrameColor RGB(255,255,255) +#define WaveOutlineColor RGB(16,16,32) +#define UI_DutyColor Magenta +#define UI_FreqColor BrightRed +#define UI_VP2PColor Yellow +#define UI_VOffsetColor Green +#define UI_BUTTON_FACE_UP White +#define UI_BUTTON_FACE_DN RGB(255,92,92) +#define UI_BUTTON_SHADOW RGB(128,0,0) +#define UI_BUTTON_FACE_DISABLED RGB(24,24,24) +#define UI_BUTTON_SHADOW_DISABLED RGB(32,0,0) +#define UI_ProductNameColor UI_BUTTON_FACE_DN -const rect_t UI_DATA_ENTRY = {300,45, 475,65}; - +// Rectangular Zones +const rect_t UI_DATA_ENTRY = {300,53, 410,73}; const rect_t UI_SCOPE_RECT = {4,5, 290,160}; -#define UI_ScopeBackColor RGB(0,0,0) -#define UI_ScopeFrameColor RGB(255,255,255) +#define SC_LEFT_MARGIN 10 // Scope left margin +#define SC_TOP_MARGIN 20 +#define SC_RIGHT_MARGIN 30 +#define SC_BOT_MARGIN 30 +const rect_t UI_WAVE_RECT = {4+SC_LEFT_MARGIN,5+SC_TOP_MARGIN, 290-SC_RIGHT_MARGIN,160-SC_BOT_MARGIN}; -#define SC_LEFT_MARGIN 10 -#define SC_TOP_MARGIN 20 -#define SC_RIGHT_MARGIN 30 -#define SC_BOT_MARGIN 30 -#define WaveOutlineColor RGB(16,16,32) +#define BTN_W 54 // Button width +#define BTN_H 32 // Button height +#define BTN_S 5 // Button white-space + +#define BTN_MODE_X 2 // Mode Buttons left edge +#define BTN_MODE_Y 233 // Mode Buttons top edge + +#define BTN_KEYP_X 300 // Keypad left edge +#define BTN_KEYP_Y 53 // Keypad top edge const rect_t Parameters[] = { - {4,170, 60,190}, // 'd'uty cycle - {90,170, 186,190}, // 'f'requency - {90,200, 186,220}, // 'p'eriod - {230,170, 290,190}, // 'v'oltage - {230,200, 290,220} // 'o'ffset + {4,170, 60,190}, // 'd'uty cycle + {90,170, 186,190}, // 'f'requency + {90,200, 186,220}, // 'p'eriod + {230,170, 290,190}, // 'v'oltage + {230,200, 290,220} // 'o'ffset }; const int ParameterCount = sizeof(Parameters)/sizeof(Parameters[0]); -const char ParameterKeys[] = { 'd', 'f', 'p', 'v', 'o' }; - -#define UI_DutyColor Magenta -#define UI_FreqColor BrightRed -#define UI_VP2PColor DarkBrown -#define UI_VOffsetColor Green - -#define UI_BUTTON_FACE_UP White -#define UI_BUTTON_FACE_DN RGB(255,92,92) -#define UI_BUTTON_SHADOW RGB(128,0,0) -#define UI_BUTTON_FACE_DISABLED RGB(24,24,24) -#define UI_BUTTON_SHADOW_DISABLED RGB(32,0,0) - -const rect_t UI_PROD_RECT = {298,3, 479,40}; -#define UI_ProductNameColor UI_BUTTON_FACE_DN // RGB(192,192,192) +const char ParameterKeys[] = { 'd', 'f', 'p', 'v', 'o' }; -#define PI 3.1415 - -#define BTN_W 54 -#define BTN_H 35 -#define BTN_S 5 // space - -#define BTN_MODE_X 2 -#define BTN_MODE_Y 230 +const rect_t UI_PROD_RECT = {298,3, 479,40}; +const rect_t NavToSettings = { 4,200, 60,220 }; -#define BTN_KEYP_X 300 -#define BTN_KEYP_Y 70 - -const rect_t NavToSettings = { 4,200, 60,220 }; - - - -const rect_t UI_Buttons[] = { +// Mode Buttons +const rect_t ModeButtons[] = { { BTN_MODE_X+0*(BTN_W+BTN_S),BTN_MODE_Y, BTN_MODE_X+0*(BTN_W+BTN_S)+BTN_W,BTN_MODE_Y+BTN_H }, { BTN_MODE_X+1*(BTN_W+BTN_S),BTN_MODE_Y, BTN_MODE_X+1*(BTN_W+BTN_S)+BTN_W,BTN_MODE_Y+BTN_H }, { BTN_MODE_X+2*(BTN_W+BTN_S),BTN_MODE_Y, BTN_MODE_X+2*(BTN_W+BTN_S)+BTN_W,BTN_MODE_Y+BTN_H }, { BTN_MODE_X+3*(BTN_W+BTN_S),BTN_MODE_Y, BTN_MODE_X+3*(BTN_W+BTN_S)+BTN_W,BTN_MODE_Y+BTN_H }, { 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 }, }; -const int ButtonCount = sizeof(UI_Buttons)/sizeof(UI_Buttons[0]); -SignalGenDisplay::SG_Mode UI_ModeList[] = { - SignalGenDisplay::SG_SINE, - SignalGenDisplay::SG_SQUARE, - SignalGenDisplay::SG_TRIANGLE, - SignalGenDisplay::SG_SAWTOOTH, - SignalGenDisplay::SG_USER, +const int ModeCount = sizeof(ModeButtons)/sizeof(ModeButtons[0]); +SG_Mode UI_ModeList[] = { + SG_SINE, + SG_SQUARE, + SG_TRIANGLE, + SG_SAWTOOTH, + SG_USER, }; const char ModeKeys[] = { 'S','Q','T','W','U' }; +const char *ModeNames[] = { + "Sine", + "Square", + "Triangle", + "Sawtooth", + "User", +}; const rect_t UI_Keypad[] = { - {BTN_KEYP_X+0*(BTN_W+BTN_S),BTN_KEYP_Y+0*(BTN_H+BTN_S), BTN_KEYP_X+0*(BTN_W+BTN_S)+BTN_W,BTN_KEYP_Y+0*(BTN_H+BTN_S)+BTN_H }, - {BTN_KEYP_X+1*(BTN_W+BTN_S),BTN_KEYP_Y+0*(BTN_H+BTN_S), BTN_KEYP_X+1*(BTN_W+BTN_S)+BTN_W,BTN_KEYP_Y+0*(BTN_H+BTN_S)+BTN_H }, - {BTN_KEYP_X+2*(BTN_W+BTN_S),BTN_KEYP_Y+0*(BTN_H+BTN_S), BTN_KEYP_X+2*(BTN_W+BTN_S)+BTN_W,BTN_KEYP_Y+0*(BTN_H+BTN_S)+BTN_H }, + {BTN_KEYP_X+2*(BTN_W+BTN_S),BTN_KEYP_Y+0*(BTN_H+BTN_S), BTN_KEYP_X+2*(BTN_W+BTN_S)+BTN_W,BTN_KEYP_Y+0*(BTN_H+BTN_S)+BTN_H }, // backspace {BTN_KEYP_X+0*(BTN_W+BTN_S),BTN_KEYP_Y+1*(BTN_H+BTN_S), BTN_KEYP_X+0*(BTN_W+BTN_S)+BTN_W,BTN_KEYP_Y+1*(BTN_H+BTN_S)+BTN_H }, {BTN_KEYP_X+1*(BTN_W+BTN_S),BTN_KEYP_Y+1*(BTN_H+BTN_S), BTN_KEYP_X+1*(BTN_W+BTN_S)+BTN_W,BTN_KEYP_Y+1*(BTN_H+BTN_S)+BTN_H }, {BTN_KEYP_X+2*(BTN_W+BTN_S),BTN_KEYP_Y+1*(BTN_H+BTN_S), BTN_KEYP_X+2*(BTN_W+BTN_S)+BTN_W,BTN_KEYP_Y+1*(BTN_H+BTN_S)+BTN_H }, @@ -117,17 +119,26 @@ {BTN_KEYP_X+0*(BTN_W+BTN_S),BTN_KEYP_Y+4*(BTN_H+BTN_S), BTN_KEYP_X+0*(BTN_W+BTN_S)+BTN_W,BTN_KEYP_Y+4*(BTN_H+BTN_S)+BTN_H }, {BTN_KEYP_X+1*(BTN_W+BTN_S),BTN_KEYP_Y+4*(BTN_H+BTN_S), BTN_KEYP_X+1*(BTN_W+BTN_S)+BTN_W,BTN_KEYP_Y+4*(BTN_H+BTN_S)+BTN_H }, {BTN_KEYP_X+2*(BTN_W+BTN_S),BTN_KEYP_Y+4*(BTN_H+BTN_S), BTN_KEYP_X+2*(BTN_W+BTN_S)+BTN_W,BTN_KEYP_Y+4*(BTN_H+BTN_S)+BTN_H }, + {BTN_KEYP_X+0*(BTN_W+BTN_S),BTN_KEYP_Y+5*(BTN_H+BTN_S), BTN_KEYP_X+0*(BTN_W+BTN_S)+BTN_W,BTN_KEYP_Y+5*(BTN_H+BTN_S)+BTN_H }, + {BTN_KEYP_X+1*(BTN_W+BTN_S),BTN_KEYP_Y+5*(BTN_H+BTN_S), BTN_KEYP_X+1*(BTN_W+BTN_S)+BTN_W,BTN_KEYP_Y+5*(BTN_H+BTN_S)+BTN_H }, + {BTN_KEYP_X+2*(BTN_W+BTN_S),BTN_KEYP_Y+5*(BTN_H+BTN_S), BTN_KEYP_X+2*(BTN_W+BTN_S)+BTN_W,BTN_KEYP_Y+5*(BTN_H+BTN_S)+BTN_H }, }; const int KeypadCount = sizeof(UI_Keypad)/sizeof(UI_Keypad[0]); const char UI_KeyLabels[] = { + '\x1B', '7', '8', '9', '4', '5', '6', '1', '2', '3', '0', '.', '-', - '\x1F', '\x1E', '\xB6', + '\x19', '\x18', '\xB6', }; -const char KeyPadKeys[] = { '7', '8', '9', '4', '5', '6', '1', '2', '3', - '0', '.', '-', '<', '>', '\n' }; +const char KeyPadKeys[] = { + '\x08', + '7', '8', '9', + '4', '5', '6', + '1', '2', '3', + '0', '.', '-', + '<', '>', '\n' }; // ##### Settings ############################################################# @@ -136,9 +147,9 @@ // | Progam Name and version | // | Manufacturer name | // | | -// | | -// | | -// | | +// | \ | / | +// | = O = | +// | / | \ | // | +--------+ | // | | | | // | | | | @@ -162,6 +173,19 @@ const rect_t sungraph = { 450-20,100+0, 450+20,265+0 }; const rect_t inrgraph = { 450-18,100+2, 450+18,265-2 }; +#define PI 3.1415 // Handy value + + +SignalGenDisplay::SignalGenDisplay(RA8875 * _lcd, SignalGenDAC * _signal, + const char * _ProgName, const char * _Manuf, const char * _Ver, const char * _Build) : + lcd(_lcd), signal(_signal), ProgName(_ProgName), Manuf(_Manuf), Ver(_Ver), Build(_Build) { + needsInit = true; +} + + +SignalGenDisplay::~SignalGenDisplay() { +} + template <typename T> int sgn(T val) { return (T(0) < val) - (val < T(0)); @@ -183,10 +207,9 @@ timer.reset(); switch (vis) { case VS_MainScreen: -printf("touch [vis: %d] (%d,%d)\r\n", vis, point.x, point.y); // Mode Keys touch - for (int i=0; i<ButtonCount; i++) { - if (lcd->Intersect(UI_Buttons[i], point)) { + for (int i=0; i<ModeCount; i++) { + if (lcd->Intersect(ModeButtons[i], point)) { return ModeKeys[i]; } } @@ -205,9 +228,8 @@ } if (lcd->Intersect(NavToSettings, point)) { -printf("Nav\r\n"); vis = VS_Settings; - Init(); + Refresh(); while (lcd->TouchPanelReadable()) ; Thread::wait(100); @@ -215,22 +237,20 @@ break; case VS_Settings: Thread::wait(20); -printf("touch [VIS: %d\r\n", vis); if (lcd->Intersect(sungraph, point)) { float bl = (float)(sungraph.p2.y - point.y)/(sungraph.p2.y - sungraph.p1.y); lcd->Backlight(rangelimit(bl, 0.1, 1.0)); ShowBrightnessSetting(); } if (lcd->Intersect(NavToSettings, point)) { - // Save settings + // Save Backlight settings on screen change char buf[20]; - snprintf(buf, sizeof(buf), "%d", lcd->GetBacklight_u8()); ini.WriteString("Settings", "Backlight", buf); // Switch to main screen vis = VS_MainScreen; - Init(); + Refresh(); while (lcd->TouchPanelReadable()) ; Thread::wait(100); @@ -244,18 +264,36 @@ } -SignalGenDisplay::SignalGenDisplay(RA8875 * _lcd, SignalGenerator * _signal, - const char * _ProgName, const char * _Manuf, const char * _Ver, const char * _Build) : - lcd(_lcd), signal(_signal), ProgName(_ProgName), Manuf(_Manuf), Ver(_Ver), Build(_Build) { - vis = VS_MainScreen; -} - - -SignalGenDisplay::~SignalGenDisplay() { -} - - -void SignalGenDisplay::Init() { +void SignalGenDisplay::Refresh() { + if (needsInit) { + char buf[100]; + + needsInit = false; + vis = VS_MainScreen; // always start on main screen + + // Default the backlight + ini.ReadString("Settings", "Backlight", buf, sizeof(buf), "60"); + lcd->Backlight_u8(atoi(buf)); + + ini.ReadString("Signal", "Waveform", buf, sizeof(buf), "Sine"); + for (int i=0; i<ModeCount; i++) { + if (strcmp(ModeNames[i], buf) == 0) { + mode = (SG_Mode)i; + break; + } + } + ini.ReadString("Signal", "Duty Cycle", buf, sizeof(buf), "50"); + dutycycle = atof(buf); + + ini.ReadString("Signal", "Frequency", buf, sizeof(buf), "1000"); + frequency = atof(buf); + + ini.ReadString("Signal", "Voltage", buf, sizeof(buf), "3.0"); + voltage = atof(buf); + + ini.ReadString("Signal", "Offset", buf, sizeof(buf), "1.5"); + offset = atof(buf); + } switch (vis) { case VS_MainScreen: lcd->background(UI_BackColor); @@ -269,15 +307,9 @@ ShowProductInfo(); ClearScope(); - // Some defaults for testing - SetDutyCycle(30); - SetFrequency(1230.0); - SetVoltagePeakToPeak(3.0); - SetVoltageOffset(1.50); resetDataEntry(); - SelectWaveformMode(SignalGenDisplay::SG_SINE); - DrawKeypadEnabled(false); DrawNavGadget(); + DrawModeButtons(); break; case VS_Settings: @@ -288,11 +320,20 @@ lcd->foreground(UI_ProductNameColor); ShowProductInfo(); ShowBrightnessSetting(); - DrawNavGadget(); + DrawNavGadget(); + DrawModeButtons(); break; } } + +void SignalGenDisplay::DrawModeButtons(void) { + for (int i=0; i<ModeCount; i++) { + DrawButton(ModeButtons[i], (UI_ModeList[i] == mode) ? true : false, UI_ModeList[i], true); + } + UpdateScope(); +} + void SignalGenDisplay::DrawNavGadget(void) { lcd->fillrect(NavToSettings, Black); lcd->SetTextCursor(NavToSettings.p1.x+1, NavToSettings.p1.y+1); @@ -324,9 +365,29 @@ lcd->fillrect(inrgraph.p1.x,inrgraph.p2.y, inrgraph.p2.x, inrgraph.p2.y - bl * (inrgraph.p2.y - inrgraph.p1.y), White); } -SignalGenDisplay::SG_Changes SignalGenDisplay::Poll(char c) { - SG_Changes ret = SG_NONE; +void SignalGenDisplay::ShowMenu(void) { + if (Manuf) { + printf("\r\n%s v%s by %s build %s\r\n\r\n", ProgName, Ver, Manuf, Build); + } + printf(" Select: Signal:\r\n"); + printf(" S: Sine Wave d: Duty Cycle\r\n"); + printf(" Q: Square Wave f: Frequency\r\n"); + printf(" T: Triangle Wave p: Period\r\n"); + printf(" W: Sawtooth Wave v: Voltage\r\n"); + printf(" U: User Wave o: Offset\r\n"); + printf(" \r\n"); + printf(" 0-9 . - : Numeric entry\r\n"); + printf(" < > : Modify selected signal\r\n"); + printf(" <bs>: Backspace entry\r\n"); + printf(" ?: This help <cr>: Save number\r\n"); + printf(" #: Dump RA8875 <esc>: Exit number entry\r\n"); + //printf(" 4: Reverse sawtoothSignal\r\n"); +} + +SignalGenDisplay::OM_Changes SignalGenDisplay::Poll(char c) { + OM_Changes ret = OM_NONE; + SaveSettings(); if (!c) { c = GetTouchEvent(); } @@ -343,31 +404,45 @@ /// - <esc> abandon numeric entry /// - <nul> do nothing, just poll switch (c) { + case '#': + lcd->DumpRegisters(); + break; case '?': ShowMenu(); break; case 'S': - SelectWaveformMode(SG_SINE); - signal->SetSignalFrequency(SignalGenerator::SinusSignal, frequency); + if (mode != SG_SINE) + SaveSettings(OM_MODE); + SetWaveformMode(SG_SINE); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); //ret = SG_SINE; break; case 'Q': - SelectWaveformMode(SG_SQUARE); - signal->SetSignalFrequency(SignalGenerator::SquareSignal, frequency); + if (mode != SG_SQUARE) + SaveSettings(OM_MODE); + SetWaveformMode(SG_SQUARE); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); //ret = SG_SQUARE; break; case 'T': - SelectWaveformMode(SG_TRIANGLE); - signal->SetSignalFrequency(SignalGenerator::TriangleSignal, frequency); + if (mode != SG_TRIANGLE) + SaveSettings(OM_MODE); + SetWaveformMode(SG_TRIANGLE); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); //ret = SG_TRIANGLE; break; case 'W': - SelectWaveformMode(SG_SAWTOOTH); - signal->SetSignalFrequency(SignalGenerator::SawtoothSignal, frequency); + if (mode != SG_SAWTOOTH) + SaveSettings(OM_MODE); + SetWaveformMode(SG_SAWTOOTH); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); //ret = SG_SAWTOOTH; break; case 'U': - SelectWaveformMode(SG_USER); + if (mode != SG_USER) + SaveSettings(OM_MODE); + SetWaveformMode(SG_USER); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); //ret = SG_USER; break; case '0': @@ -397,12 +472,13 @@ textBuffer[textLen] = '\0'; updateTextWindow(); } + if (textLen == 0) + clearTextWindow(); } break; case '\x1B': textBuffer[0] = '\0'; textLen = 0; - EntryMd = SG_NONE; resetDataEntry(); break; case '\r': @@ -410,45 +486,64 @@ if (EntryMd) { if (strlen(textBuffer)) { switch (EntryMd) { - case SG_DUTY: + case OM_DUTY: SetDutyCycle(atof(textBuffer)); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); + SaveSettings(OM_DUTY); break; - case SG_FREQ: + case OM_FREQ: SetFrequency(atof(textBuffer)); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); + SaveSettings(OM_FREQ); break; - case SG_PERI: + case OM_PERI: SetPeriod(atof(textBuffer)); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); + SaveSettings(OM_FREQ); break; - case SG_VOLT: + case OM_VOLT: SetVoltagePeakToPeak(atof(textBuffer)); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); + SaveSettings(OM_VOLT); break; - case SG_OFFS: + case OM_OFFS: SetVoltageOffset(atof(textBuffer)); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); + SaveSettings(OM_OFFS); break; default: break; } } - EntryMd = SG_NONE; - resetDataEntry(); + resetDataEntry(OM_NONE, true); } break; case '>': switch (EntryMd) { - case SG_DUTY: + case OM_DUTY: SetDutyCycle(dutycycle + 1.0); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); + SaveSettings(OM_DUTY); break; - case SG_FREQ: + case OM_FREQ: SetFrequency(frequency + 1.0); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); + SaveSettings(OM_FREQ); break; - case SG_PERI: - SetPeriod(1/frequency + 0.001); + case OM_PERI: + SetPeriod(1/frequency + 0.000001); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); + SaveSettings(OM_FREQ); break; - case SG_VOLT: + case OM_VOLT: SetVoltagePeakToPeak(voltage + 0.1); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); + SaveSettings(OM_VOLT); break; - case SG_OFFS: - SetVoltageOffset(offset + 0.01); + case OM_OFFS: + SetVoltageOffset(offset + 0.1); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); + SaveSettings(OM_OFFS); break; default: break; @@ -456,78 +551,83 @@ break; case '<': switch (EntryMd) { - case SG_DUTY: + case OM_DUTY: SetDutyCycle(dutycycle - 1.0); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); + SaveSettings(OM_DUTY); break; - case SG_FREQ: + case OM_FREQ: SetFrequency(frequency - 1.0); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); + SaveSettings(OM_FREQ); break; - case SG_PERI: - SetPeriod(1/frequency - 0.001); + case OM_PERI: + SetPeriod(1/frequency - 0.000001); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); + SaveSettings(OM_FREQ); break; - case SG_VOLT: + case OM_VOLT: SetVoltagePeakToPeak(voltage - 0.1); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); + SaveSettings(OM_VOLT); break; - case SG_OFFS: - SetVoltageOffset(offset - 0.01); + case OM_OFFS: + SetVoltageOffset(offset - 0.1); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); + SaveSettings(OM_OFFS); break; default: break; } break; case 'd': - if (EntryMd != SG_DUTY) { - resetDataEntry(); - EntryMd = SG_DUTY; - DrawKeypadEnabled(true); + if (EntryMd != OM_DUTY) { + SaveSettings(EntryMd); + resetDataEntry(OM_DUTY, true); updateDutyCycle(); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); } else { - EntryMd = SG_NONE; - resetDataEntry(); + resetDataEntry(OM_NONE, true); } break; case 'f': - if (EntryMd != SG_FREQ) { - resetDataEntry(); - EntryMd = SG_FREQ; - DrawKeypadEnabled(true); + if (EntryMd != OM_FREQ) { + SaveSettings(EntryMd); + resetDataEntry(OM_FREQ, true); updateFrequency(); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); } else { - EntryMd = SG_NONE; - resetDataEntry(); + resetDataEntry(OM_NONE, true); } break; case 'p': - if (EntryMd != SG_PERI) { - resetDataEntry(); - EntryMd = SG_PERI; - DrawKeypadEnabled(true); + if (EntryMd != OM_PERI) { + SaveSettings(EntryMd); + resetDataEntry(OM_PERI, true); updatePeriod(); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); } else { - EntryMd = SG_NONE; - resetDataEntry(); + resetDataEntry(OM_NONE, true); } break; case 'v': - if (EntryMd != SG_VOLT) { - resetDataEntry(); - EntryMd = SG_VOLT; - DrawKeypadEnabled(true); + if (EntryMd != OM_VOLT) { + SaveSettings(EntryMd); + resetDataEntry(OM_VOLT, true); updateVoltage(); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); } else { - EntryMd = SG_NONE; - resetDataEntry(); + resetDataEntry(OM_NONE, true); } break; case 'o': - if (EntryMd != SG_OFFS) { - resetDataEntry(); - EntryMd = SG_OFFS; - DrawKeypadEnabled(true); + if (EntryMd != OM_OFFS) { + SaveSettings(EntryMd); + resetDataEntry(OM_OFFS, true); updateOffset(); + signal->PrepareWaveform(mode, frequency, dutycycle, voltage, offset); } else { - EntryMd = SG_NONE; - resetDataEntry(); + resetDataEntry(OM_NONE, true); } break; default: @@ -536,13 +636,10 @@ return ret; } -bool SignalGenDisplay::SelectWaveformMode(SG_Mode _mode) { +bool SignalGenDisplay::SetWaveformMode(SG_Mode _mode, bool force) { if (/* _mode >= SG_SINE && */ _mode <= SG_USER) { - mode= _mode; - for (int i=0; i<ButtonCount; i++) { - DrawButton(UI_Buttons[i], (UI_ModeList[i] == mode) ? true : false, UI_ModeList[i], true); - } - UpdateScope(); + mode = _mode; + DrawModeButtons(); return true; } else { return false; @@ -561,16 +658,13 @@ } bool SignalGenDisplay::SetFrequency(float _frequency) { - printf("-> SetFrequency(%f)\r\n", _frequency); if (_frequency >= 1.0 && _frequency <= 1.0E6) { frequency = _frequency; updateFrequency(); updatePeriod(); UpdateScope(); - printf(" end SetFrequency\r\n"); return true; } else { - printf(" end SetFrequency - out of range\r\n"); return false; } } @@ -614,36 +708,40 @@ // ######################## Private Methods past here ####################### void SignalGenDisplay::UpdateScope(void) { - printf("-> UpdateScope()\r\n"); ClearScope(); - rect_t r; + rect_t r = UI_WAVE_RECT; - r.p1.x = UI_SCOPE_RECT.p1.x + SC_LEFT_MARGIN; - r.p1.y = UI_SCOPE_RECT.p1.y + SC_TOP_MARGIN; - r.p2.x = UI_SCOPE_RECT.p2.x - SC_RIGHT_MARGIN; - r.p2.y = UI_SCOPE_RECT.p2.y - SC_BOT_MARGIN; - lcd->rect(r, WaveOutlineColor); + float vPeakPos, vPeakNeg; + dim_t waveHeight = (UI_WAVE_RECT.p2.y - UI_WAVE_RECT.p1.y); + vPeakPos = rangelimit(offset + voltage/2, SG_MIN_V, SG_MAX_V); + vPeakNeg = rangelimit(offset - voltage/2, SG_MIN_V, SG_MAX_V); + loc_t markerPos_y = UI_WAVE_RECT.p2.y - vPeakPos/(SG_MAX_V-SG_MIN_V) * waveHeight; + loc_t markerNeg_y = UI_WAVE_RECT.p2.y - vPeakNeg/(SG_MAX_V-SG_MIN_V) * waveHeight; + loc_t df = rangelimit(offset, SG_MIN_V, SG_MAX_V) / SG_MAX_V * (r.p2.y - r.p1.y); + loc_t y; + + // Draw the Waveform rectangle + lcd->rect(UI_WAVE_RECT, WaveOutlineColor); // Draw the Peak to Peak markers - lcd->line(r.p1.x,r.p1.y, r.p2.x+3*SC_RIGHT_MARGIN/4,r.p1.y, UI_VP2PColor); - lcd->line(r.p1.x,r.p2.y, r.p2.x+3*SC_RIGHT_MARGIN/4,r.p2.y, UI_VP2PColor); - lcd->line(r.p2.x+3*SC_RIGHT_MARGIN/4-3,r.p1.y, r.p2.x+3*SC_RIGHT_MARGIN/4-3,r.p2.y, UI_VP2PColor); - lcd->filltriangle( - r.p2.x+3*SC_RIGHT_MARGIN/4-3,r.p1.y, - r.p2.x+3*SC_RIGHT_MARGIN/4-3+2,r.p1.y+3, - r.p2.x+3*SC_RIGHT_MARGIN/4-3-2,r.p1.y+3, + lcd->line(UI_WAVE_RECT.p1.x-3,markerPos_y, UI_WAVE_RECT.p2.x+3*SC_RIGHT_MARGIN/4,markerPos_y, UI_VP2PColor); + lcd->line(UI_WAVE_RECT.p1.x-3,markerNeg_y, UI_WAVE_RECT.p2.x+3*SC_RIGHT_MARGIN/4,markerNeg_y, UI_VP2PColor); + lcd->line(r.p2.x+3*SC_RIGHT_MARGIN/4-3,markerPos_y, r.p2.x+3*SC_RIGHT_MARGIN/4-3,markerNeg_y, UI_VP2PColor); // vert + lcd->filltriangle( // top arrowhead + r.p2.x+3*SC_RIGHT_MARGIN/4-3, markerPos_y, + r.p2.x+3*SC_RIGHT_MARGIN/4-3+2,markerPos_y+3, + r.p2.x+3*SC_RIGHT_MARGIN/4-3-2,markerPos_y+3, UI_VP2PColor); - lcd->filltriangle( - r.p2.x+3*SC_RIGHT_MARGIN/4-3,r.p2.y, - r.p2.x+3*SC_RIGHT_MARGIN/4-3+2,r.p2.y-3, - r.p2.x+3*SC_RIGHT_MARGIN/4-3-2,r.p2.y-3, + lcd->filltriangle( // bottom arrowhead + r.p2.x+3*SC_RIGHT_MARGIN/4-3, markerNeg_y, + r.p2.x+3*SC_RIGHT_MARGIN/4-3+2,markerNeg_y-3, + r.p2.x+3*SC_RIGHT_MARGIN/4-3-2,markerNeg_y-3, UI_VP2PColor); // Draw the offset voltage markers - loc_t y = (r.p1.y + r.p2.y)/2; + y = r.p2.y - df; dim_t w = (r.p2.x + SC_RIGHT_MARGIN/3 - r.p1.x) / 35; - dim_t h = (r.p2.y - r.p1.y); - for (int i=0; i<=35+1; i++) { + for (int i=0; i<=35+1; i++) { // dashed line if ((i & 1) == 0) { lcd->line(r.p1.x + i * w,y, r.p1.x + (i+1) * w, y, UI_VOffsetColor); } @@ -654,24 +752,21 @@ break; case -1: case 1: - lcd->line(r.p2.x+SC_RIGHT_MARGIN/3-3,y+sgn(offset)*(h/2+7), r.p2.x+SC_RIGHT_MARGIN/3-3,y, UI_VOffsetColor); + lcd->line(r.p2.x+SC_RIGHT_MARGIN/3-3,r.p2.y, r.p2.x+SC_RIGHT_MARGIN/3-3,y, UI_VOffsetColor); // vert lcd->filltriangle( r.p2.x+SC_RIGHT_MARGIN/3-3,y, r.p2.x+SC_RIGHT_MARGIN/3-3+2,y+sgn(offset)*3, r.p2.x+SC_RIGHT_MARGIN/3-3-2,y+sgn(offset)*3, UI_VOffsetColor); - if (abs(offset) > voltage/2) - lcd->line(r.p1.x,y+sgn(offset)*(h/2+7), r.p2.x+SC_RIGHT_MARGIN/3,y+sgn(offset)*(h/2+7), UI_VOffsetColor); - else - lcd->line(r.p1.x,y+(offset/voltage)*h, r.p2.x+SC_RIGHT_MARGIN/3,y+(offset/voltage)*h, UI_VOffsetColor); + lcd->line(r.p2.x,r.p2.y, r.p2.x+SC_RIGHT_MARGIN/3,r.p2.y, UI_VOffsetColor); // horz break; } // Draw the Frequency marker w = r.p2.x - r.p1.x; dim_t dc = dutycycle/100.0 * 1*w/2; - lcd->line(r.p1.x,r.p1.y, r.p1.x,r.p2.y+3*SC_BOT_MARGIN/4, UI_FreqColor); - lcd->line(r.p1.x+1*w/2,r.p1.y, r.p1.x+1*w/2,r.p2.y+3*SC_BOT_MARGIN/4, UI_FreqColor); + lcd->line(r.p1.x,r.p1.y-3, r.p1.x,r.p2.y+3*SC_BOT_MARGIN/4, UI_FreqColor); + lcd->line(r.p1.x+1*w/2,r.p1.y-3, r.p1.x+1*w/2,r.p2.y+3*SC_BOT_MARGIN/4, UI_FreqColor); lcd->line(r.p1.x,r.p2.y+3*SC_BOT_MARGIN/4-3, r.p1.x+1*w/2,r.p2.y+3*SC_BOT_MARGIN/4-3, UI_FreqColor); lcd->filltriangle( r.p1.x+0,r.p2.y+3*SC_BOT_MARGIN/4-3, @@ -685,8 +780,8 @@ UI_FreqColor); // Draw the Duty Cycle markers - lcd->line(r.p1.x,r.p1.y, r.p1.x,r.p2.y+2*SC_BOT_MARGIN/4, UI_DutyColor); - lcd->line(r.p1.x + dc,r.p1.y, r.p1.x + dc,r.p2.y+2*SC_BOT_MARGIN/4, UI_DutyColor); + lcd->line(r.p1.x,r.p1.y-3, r.p1.x,r.p2.y+2*SC_BOT_MARGIN/4, UI_DutyColor); + lcd->line(r.p1.x + dc,r.p1.y-3, r.p1.x + dc,r.p2.y+2*SC_BOT_MARGIN/4, UI_DutyColor); point_t p; p.x = r.p1.x; p.y = r.p2.y+2*SC_BOT_MARGIN/4-3; @@ -703,62 +798,82 @@ p.x-3,p.y+2, UI_DutyColor); DrawWaveform(r, mode, White); - printf(" end UpdateScope()\r\n"); } + // ++ +----+ + + // . . | | / \ /| // . . | | | / \ / / | // . | | \ / / | // ++ +----+ + + + // -void SignalGenDisplay::DrawWaveform(rect_t r, SG_Mode mode, color_t color, float dutycycleOverride) { +void SignalGenDisplay::DrawWaveform(rect_t r, SG_Mode 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; - dim_t dc = ((dutycycleOverride >= 5.0) ? dutycycleOverride : dutycycle)/100.0 * 1*w/2; + dim_t h = r.p2.y - r.p1.y; + dim_t privDutyCycleX; dim_t a = (r.p2.y - r.p1.y)/2; + float privVoltage = voltage; + float privOffset = offset; + float privDutyCycle = dutycycle; + float vRange = SG_MAX_V - SG_MIN_V; float v; - + + if (drawPure) { + privVoltage = vRange; + privOffset = vRange/2; + privDutyCycle = 50; + } + privDutyCycleX = privDutyCycle/100.0 * 1*w/2; switch (mode) { case SG_SINE: for (int cycle=0; cycle<2; cycle++) { - for (x=0; x<=dc; x++) { - v = offset + voltage/2 * sin(x * 1 * PI / dc); + for (x=0; x<=privDutyCycleX; x++) { + v = privOffset + privVoltage/2 * sin(x * 1 * PI / privDutyCycleX); v = rangelimit(v, SG_MIN_V, SG_MAX_V); - y = r.p2.y - 2 * a * v / SG_AOUT_FS; + y = r.p2.y - 2 * a * v / vRange; lcd->pixel(r.p1.x + cycle * w/2 + x, y, color); } - for (x=0; x<=(w/2-dc); x++) { - v = offset - voltage/2 * sin(x * 1 * PI / (w/2-dc)); + for (x=0; x<=(w/2-privDutyCycleX); x++) { + v = privOffset - privVoltage/2 * sin(x * 1 * PI / (w/2-privDutyCycleX)); v = rangelimit(v, SG_MIN_V, SG_MAX_V); - y = r.p2.y - 2 * a * v / SG_AOUT_FS; - lcd->pixel(r.p1.x + cycle * w/2 + dc + x, y, color); + y = r.p2.y - 2 * a * v / vRange; + lcd->pixel(r.p1.x + cycle * w/2 + privDutyCycleX + x, y, color); } } break; case SG_SQUARE: for (int cycle=0; cycle<2; cycle++) { - lcd->line(r.p1.x+cycle*w/2+0*w/8, y0, r.p1.x+cycle*w/2+0*w/8, y0-a, color); // rise - lcd->line(r.p1.x+cycle*w/2+0*w/8, y0-a, r.p1.x+cycle*w/2+dc, y0-a, color); // horz - lcd->line(r.p1.x+cycle*w/2+dc, y0-a, r.p1.x+cycle*w/2+dc, y0+a, color); // fall - lcd->line(r.p1.x+cycle*w/2+dc, y0+a, r.p1.x+cycle*w/2+4*w/8, y0+a, color); // horz - lcd->line(r.p1.x+cycle*w/2+4*w/8, y0+a, r.p1.x+cycle*w/2+4*w/8, y0, color); // rise + loc_t mid = r.p2.y - rangelimit(privOffset, SG_MIN_V, SG_MAX_V) / vRange * h; + loc_t upp = r.p2.y - rangelimit(privOffset + privVoltage/2, SG_MIN_V, SG_MAX_V) / vRange * h; + loc_t low = r.p2.y - rangelimit(privOffset - privVoltage/2, SG_MIN_V, SG_MAX_V) / vRange * h; + lcd->line(r.p1.x+cycle*w/2+0*w/8, mid, r.p1.x+cycle*w/2+0*w/8, upp, color); // rise + lcd->line(r.p1.x+cycle*w/2+0*w/8, upp, r.p1.x+cycle*w/2+privDutyCycleX, upp, color); // horz + lcd->line(r.p1.x+cycle*w/2+privDutyCycleX, upp, r.p1.x+cycle*w/2+privDutyCycleX, low, color); // fall + lcd->line(r.p1.x+cycle*w/2+privDutyCycleX, low, r.p1.x+cycle*w/2+4*w/8, low, color); // horz + lcd->line(r.p1.x+cycle*w/2+4*w/8, low, r.p1.x+cycle*w/2+4*w/8, mid, color); // rise } break; case SG_TRIANGLE: for (int cycle=0; cycle<2; cycle++) { - lcd->line(r.p1.x+cycle*w/2+0*w/8, y0+0, r.p1.x+cycle*w/2+dc/2, y0-a, color); // rise 2 - lcd->line(r.p1.x+cycle*w/2+dc/2, y0-a, r.p1.x+cycle*w/2+dc/1, y0, color); // fall 1 - lcd->line(r.p1.x+cycle*w/2+dc/1, y0, r.p1.x+cycle*w/2+(w/2+dc)/2, y0+a, color); // fall 2 - lcd->line(r.p1.x+cycle*w/2+(w/2+dc)/2, y0+a, r.p1.x+cycle*w/2+4*w/8, y0, color); // rise 1 + loc_t mid = r.p2.y - rangelimit(privOffset, SG_MIN_V, SG_MAX_V) / vRange * h; + loc_t upp = r.p2.y - rangelimit(privOffset + privVoltage/2, SG_MIN_V, SG_MAX_V) / vRange * h; + loc_t low = r.p2.y - rangelimit(privOffset - privVoltage/2, SG_MIN_V, SG_MAX_V) / vRange * h; + lcd->line(r.p1.x+cycle*w/2+0*w/8, mid, r.p1.x+cycle*w/2+privDutyCycleX/2, upp, color); // rise 2 + lcd->line(r.p1.x+cycle*w/2+privDutyCycleX/2, upp, r.p1.x+cycle*w/2+privDutyCycleX/1, mid, color); // fall 1 + lcd->line(r.p1.x+cycle*w/2+privDutyCycleX/1, mid, r.p1.x+cycle*w/2+(w/2+privDutyCycleX)/2, low, color); // fall 2 + lcd->line(r.p1.x+cycle*w/2+(w/2+privDutyCycleX)/2, low, r.p1.x+cycle*w/2+4*w/8, mid, color); // rise 1 } break; case SG_SAWTOOTH: for (int cycle=0; cycle<2; cycle++) { - lcd->line(r.p1.x+cycle*w/2+0*w/8+0, y0+a, r.p1.x+cycle*w/2+dc, y0, color); - lcd->line(r.p1.x+cycle*w/2+dc, y0, r.p1.x+cycle*w/2+4*w/8-1, y0-a, color); - lcd->line(r.p1.x+cycle*w/2+4*w/8-1, y0-a, r.p1.x+cycle*w/2+4*w/8, y0+a, color); + loc_t mid = r.p2.y - rangelimit(privOffset, SG_MIN_V, SG_MAX_V) / vRange * h; + loc_t upp = r.p2.y - rangelimit(privOffset + privVoltage/2, SG_MIN_V, SG_MAX_V) / vRange * h; + loc_t low = r.p2.y - rangelimit(privOffset - privVoltage/2, SG_MIN_V, SG_MAX_V) / vRange * h; + lcd->line(r.p1.x+cycle*w/2+0*w/8+0, low, r.p1.x+cycle*w/2+privDutyCycleX, mid, color); + lcd->line(r.p1.x+cycle*w/2+privDutyCycleX, mid, r.p1.x+cycle*w/2+4*w/8-1, upp, color); + lcd->line(r.p1.x+cycle*w/2+4*w/8-1, upp, r.p1.x+cycle*w/2+4*w/8, low, color); } break; case SG_USER: @@ -781,7 +896,7 @@ rect_t r = Parameters[0]; // UI_DUTY_CYCLE_RECT; color_t fcolor, bcolor; - if (EntryMd != SG_DUTY) { + if (EntryMd != OM_DUTY) { fcolor = UI_DutyColor; bcolor = UI_ScopeBackColor; } else { @@ -799,7 +914,7 @@ rect_t r = Parameters[1]; // UI_FREQ_RECT; color_t fcolor, bcolor; - if (EntryMd != SG_FREQ) { + if (EntryMd != OM_FREQ) { fcolor = UI_FreqColor; bcolor = UI_ScopeBackColor; } else { @@ -810,7 +925,6 @@ lcd->foreground(fcolor); lcd->background(bcolor); lcd->SetTextCursor(r.p1.x+1, r.p1.y+1); - printf("EntryMode: %d, bg: %08X, fg: %08X\r\n", EntryMd, bcolor, fcolor); if (frequency >= 1000.0) lcd->printf("%8.3f kHz", frequency/1000); else @@ -822,7 +936,7 @@ rect_t r = Parameters[2]; // UI_PERIOD_RECT; color_t fcolor, bcolor; - if (EntryMd != SG_PERI) { + if (EntryMd != OM_PERI) { fcolor = UI_FreqColor; bcolor = UI_ScopeBackColor; } else { @@ -843,7 +957,7 @@ rect_t r = Parameters[3]; // UI_VP2P_RECT; color_t fcolor, bcolor; - if (EntryMd != SG_VOLT) { + if (EntryMd != OM_VOLT) { fcolor = UI_VP2PColor; bcolor = UI_ScopeBackColor; } else { @@ -861,7 +975,7 @@ rect_t r = Parameters[4]; // UI_VOFFSET_RECT; color_t fcolor, bcolor; - if (EntryMd != SG_OFFS) { + if (EntryMd != OM_OFFS) { fcolor = UI_VOffsetColor; bcolor = UI_ScopeBackColor; } else { @@ -922,7 +1036,7 @@ case SG_TRIANGLE: case SG_SAWTOOTH: case SG_USER: - DrawWaveform(wave, mode, Black, 50.0); + DrawWaveform(wave, mode, Black, true); break; case SG_KEYPAD: lcd->foreground(Black); @@ -943,6 +1057,12 @@ lcd->window(); } +void SignalGenDisplay::clearTextWindow(void) { + lcd->fillrect(UI_DATA_ENTRY, UI_BackColor); + textBuffer[0] = '\0'; + textLen = 0; +} + float SignalGenDisplay::rangelimit(float value, float min, float max) { if (value < min) return min; @@ -952,60 +1072,106 @@ return value; } +void SignalGenDisplay::SaveSettings(OM_Changes reportMode) { + char buf[20]; -void SignalGenDisplay::ShowMenu(void) { - if (Manuf) { - printf("\r\n%s v%s by %s build %s\r\n", ProgName, Ver, Manuf, Build); + if (reportMode != OM_NONE) { + Changes |= reportMode; + printf("SaveSettings - reset timer [%02X]\r\n", Changes); + timerSave.reset(); + timerSave.start(); + } else if (timerSave.read() > SAVE_AFTER_IDLE_S) { + timerSave.stop(); + timerSave.reset(); + printf("SaveSettings - timeout [%02X]\r\n", Changes); + if (Changes & OM_MODE) { + Changes &= ~ OM_MODE; + ini.WriteString("Signal", "Waveform", ModeNames[mode]); + } + if (Changes & OM_FREQ) { + Changes &= ~ OM_FREQ; + snprintf(buf, sizeof(buf),"%5.3f", frequency); + printf(" Signal:Frequency=%s\r\n", buf); + ini.WriteString("Signal", "Frequency", buf); + } + if (Changes & OM_PERI) { + Changes &= ~ OM_PERI; + snprintf(buf, sizeof(buf),"%5.3f", frequency); + printf(" Signal:Frequency=%s\r\n", buf); + ini.WriteString("Signal", "Frequency", buf); + } + if (Changes & OM_DUTY) { + Changes &= ~ OM_DUTY; + snprintf(buf, sizeof(buf),"%1.0f", dutycycle); + printf(" Signal:Duty Cycle=%s\r\n", buf); + ini.WriteString("Signal", "Duty Cycle", buf); + } + if (Changes & OM_VOLT) { + Changes &= ~ OM_VOLT; + snprintf(buf, sizeof(buf),"%3.2f", voltage); + printf(" Signal:Voltage=%s\r\n", buf); + ini.WriteString("Signal", "Voltage", buf); + } + if (Changes & OM_OFFS) { + Changes &= ~ OM_OFFS; + snprintf(buf, sizeof(buf),"%3.2f", offset); + printf(" Signal:Offset=%s\r\n", buf); + ini.WriteString("Signal", "Offset", buf); + } } - printf(" Select: Signal:\r\n"); - printf(" S: Sine Wave d: Duty Cycle\r\n"); - printf(" Q: Square Wave f: Frequency\r\n"); - printf(" T: Triangle Wave p: Period\r\n"); - printf(" W: Sawtooth Wave v: Voltage\r\n"); - printf(" U: User Wave o: Offset\r\n"); - printf(" \r\n"); - printf(" 0-9 . - : Numeric entry\r\n"); - printf(" < > : Modify selected signal\r\n"); - printf(" <bs>: Backspace entry\r\n"); - printf(" <cr>: Save number\r\n"); - printf(" <esc>: Exit number entry\r\n"); - //printf(" 4: Reverse sawtoothSignal\r\n"); } +void SignalGenDisplay::resetDataEntry(OM_Changes nextMode, bool save) { + OM_Changes last = EntryMd; -void SignalGenDisplay::resetDataEntry(void) { - SG_Changes last = EntryMd; - printf("-> resetDataEntry()\r\n"); - EntryMd = SG_NONE; + printf("-> resetDataEntry(next: %d) curr:%d, save:%d\r\n", nextMode, last, save); + EntryMd = nextMode; + if (last != OM_NONE) + signal->PrepareWaveform(SG_SAWTOOTH, frequency, dutycycle, voltage, offset); switch (last) { - case SG_NONE: + case OM_NONE: updateDutyCycle(); updateFrequency(); updatePeriod(); updateVoltage(); updateOffset(); - lcd->fillrect(UI_DATA_ENTRY, UI_BackColor); - textBuffer[0] = '\0'; - textLen = 0; break; - case SG_DUTY: + case OM_DUTY: updateDutyCycle(); + if (save) { + SaveSettings(OM_DUTY); + } break; - case SG_FREQ: + case OM_FREQ: updateFrequency(); + if (save) { + SaveSettings(OM_FREQ); + } break; - case SG_PERI: + case OM_PERI: updatePeriod(); + if (save) { + SaveSettings(OM_FREQ); + } break; - case SG_VOLT: + case OM_VOLT: updateVoltage(); + if (save) { + SaveSettings(OM_VOLT); + } break; - case SG_OFFS: + case OM_OFFS: updateOffset(); + if (save) { + SaveSettings(OM_OFFS); + } break; default: break; } - DrawKeypadEnabled(false); - printf(" end resetDataEntry()\r\n"); + DrawKeypadEnabled(EntryMd != OM_NONE); + if (EntryMd == OM_NONE) { + clearTextWindow(); + } + printf("<- end resetDataEntry()\r\n"); } \ No newline at end of file