Signal Generator

Dependencies:   IniManager RA8875 Watchdog mbed-rtos mbed

Fork of speaker_demo_Analog by jim hamblen

SignalGenDisplay.h

Committer:
WiredHome
Date:
2017-05-20
Revision:
6:1f48212fbaf9
Parent:
5:49dd0c647a40

File content as of revision 6:1f48212fbaf9:


#ifndef SIGNALGENDISPLAY_H
#define SIGNALGENDISPLAY_H

#include "mbed.h"
#include "RA8875.h"
#include "SignalGenDAC.h"
#include "IniManager.h"

#define SG_MIN_V 0.0    // Constraint, to match to the hardware
#define SG_MAX_V 3.3    // 
#define SG_AOUT_FS 3.3  // Analog output full scale

#define SAVE_AFTER_IDLE_S 10 // How long after idle should it save

class SignalGenDisplay {
public:
    /// Constructor for the Signal Generator User Interface.
    ///
    /// This will also load the initial settings from the
    /// file system.
    ///
    /// @code
    /// #include "SignalGenDisplay.h"
    /// #include "SignalGenDAC.h"
    /// RA8875 lcd(p5,p6,p7,p12, NC, "tft");             // SPI:{MOSI,MISO,SCK,/ChipSelect,/reset}, name
    /// INI ini;
    /// 
    /// RawSerial pc(USBTX, USBRX);
    /// LocalFileSystem local("local");
    /// SignalGenDAC g_signal(p18);
    /// SignalGenDisplay ui(&lcd, &g_signal);
    /// 
    /// int main() {
    ///     pc.baud(460800);
    /// 
    ///     if (wd.WatchdogCausedReset()) {
    ///         pc.printf("**** Watchdog Event caused reset ****\r\n");
    ///     }
    ///     wd.Configure(30.0);
    ///     ini.SetFile("/local/SigGen.ini", 2);
    /// 
    ///     lcd.init(480,272,16, true, true, true);
    ///     while (true)
    ///     {
    ///         wd.Service();
    ///         if (pc.readable()) {
    ///             int c = pc.getc();
    ///             ui.Poll(c);
    ///         } else {
    ///             ui.Poll();
    ///         }
    ///     } // End of 'while' statement
    /// } // End of main program
    /// @endcode
    ///
    /// @param[in] lcd is a pointer to the Graphics Display
    /// @param[in] signal is a handle to the signal generator
    /// @param[in] Path is a pointer to an optional file system path. If
    ///             not provided, "/local" is used. If you do not have the
    ///             original mbed, your device might not have the local file
    ///             system.
    /// @param[in] ProgrName is an optional pointer to a constant string
    ///             proclaiming the program name. If not provided,
    ///             "Signal Generator" is used.
    /// @param[in] Manuf is an optional pointer to a constant string. If
    ///             not provided, "Smartware Computing" is used.
    /// @param[in] Ver is an optional pointer to a constant string. If not
    ///             provided, "0.01" (or similar) is used.
    /// @param[in] Build is an optional pointer to a constant string. If not
    ///             provided, __DATE__ " " __TIME__ is used.
    ///
    SignalGenDisplay(RA8875 * lcd, SignalGenDAC * signal, 
        const char * Path = "/local",
        const char * ProgName = "Signal Generator", 
        const char * Manuf = "Smartware Computing", 
        const char * Ver = "0.01",
        const char * Build = __DATE__ " " __TIME__);
    
    /// Destructor
    ////
    ~SignalGenDisplay();
    
    /// Refresh the display for the current settings
    /// and display mode.
    ///
    void Refresh(void);
    
    /// Set the frequency information
    ///
    /// This automatically sets the period as 1/frequency
    ///
    /// @param[in] frequency desired
    /// @returns true if the value was accepted
    ///
    bool SetFrequency(float frequency);
    
    /// Get the current frequency setting
    ///
    /// @returns current frequency
    ///
    float GetFrequency(void) { return frequency; }
    
    /// Set the period instead of the frequency
    ///
    /// This automatically sets the frequency as 1/period
    ///
    /// @param[in] period desired
    /// @returns true if the value was accepted
    ///
    bool SetPeriod(float period);
    
    /// Get the current period
    ///
    /// @returns current period
    ///
    float GetPeriod(void) { return 1/frequency; }
    
    /// Set the Duty Cycle
    ///
    /// This adjusts the duty cycle of the waveform
    ///
    /// @param[in] dutyCycle is a value ranging from 0 to 100.
    /// @returns true if the value was accepted
    ///
    bool SetDutyCycle(float dutyCycle);
    
    /// Get the current duty cycle
    ///
    /// @returns the duty cycle
    ///
    float GetDutyCycle(void) { return dutycycle; }
    
    /// Set the peak-to-peak voltage of the of the waveform
    ///
    /// In the range of 0 to 3.3v
    ///
    /// @param[in] voltage is the peak to peak voltage
    /// @returns true if the value was accepted
    ///
    bool SetVoltagePeakToPeak(float voltage);

