Signal Generator
Dependencies: IniManager RA8875 Watchdog mbed-rtos mbed
Fork of speaker_demo_Analog by
Diff: SignalGenDisplay.cpp
- Revision:
- 3:d22f3e52d06a
- Parent:
- 2:8f71b71fce1b
- Child:
- 4:10281ddb673d
--- a/SignalGenDisplay.cpp Sun Jan 15 03:11:22 2017 +0000 +++ b/SignalGenDisplay.cpp Mon Jan 16 04:33:06 2017 +0000 @@ -5,8 +5,8 @@ #include "SignalGenDisplay.h" #include "rtos.h" #include "IniManager.h" +#include "BPG_Arial08x08.h" -extern INI ini; // ##### Main Page ############################################################# // @@ -14,14 +14,14 @@ // | +--- Scope Area ---------------------------+ Progam Name and version | // | | | Manufacturer name | // | | +---- Wave Outline - - | | +// | | | | [Start/Stop ] [ ] | // | | | | [Text Entry Box] [ Back ] | -// | | | | | -// | | | +------------------------+ | +// | | | +-- Keypad Area ---------+ | // | | | | | | // | | | | | | | // | | | | | | | // | | ---+ | | | | -// | | | | Keypad Area | | +// | | | | | | // | +------------------------------------------+ | | | // | | | | // | [duty cycle] [frequency] [amplitude] | | | @@ -48,15 +48,10 @@ #define UI_BUTTON_SHADOW_DISABLED RGB(32,0,0) #define UI_ProductNameColor UI_BUTTON_FACE_DN -// Rectangular Zones -const rect_t UI_DATA_ENTRY = {300,53, 410,73}; -const rect_t UI_SCOPE_RECT = {4,5, 290,160}; #define SC_LEFT_MARGIN 10 // Scope left margin -#define SC_TOP_MARGIN 20 +#define SC_TOP_MARGIN 10 #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_BOT_MARGIN 20 #define BTN_W 54 // Button width #define BTN_H 32 // Button height #define BTN_S 5 // Button white-space @@ -67,6 +62,15 @@ #define BTN_KEYP_X 300 // Keypad left edge #define BTN_KEYP_Y 53 // Keypad top edge +// Rectangular Zones +const rect_t UI_START_STOP = {BTN_KEYP_X,BTN_KEYP_Y, BTN_KEYP_X + 2 * BTN_W + BTN_S,BTN_KEYP_Y+BTN_H}; +const char * UI_StartLabels[3] = { "Start", "Stop", "Pulse" }; +const char StartStopKeys[] = { 'G', 'O', 'P' }; +const rect_t UI_DATA_ENTRY = {BTN_KEYP_X,BTN_KEYP_Y, BTN_KEYP_X + 2 * BTN_W + BTN_S,BTN_KEYP_Y+BTN_H}; +const rect_t UI_SCOPE_RECT = {4,5, 290,160}; + +const rect_t UI_WAVE_RECT = {4+SC_LEFT_MARGIN,5+SC_TOP_MARGIN, 290-SC_RIGHT_MARGIN,160-SC_BOT_MARGIN}; + const rect_t Parameters[] = { {4,170, 60,190}, // 'd'uty cycle {90,170, 186,190}, // 'f'requency @@ -77,7 +81,7 @@ const int ParameterCount = sizeof(Parameters)/sizeof(Parameters[0]); const char ParameterKeys[] = { 'd', 'f', 'p', 'v', 'o' }; -const rect_t UI_PROD_RECT = {298,3, 479,40}; +const rect_t UI_PROD_RECT = { 298,3, 479,51 }; const rect_t NavToSettings = { 4,200, 60,220 }; // Mode Buttons @@ -146,12 +150,12 @@ // +---------------------------------------------------------------------------+ // | Progam Name and version | // | Manufacturer name | -// | | +// | Build Date | +// | Signal Generator Mode | // | \ | / | -// | = O = | +// | ( * ) Continuous = O = | // | / | \ | -// | +--------+ | -// | | | | +// | ( ) One-Shot +--------+ | // | | | | // | | | | // | | | | @@ -165,20 +169,48 @@ // | +--------+ | // +---------------------------------------------------------------------------+ -const point_t suncenter = { 450,65 }; +const point_t suncenter = { 450,85 }; const rect_t sunray[] = { - { 450-2,65-25, 450+2,65+25 }, - { 450-25,65-2, 450+25,65+2 } + { 450-2, 85-25, 450+2, 85+25 }, + { 450-25,85-2, 450+25,85+2 } }; -const rect_t sungraph = { 450-20,100+0, 450+20,265+0 }; -const rect_t inrgraph = { 450-18,100+2, 450+18,265-2 }; +const rect_t sungraph = { 450-18,120+0, 450+18,265+0 }; +const rect_t inrgraph = { 450-16,120+2, 450+16,265-2 }; + +const rect_t SignalMode = + { 20,50, 20+140,70 }; +const char * SignalModeLabel = "Signal Mode"; + +const rect_t radio_Cycles[] = { + { 40, 80, 40+120,100 }, + { 40,110, 40+120,130 } +}; +const int radio_CyclesCount = sizeof(radio_Cycles)/sizeof(radio_Cycles[0]); +const char * radio_CyclesLabels[] = { + "Continuous", + "One-Shot" +}; +#define UI_CyclesColor Green +#define UI_CyclesBackColor RGB(0,0,0) + +// rect_t radio_Cycles[], radio_CyclesCount, char * radio_CyclesLabels[] #define PI 3.1415 // Handy value +template <typename T> int sgn(T val) { + return (T(0) < val) - (val < T(0)); +} -SignalGenDisplay::SignalGenDisplay(RA8875 * _lcd, SignalGenDAC * _signal, + +// ############################################################################# + +SignalGenDisplay::SignalGenDisplay(RA8875 * _lcd, SignalGenDAC * _signal, const char * _Path, const char * _ProgName, const char * _Manuf, const char * _Ver, const char * _Build) : - lcd(_lcd), signal(_signal), ProgName(_ProgName), Manuf(_Manuf), Ver(_Ver), Build(_Build) { + lcd(_lcd), signal(_signal), Path(_Path), ProgName(_ProgName), Manuf(_Manuf), Ver(_Ver), Build(_Build) { + char buf[50]; + + snprintf(buf, sizeof(buf), "%s/SigGen.ini", Path); + ini.SetFile(buf, 2); needsInit = true; } @@ -187,74 +219,107 @@ } -template <typename T> int sgn(T val) { - return (T(0) < val) - (val < T(0)); -} + char SignalGenDisplay::GetTouchEvent(void) { TouchCode_t touch; - touch = lcd->TouchPanelReadable(); // any touch to report? - if (touch) { - uint8_t id = lcd->TouchID(0); // 'id' tracks the individual touches - TouchCode_t ev = lcd->TouchCode(0); // 'ev'ent indicates no_touch, touch, held, release, ... - point_t point = lcd->TouchCoordinates(0); // and of course the (x,y) coordinates + touch = lcd->TouchPanelReadable(); // any touch to report? + if (touch == no_touch) { + timerForceTSCal.stop(); + timerForceTSCal.reset(); + } else { + uint8_t id = lcd->TouchID(0); // 'id' tracks the individual touches + TouchCode_t ev = lcd->TouchCode(0); // 'ev'ent indicates no_touch, touch, held, release, ... + point_t point = lcd->TouchCoordinates(0); // and of course the (x,y) coordinates if (ev == touch) { - timer.start(); - timer.reset(); + timerRepeat.start(); + timerRepeat.reset(); + timerForceTSCal.start(); + timerForceTSCal.reset(); + } else if (ev == held && timerForceTSCal.read() > 10.0) { + printf("Forcing T.S. Cal\r\n"); + timerForceTSCal.stop(); + timerForceTSCal.reset(); + lcd->cls(); + CalibrateTS(); + Refresh(); } - if ((ev == release) || (ev == held && timer.read_ms() > 250)) { - timer.reset(); + if ((ev == release) || (ev == held && timerRepeat.read_ms() > 250)) { + timerRepeat.reset(); switch (vis) { case VS_MainScreen: + // Start/Stop/Pulse + if (textLen == 0 && ev == release) { + if (lcd->Intersect(UI_START_STOP, point)) { + printf("Start/Stop/Pulse %d - %d : %c\r\n", pulseMode, signal->isRunning(), + StartStopKeys[pulseMode ? 2 : signal->isRunning()]); + return StartStopKeys[pulseMode ? 2 : signal->isRunning()]; + } + } // Mode Keys touch - for (int i=0; i<ModeCount; i++) { - if (lcd->Intersect(ModeButtons[i], point)) { - return ModeKeys[i]; + if (ev == release) { + for (int i=0; i<ModeCount; i++) { + if (lcd->Intersect(ModeButtons[i], point)) { + return ModeKeys[i]; + } } } // Parameters - for (int i=0; i<ParameterCount; i++) { - if (lcd->Intersect(Parameters[i], point)) { - return ParameterKeys[i]; + if (ev == release) { + for (int i=0; i<ParameterCount; i++) { + if (lcd->Intersect(Parameters[i], point)) { + return ParameterKeys[i]; + } + } + } + // Keypad + if (1 || ev == release) { + for (int i=0; i<KeypadCount; i++) { + if (lcd->Intersect(UI_Keypad[i], point)) { + return KeyPadKeys[i]; + } } } - // Keypad - for (int i=0; i<KeypadCount; i++) { - if (lcd->Intersect(UI_Keypad[i], point)) { - return KeyPadKeys[i]; + if (ev == release) { + if (lcd->Intersect(NavToSettings, point)) { + vis = VS_Settings; + Refresh(); + while (lcd->TouchPanelReadable()) + ; + Thread::wait(100); } } - - if (lcd->Intersect(NavToSettings, point)) { - vis = VS_Settings; - Refresh(); - while (lcd->TouchPanelReadable()) - ; - Thread::wait(100); - } break; + case VS_Settings: Thread::wait(20); 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)); + SaveSettings(OM_BACKL); ShowBrightnessSetting(); } - if (lcd->Intersect(NavToSettings, point)) { - // 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; - Refresh(); - while (lcd->TouchPanelReadable()) - ; - Thread::wait(100); - ShowMenu(); + if (ev == release) { + if (lcd->Intersect(NavToSettings, point)) { + // Switch to main screen + vis = VS_MainScreen; + Refresh(); + while (lcd->TouchPanelReadable()) + ; + Thread::wait(100); + ShowMenu(); + } + } + + if (ev == release) { + for (int i=0; i<radio_CyclesCount; i++) { + if (lcd->Intersect(radio_Cycles[i], point)) { + pulseMode = i; + ShowCyclesControl(); + } + } } break; } @@ -267,15 +332,17 @@ void SignalGenDisplay::Refresh() { if (needsInit) { char buf[100]; - + needsInit = false; vis = VS_MainScreen; // always start on main screen - + lcd->TouchPanelInit(); + InitializeTS(); + // Default the backlight ini.ReadString("Settings", "Backlight", buf, sizeof(buf), "60"); lcd->Backlight_u8(atoi(buf)); - ini.ReadString("Signal", "Waveform", buf, sizeof(buf), "Sine"); + 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; @@ -293,6 +360,15 @@ ini.ReadString("Signal", "Offset", buf, sizeof(buf), "1.5"); offset = atof(buf); + + ini.ReadString("Signal", "Pulse Mode", buf, sizeof(buf), radio_CyclesLabels[0]); + for (int i=0; i<radio_CyclesCount; i++) { + if (strcmp(radio_CyclesLabels[i], buf) == 0) { + pulseMode = i; + break; + } + } + ShowMenu(); } switch (vis) { case VS_MainScreen: @@ -318,14 +394,31 @@ lcd->SelectDrawingLayer(1); lcd->SetLayerMode(RA8875::ShowLayer1); lcd->foreground(UI_ProductNameColor); - ShowProductInfo(); + ShowProductInfo(true); + ShowCyclesControl(); ShowBrightnessSetting(); DrawNavGadget(); - DrawModeButtons(); break; } } +// rect_t radio_Cycles[], radio_CyclesCount, char * radio_CyclesLabels[] + +void SignalGenDisplay::ShowCyclesControl(void) { + lcd->fillrect(SignalMode, UI_CyclesBackColor); + lcd->foreground(UI_CyclesColor); + lcd->background(UI_CyclesBackColor); + lcd->SetTextCursor(SignalMode.p1.x+1, SignalMode.p1.y+1); + lcd->printf("%s", SignalModeLabel); + for (int x=0; x<radio_CyclesCount; x++) { + lcd->fillrect(radio_Cycles[x], UI_CyclesBackColor); + lcd->foreground(UI_CyclesColor); + lcd->background(UI_CyclesBackColor); + lcd->SetTextCursor(radio_Cycles[x].p1.x+1,radio_Cycles[x].p1.y+1); + lcd->printf("%c %s", (pulseMode == x) ? '\x07' : '\x09', radio_CyclesLabels[x]); + } +} + void SignalGenDisplay::DrawModeButtons(void) { for (int i=0; i<ModeCount; i++) { @@ -343,22 +436,37 @@ } -void SignalGenDisplay::ShowProductInfo(void) { +void SignalGenDisplay::ShowProductInfo(bool builddate) { rect_t r = UI_PROD_RECT; lcd->window(r); lcd->SetTextCursor(r.p1.x, r.p1.y); lcd->printf("%s v%s", ProgName, Ver); lcd->SetTextCursor(r.p1.x, r.p1.y+16); lcd->printf("by %s", Manuf); + if (builddate) { + lcd->SetTextCursor(r.p1.x, r.p1.y+32); + lcd->printf("%s", Build); + } lcd->window(); } void SignalGenDisplay::ShowBrightnessSetting(void) { + int i; // Sunbeam lcd->fillrect(sunray[0], White); lcd->fillrect(sunray[1], White); + for (i=-2; i<=+2; i++) { + lcd->line( + (sunray[0].p1.x + sunray[1].p1.x)/2 - 5 + i, (sunray[0].p1.y + sunray[1].p1.y)/2 - 5 - i, + (sunray[0].p2.x + sunray[1].p2.x)/2 + 5 + i, (sunray[0].p2.y + sunray[1].p2.y)/2 + 5 - i, + White); + lcd->line( + (sunray[0].p2.x + sunray[1].p1.x)/2 - 5 + i, (sunray[0].p2.y + sunray[1].p1.y)/2 + 5 + i, + (sunray[0].p1.x + sunray[1].p2.x)/2 + 5 + i, (sunray[0].p1.y + sunray[1].p2.y)/2 - 5 + i, + White); + } lcd->fillcircle(suncenter, 18, UI_BackColor); - lcd->fillcircle(suncenter, 15, White); + lcd->fillcircle(suncenter, 12, White); lcd->rect(sungraph, Blue); float bl = lcd->GetBacklight(); lcd->fillrect(inrgraph, UI_BackColor); @@ -387,29 +495,36 @@ SignalGenDisplay::OM_Changes SignalGenDisplay::Poll(char c) { OM_Changes ret = OM_NONE; + if (needsInit) + Refresh(); // If Poll was the first API call, we need to init SaveSettings(); if (!c) { c = GetTouchEvent(); } if (c) { printf("%02X: EntryMd: %d, textLen: %d [%s] VIS: %d\r\n", c, EntryMd, textLen, textBuffer, vis); - } - /// - 'd' duty cycle entry - /// - 'f' frequency entry - /// - 'p' period entry - /// - 'v' voltage entry - /// - 'o' offset voltage entry - /// - '0'-'9','.' numeric entry - /// - <enter> complete numeric entry - /// - <esc> abandon numeric entry - /// - <nul> do nothing, just poll + } + /// 01234567890-. #?SQTW dfpvo < > <bs> <enter> <esc> switch (c) { case '#': - lcd->DumpRegisters(); + printf("DumpRegisters for RA8875 unsupported\r\n"); + //lcd->DumpRegisters(); break; case '?': ShowMenu(); break; + case 'G': // Go is 'Start' + signal->Start(false); + ShowStartStop(true); + break; + case 'O': // Off + signal->Stop(); + ShowStartStop(true); + break; + case 'P': // 'P'ulse + signal->Start(true); + ShowStartStop(true); + break; case 'S': if (mode != SG_SINE) SaveSettings(OM_MODE); @@ -693,7 +808,7 @@ } bool SignalGenDisplay::SetVoltageOffset(float _voltage) { - if (_voltage >= -1.65 && _voltage <= 1.65) { + if (_voltage > -SG_MAX_V && _voltage < SG_MAX_V) { if (abs(_voltage) < 0.008) // if binary precision slips it, fix it _voltage = 0.0; offset = _voltage; @@ -720,6 +835,8 @@ loc_t df = rangelimit(offset, SG_MIN_V, SG_MAX_V) / SG_MAX_V * (r.p2.y - r.p1.y); loc_t y; + lcd->SelectUserFont(BPG_Arial08x08); + lcd->background(UI_ScopeBackColor); // Draw the Waveform rectangle lcd->rect(UI_WAVE_RECT, WaveOutlineColor); @@ -737,6 +854,10 @@ 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); + lcd->SetTextCursor(r.p2.x+3*SC_RIGHT_MARGIN/4-3 - 10, markerPos_y - 9); + lcd->printf("%3.2f", vPeakPos); + lcd->SetTextCursor(r.p2.x+3*SC_RIGHT_MARGIN/4-3 - 10, markerNeg_y + 3); + lcd->printf("%3.2f", vPeakNeg); // Draw the offset voltage markers y = r.p2.y - df; @@ -761,7 +882,9 @@ lcd->line(r.p2.x,r.p2.y, r.p2.x+SC_RIGHT_MARGIN/3,r.p2.y, UI_VOffsetColor); // horz break; } - + lcd->SetTextCursor(r.p2.x+SC_RIGHT_MARGIN/3-3 - 8, y - 10); + lcd->printf("%3.2f", offset); + // Draw the Frequency marker w = r.p2.x - r.p1.x; dim_t dc = dutycycle/100.0 * 1*w/2; @@ -797,15 +920,23 @@ p.x-3,p.y-2, p.x-3,p.y+2, UI_DutyColor); + lcd->SetTextCursor(p.x + 3, p.y-4); + float period = dutycycle/100*1/frequency; + if (period < 0.001) + lcd->printf("%8.3f uS", period * 1000000); + else + lcd->printf("%8.3f mS", period * 1000); + + lcd->SelectUserFont(); // restore DrawWaveform(r, mode, White); } -// ++ +----+ + + -// . . | | / \ /| -// . . | | | / \ / / | -// . | | \ / / | -// ++ +----+ + + + +// ++ +----+ + + +// . . | | / \ / | +// . + | | | / + / + | +// . | | \ / / | +// ++ +----+ + + + // void SignalGenDisplay::DrawWaveform(rect_t r, SG_Mode mode, color_t color, bool drawPure) { loc_t x,y; @@ -857,23 +988,43 @@ break; case SG_TRIANGLE: for (int cycle=0; cycle<2; cycle++) { - 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 + for (x=0; x<=privDutyCycleX; x++) { + v = privVoltage * (float)x/privDutyCycleX; + if (x < privDutyCycleX/2) + v += privOffset; + else + v = privVoltage - (v - privOffset); + y = r.p2.y - rangelimit(v, SG_MIN_V, SG_MAX_V) / vRange * h; + lcd->pixel(r.p1.x + cycle * w/2 + x, y, color); + } + dim_t phaseWidth = (w/2 - privDutyCycleX); + for (x=0; x<phaseWidth; x++) { + v = privVoltage * (float)x/phaseWidth; + if (x < phaseWidth/2) + v = privOffset - v; + else + v = v + privOffset - privVoltage; + y = r.p2.y - rangelimit(v, SG_MIN_V, SG_MAX_V) / vRange * h; + lcd->pixel(r.p1.x + cycle * w/2 + privDutyCycleX + x, y, color); + } } break; case SG_SAWTOOTH: for (int cycle=0; cycle<2; cycle++) { - 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); + for (x=0; x<=privDutyCycleX; x++) { + v = privVoltage/2 * (float)x/privDutyCycleX - privVoltage/2 + privOffset; + y = r.p2.y - rangelimit(v, SG_MIN_V, SG_MAX_V) / vRange * h; + lcd->pixel(r.p1.x + cycle * w/2 + x, y, color); + } + dim_t phaseWidth = (w/2 - privDutyCycleX); + for (x=0; x<phaseWidth; x++) { + v = privVoltage/2 * (float)x/phaseWidth + privOffset; + y = r.p2.y - rangelimit(v, SG_MIN_V, SG_MAX_V) / vRange * h; + lcd->pixel(r.p1.x + cycle * w/2 + privDutyCycleX + x, y, color); + } + loc_t y2 = r.p2.y - rangelimit(-privVoltage/2 + privOffset, SG_MIN_V, SG_MAX_V) / vRange * h; + lcd->line(r.p1.x + cycle*w/2 + w/2 - 1, y, + r.p1.x + cycle*w/2 + w/2, y2); } break; case SG_USER: @@ -925,7 +1076,9 @@ lcd->foreground(fcolor); lcd->background(bcolor); lcd->SetTextCursor(r.p1.x+1, r.p1.y+1); - if (frequency >= 1000.0) + if (frequency >= 1000000.0) + lcd->printf("%8.3f MHz", frequency/1000000); + else if (frequency >= 1000.0) lcd->printf("%8.3f kHz", frequency/1000); else lcd->printf("%8.3f Hz ", frequency); @@ -1044,16 +1197,32 @@ lcd->SetTextCursor((r.p1.x+r.p2.x)/2 - 4,r.p1.y + BTN_H/2 - 8); // 8x16 char lcd->putc(UI_KeyLabels[label]); break; + case SG_START: + lcd->foreground(Black); + lcd->background(buttonface); + lcd->SetTextCursor((r.p1.x+r.p2.x)/2 - 4 * strlen(UI_StartLabels[label]),r.p1.y + BTN_H/2 - 8); + lcd->puts(UI_StartLabels[label]); + break; + } +} + +void SignalGenDisplay::ShowStartStop(bool showIt) { + if (textLen == 0) { + lcd->fillrect(UI_START_STOP, UI_BackColor); + if (showIt) { + DrawButton(UI_START_STOP, false, SG_START, true, pulseMode ? 2 : signal->isRunning()); + } } } void SignalGenDisplay::updateTextWindow(void) { + ShowStartStop(false); lcd->window(UI_DATA_ENTRY); lcd->fillrect(UI_DATA_ENTRY, White); lcd->foreground(Black); lcd->background(White); lcd->SetTextCursor(UI_DATA_ENTRY.p1.x+1,UI_DATA_ENTRY.p1.y+1); - lcd->printf("%21s", textBuffer); + lcd->printf("%13s", textBuffer); lcd->window(); } @@ -1061,6 +1230,7 @@ lcd->fillrect(UI_DATA_ENTRY, UI_BackColor); textBuffer[0] = '\0'; textLen = 0; + ShowStartStop(true); } float SignalGenDisplay::rangelimit(float value, float min, float max) { @@ -1118,6 +1288,12 @@ printf(" Signal:Offset=%s\r\n", buf); ini.WriteString("Signal", "Offset", buf); } + if (Changes & OM_BACKL) { + Changes &= ~OM_BACKL; + snprintf(buf, sizeof(buf), "%d", lcd->GetBacklight_u8()); + ini.WriteString("Settings", "Backlight", buf); + } + } } @@ -1174,4 +1350,55 @@ clearTextWindow(); } printf("<- end resetDataEntry()\r\n"); -} \ No newline at end of file +} + +// Calibrate the resistive touch screen, and store the data on the +// local file system. +// +void SignalGenDisplay::CalibrateTS(void) +{ + FILE * fh; + tpMatrix_t matrix; + RetCode_t r; + Timer testperiod; + char buf[100]; + + r = lcd->TouchPanelCalibrate("Calibrate the touch panel", &matrix); + if (r == noerror) { + snprintf(buf, sizeof(buf), "%s/tpcal.cfg", Path); + fh = fopen(buf, "wb"); + if (fh) { + fwrite(&matrix, sizeof(tpMatrix_t), 1, fh); + fclose(fh); + printf(" %s cal written.\r\n", buf); + lcd->cls(); + } else { + printf(" couldn't open %s file.\r\n", buf); + } + } else { + printf("error return: %d\r\n", r); + } + lcd->cls(); +} + +// Try to load a previous resistive touch screen calibration from storage. If it +// doesn't exist, activate the touch screen calibration process. +// +void SignalGenDisplay::InitializeTS(void) +{ + FILE * fh; + tpMatrix_t matrix; + char buf[100]; + + snprintf(buf, sizeof(buf), "%s/tpcal.cfg", Path); + fh = fopen(buf, "rb"); + if (fh) { + fread(&matrix, sizeof(tpMatrix_t), 1, fh); + fclose(fh); + lcd->TouchPanelSetMatrix(&matrix); + printf(" tp cal loaded.\r\n"); + } else { + CalibrateTS(); + } +} +