    /// Get the Peak to Peak voltage
    ///
    /// @returns peak to peak voltage
    ///
    float GetVoltagePeakToPeak(void) { return voltage; }
    
    /// Set the offset in the range of +/- 1.65v
    ///
    /// A zero volt offset is biased to VCC/2 (3.3/2)
    ///
    /// @param[in] voltage is the offset voltage.
    /// @returns true if the value was accepted
    ///
    bool SetVoltageOffset(float voltage);

    /// Get the offset voltage
    ///
    /// @returns offset voltage
    ///
    float GetVoltageOffset(void) { return offset; }
    
    /// Select a Waveform Mode
    ///
    /// The selection will update the display to reflect the current state
    ///
    /// @param[in] mode sets the signal generator mode.
    /// @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_Waveform mode, bool force = false);
    
    /// Operating mode changes
    ///
    /// Changes in the operating mode or other parameters are reported by a 
    /// bitmask value, where zero or more bits are set.
    ///
    typedef enum {
        OM_NONE     = 0x0000,   ///< No change in operating mode
        OM_MODE     = 0x0001,   ///< Signal mode changed; Sine, Square, Triangle, Sawtooth, User
        OM_PULSE    = 0x0002,   ///< Continuous v. Single-shot
        OM_FREQ     = 0x0004,   ///< Change in the frequency
        OM_PERI     = 0x0008,   ///< Change in the period (effectively same as frequency)
        OM_DUTY     = 0x0010,   ///< Change in the duty cycle
        OM_VOLT     = 0x0020,   ///< Change in the peak to peak amplitude
        OM_OFFS     = 0x0040,   ///< Change in the offset voltage
        OM_BACKL    = 0x0080,   ///< Change in the backlight setting
    } OM_Changes;

    /// Poll the Signal Generator UI for changes in operation.
    ///
    /// Call this periodically, in order to determine if there is a user-activated
    /// change in the operating mode of the signal generator.
    ///
    /// @param[in] c is the optional character, emulating the onscreen keypad
    ///     - '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
    /// @returns a bitmask of which non-zero indicates changes in mode.
    ///
    OM_Changes Poll(char c = 0);

    /// Show the menu of commands on the console interface
    ///
    void ShowMenu(void);

private:
    RA8875 * lcd;
    SignalGenDAC * signal;
    const char * Path;
    const char * ProgName; 
    const char * Manuf; 
    const char * Ver;
    const char * Build;
    bool needsInit;     ///< allows defering first init to after the constructor
    INI ini;
    typedef enum {
        VS_MainScreen,
        VS_Settings,
    } VisualScreen;
    VisualScreen vis;
    SG_Waveform mode;       ///< signal mode
    float frequency;    ///< selected frequency
    float dutycycle;    ///< selected duty cycle
    float voltage;      ///< selected voltage
    float offset;       ///< selected offset
    int pulseMode;      ///< 0 == continuos, 1 == one-shot
    char textBuffer[10]; ///< a place to enter text
    int textLen;        ///< num chars in textBuffer
    Timer timerRepeat;  ///< Keypad repeat timer
    OM_Changes EntryMd; ///< indicates if in data entry mode
    uint16_t Changes;   ///< combined from EntryMd for what to save
    Timer timerSave;    ///< Save state timer
    Timer timerForceTSCal;  ///< tracks continuous touch to force TS Calibration
    
    void ShowProductInfo(bool builddate = false);
    void ShowBrightnessSetting(void);
    char GetTouchEvent(void);
    void ClearScope(void);
    void UpdateScope(void);
    void updateDutyCycle(void);
    void updateFrequency(void);
    void updatePeriod(void);
    void updateVoltage(void);
    void updateOffset(void);
    void updateTextWindow(void);
    void clearTextWindow(void);
    /// Set a flag to request modified settings to be saved.
    ///
    /// This is also called with OM_NONE as a background task to see if 
    /// any settings have been changed. In this way, settings changes are not
    /// written immediately, which is both slow, and unnecessary if another
    /// change is about to be made.
    ///
    /// @param[in] reportMode indicates what setting, if any, has changed.
    ///
    void SaveSettings(OM_Changes reportMode = OM_NONE);
    void resetDataEntry(OM_Changes mode = OM_NONE, bool save = false);     ///< save the current value if exiting entry mode
    void DrawNavGadget(void);
    void DrawModeButtons(void);
    void DrawKeypadEnabled(bool enable = false);
    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);
    
    /// Force a calibration of the resistive touchscreen
    void CalibrateTS(void);

    /// Try to load a previous resistive touch screen calibration from storage. If it
    /// doesn't exist, activate the touch screen calibration process.
    void InitializeTS(void);
    void ShowStartStop(bool showIt);
};


#endif // SIGNALGENVIEW_H