/************************************************************************
Segger JLink Programmer GUI

Alle software in dit bestand is                                     
Copyright 2013-2015 Hogeschool van Arnhem en Nijmegen                              
$Id: JLinkProgrammer.cpp 1834 2015-03-21 16:17:16Z ewout $
************************************************************************/

// -*- C++ -*- generated by wxGlade 0.6.5 (standalone edition) on Thu Oct 25 13:07:12 2012

#include "JLinkProgrammer.h"
#include <jlinkVersie.h>

// begin wxGlade: ::extracode
// end wxGlade

#include <wx/filename.h>
#include <wx/wfstream.h>
#include <wx/txtstrm.h>
#include <wx/sckstrm.h>
#include <wx/busyinfo.h>
#include <wx/utils.h> 
#include <wx/filedlg.h>
#include <wx/dirdlg.h>
#include <wx/numdlg.h>
#include <wx/clipbrd.h>
#include <wx/artprov.h>

#include <hankleinlogo.xpm>

#include <wx/arrimpl.cpp> // This is a magic incantation which must be done!
WX_DEFINE_OBJARRAY(DeviceConfigLijst);

#ifndef GeenIkoon
#include "SeggerLogo.h"
#endif

#ifndef   COUNTOF
#define COUNTOF(a)    (int)(sizeof(a)/sizeof(a[0]))
#endif

// #ifndef   ZEROFILL
// #define ZEROFILL(Obj) memset(&Obj, 0, sizeof(Obj))
// #endif
// #ifndef   LIMIT
// #define LIMIT(a,b)    if ((a) > (b)) (a) = (b);
// #endif

typedef enum
{
    ProgrammerOpKeuzeID=0,
    ProgrammerStatusBoomID,
    ProgrammerStatusveldID,
    ProgrammerLaadAdresID,
    ProgrammerSchrijfFlashID,
    ProgrammerRecentFlashFileID,
    ProgrammerDummyID,
    ProgrammerEraseFlashID,
    LeesSchrijfOptionBytesID,
    ProgrammerWriteOTPID,
    NicenessID,
    GDBIPPoortID,
    GDBSWOSocketID,
    GDBVerifyDownloadID,
    GDBServerSilentID,
    GDBServerSingleRunID,
    StartStopDDDFrontendID,
    SWOIPPoortID,
    SWOChannelsID,
    SWOSpeedID,
	ProgrammerBestandBoomID,
    ProgrammerDebugID,
    ProgrammerDebugSWOID,
    ProgrammerSWOID,
    ProgrammerKopieerSWOID,
    ProgrammerVerbindID,
    ProgrammerCheckFlashID,
    ProgrammerARMDirID,
    ProgrammerSeggerDirID,
    ProgrammerDDDFrontEndID,
    ProgrammerServerID,
    ResetTargetID,
    HaltTargetID,
    GoTargetID,
    JLinkInterfaceKeuzeID,
    USBSerialID,
    InetHostNameID,
    JLinkTargetNameID,
    JLinkTargetInterfaceID,
    GDBScriptID,
    CPUFreqSpinCtrl,
    CPUFreqDimensieID,
    ProgrammerSWOveldID,
    TargetEndianessKeuzeID,
    JLinkTargetSpeedID,
    JLinkDebugServerEventID,
    DebuggerEventID,
    JLinkSWOViewerEventID,
    ExtProcessPollingTimerID,
    HANLogoID
} ProgrammerMogelijkheden;

JLinkVensterKlasse::JLinkVensterKlasse(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
    wxFrame(parent, id, title, pos, size, wxDEFAULT_FRAME_STYLE),
    timer(this,ExtProcessPollingTimerID),
    bestandGeschiedenis(BestandGeschiedenisMax),
    laatstePad(wxGetHomeDir()),
    hanBitmap(hankleinlogo),
    debugServer((DebugServerProcess *)Null),
    debugger((DebuggerProcess *)Null),
    gdbSwoClient((wxSocketClient *)Null),
    swoViewer((SWOViewerProcess *)Null),
    appConfig(wxGetApp().appConfig),
    goedeStatusTextAttr(wxColour(wxT("DARK GREEN")),wxNullColour,*wxSMALL_FONT),
    waarschuwingStatusTextAttr(wxColour(wxT("ORANGE")),wxNullColour,*wxSMALL_FONT),
    fouteStatusTextAttr(*wxRED,wxNullColour,*wxSMALL_FONT),
    seggerStandaardPad(
#ifdef __WXMAC__
        wxT("/Applications/SEGGER")
#elif defined(__WXMSW__)
        wxT("C:/Program Files/SEGGER")
#elif defined(__LINUX__)
        wxT("/opt/SEGGER")
#endif
        ),
    armStandaardPad(
#ifdef __WXMAC__
        wxT("/usr/local")
#elif defined(__WXMSW__)
        wxT("C:/Program Files")
#elif defined(__LINUX__)
        wxT("/usr/local")
#endif
        ),
    dddStandaardPad(
#ifdef __WXMAC__
        wxT("/opt/local/bin")
#elif defined(__WXMSW__)
        wxT("C:/Program Files")
#elif defined(__LINUX__)
        wxT("/usr/local/bin")
#endif
        )

{	
    stm32DeviceIDInit();

    configLijst.Clear();
	
    int jlinkVerbinding;
    int debugPoort;
    int swoPoort,swoMaskBits,swoFreq; 
    int hulpsnelheid;
    bool gdbVerify,gdbSilentRun,gdbSingleRun;

    appConfig->SetPath(wxT("/Configuratie"));
    appConfig->Read(wxT("JLinkVerbindingInterface"),&jlinkVerbinding,0);
    appConfig->Read(wxT("SeggerDir"),&seggerDirPad,seggerStandaardPad);
    appConfig->Read(wxT("ARMdir"),&armDirPad,armStandaardPad);
    appConfig->Read(wxT("DDDpad"),&dddPad,dddStandaardPad);
    appConfig->Read(wxT("SWOBestandDir"),&swoBestandPad,wxGetHomeDir());
    appConfig->Read(wxT("Favoriete Fabrikant"),&favFabrikant,wxT("ST"));			
    appConfig->Read(wxT("Snelheid"),&hulpsnelheid,JLINKARM_SPEED_AUTO);
    echteSnelheid = snelheid=(UInt16)hulpsnelheid;
	
    appConfig->Read(wxT("Niceness"),&niceness,0);
    appConfig->Read(wxT("Debugpoort"),&debugPoort,2331);
    appConfig->Read(wxT("GDBVerifyAan"),&gdbVerify,true);
    appConfig->Read(wxT("GDBSingleRun"),&gdbSilentRun,false);
    appConfig->Read(wxT("GDBSilentRun"),&gdbSingleRun,false);

    appConfig->Read(wxT("SWOpoort"),&swoPoort,2332);
    appConfig->Read(wxT("SWOMaskBits"),&swoMaskBits,0x1);
    appConfig->Read(wxT("SWOFrequency"),&swoFreq,0x1);
	
	
    appConfig->SetPath(wxT("/Configuratie/Targets"));

    int numTargets;
    appConfig->Read(wxT("NumberOfTargets"),&numTargets,1);
    configLijst.Alloc(numTargets);

    for (Int32 i=0;i<numTargets;i++)
    {
        wxString tnaam,bestandPad,gdbis;
        int cpufreq;
        int laadAdres;
        int intfKeuze,endKeuze;
        int sernummer;

        appConfig->Read(wxString::Format(wxT("DebugTarget%d"),i),&tnaam,wxT("STM32F051R8"));
        appConfig->Read(wxString::Format(wxT("CPUFreq%d"),i),&cpufreq,48000000);
        appConfig->Read(wxString::Format(wxT("DebugInterface%d"),i),&intfKeuze,0);
        appConfig->Read(wxString::Format(wxT("Endianess%d"),i),&endKeuze,0);		
        appConfig->Read(wxString::Format(wxT("BestandPad%d"),i),&bestandPad,wxGetHomeDir());
        appConfig->Read(wxString::Format(wxT("FlashLaadAdres%d"),i),&laadAdres,0x8000000);
        appConfig->Read(wxString::Format(wxT("GDBInitScript%d"),i),&gdbis,wxEmptyString);
        appConfig->Read(wxString::Format(wxT("SerNumberID%d"),i),&sernummer,0x0);
		
        const DeviceConfig device(tnaam,cpufreq,intfKeuze,endKeuze,laadAdres,gdbis,sernummer,bestandPad);
        configLijst.Add(device);
    }

    int ht;
    appConfig->Read(wxT("CurrentTarget"),&ht,0);
    huidigTarget=ht;

    wxToolBar *gereedschap = CreateToolBar(); //new wxToolBar(this,wxID_ANY);

#ifndef __WXMAC__
    const wxBitmap recentbm(wxArtProvider::GetBitmap(wxART_EXECUTABLE_FILE,wxART_TOOLBAR));

    gereedschap->AddTool(wxID_PREVIEW, wxT("RecentFiles"),
                         recentbm, wxNullBitmap, wxITEM_DROPDOWN,
                         wxT("Recently used files"), wxT("These are the most recently selected files."));

    tbRecenteBestandenMenu = new wxMenu;
    gereedschap->SetDropdownMenu(wxID_PREVIEW, tbRecenteBestandenMenu);
#endif
    const wxBitmap openbm(wxArtProvider::GetBitmap(wxART_FILE_OPEN,wxART_TOOLBAR));
    const wxBitmap converteerbm(wxArtProvider::GetBitmap(wxART_FIND_AND_REPLACE,wxART_TOOLBAR));

    gereedschap->AddTool(wxID_OPEN,_("Open"),openbm,wxNullBitmap,wxITEM_NORMAL,_("Open a File"),_("This opens an file"));
    gereedschap->AddTool(wxID_SAVEAS,_("SaveAs"),converteerbm,wxNullBitmap,wxITEM_NORMAL,_("Convert and Save a File"),_("Convert to a different format and save a file"));

    gereedschap->AddSeparator();

    const wxBitmap kopieerbm(wxArtProvider::GetBitmap(wxART_COPY,wxART_TOOLBAR));
    const wxBitmap slaopbm(wxArtProvider::GetBitmap(wxART_FILE_SAVE,wxART_TOOLBAR));

    gereedschap->AddTool(ProgrammerKopieerSWOID,_("Kopieer"),kopieerbm,wxNullBitmap,wxITEM_NORMAL,_("Copy ITM Software Trace Output"),_("Copy the SWO output window to the copy buffer"));
    gereedschap->AddTool(wxID_SAVE,_("SlaOp"),slaopbm,wxNullBitmap,wxITEM_NORMAL,_("Save ITM Software Trace Output"),_("DSave The ITM Software trace to a file"));


    gereedschap->AddStretchableSpace();
	 
    wxImage hanIm(hankleinlogo);

    hanIm.Rescale(58,32);
    const wxBitmap hanImbm(hanIm);

//	 wxBitmapButton * const hanLogoBitmapButton = new wxBitmapButton(gereedschap, HANLogoID,hanImbm);
//	 hanLogoBitmapButton->SetHelpText(_("Kom ook Embedded Systems Engineering studeren op de HAN!!"));

    gereedschap->AddTool(HANLogoID,_("HANESE"),hanImbm,wxNullBitmap,wxITEM_NORMAL,_("HAN Embedded Systems Engineering"),_("Kom ook Embedded Systems Engineering studeren op de HAN!!"));

    gereedschap->Realize();

    SetToolBar(gereedschap);

    // (wxTE_PROCESS_ENTER+wxCB_DROPDOWN) handmatig na wxglade invullen
    // begin wxGlade: JLinkVensterKlasse::JLinkVensterKlasse
    achtergrondPaneel = new wxPanel(this, wxID_ANY);
    swoPaneel = new wxScrolledWindow(achtergrondPaneel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL);
    logPaneel = new wxScrolledWindow(achtergrondPaneel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL);
    sizer_18_staticbox = new wxStaticBox(achtergrondPaneel, wxID_ANY, _("CPU Frequency"));
    gdbPickerCtrl_staticbox = new wxStaticBox(achtergrondPaneel, wxID_ANY, _("GDB initilisation script"));
    sizer_12_staticbox = new wxStaticBox(achtergrondPaneel, wxID_ANY, _("Target parameters"));
    sizer_10_staticbox = new wxStaticBox(achtergrondPaneel, wxID_ANY, _("Connection to J-Link"));
    logSizer_staticbox = new wxStaticBox(achtergrondPaneel, wxID_ANY, _("Logging and GDB server output"));
    swoSizer_staticbox = new wxStaticBox(achtergrondPaneel, wxID_ANY, _("ITM software trace output"));
    sizer_14_staticbox = new wxStaticBox(achtergrondPaneel, wxID_ANY, _("Target file"));
    sizer_8_staticbox = new wxStaticBox(achtergrondPaneel, wxID_ANY, _("Load address"));
    flashSizer_staticbox = new wxStaticBox(achtergrondPaneel, wxID_ANY, _("Flash operations"));
    jlinkGDBSizer_staticbox = new wxStaticBox(achtergrondPaneel, wxID_ANY, _("J-Link GDB Server"));
    sizer_26_staticbox = new wxStaticBox(achtergrondPaneel, wxID_ANY, _("GDB "));
    jlinkSWOSizer_staticbox = new wxStaticBox(achtergrondPaneel, wxID_ANY, _("J-Link SWO Viewer"));
    debugSizer_staticbox = new wxStaticBox(achtergrondPaneel, wxID_ANY, _("Debug operations"));
    sizer_20_staticbox = new wxStaticBox(achtergrondPaneel, wxID_ANY, _("Serial Number"));
    menubar = new wxMenuBar();
    wxMenu* bestandMenu = new wxMenu();
    wxMenu* recenteBestandenMenu = new wxMenu();
    recenteBestandenMenu->Append(ProgrammerDummyID, _("________________"), wxEmptyString, wxITEM_NORMAL);
    bestandMenu->Append(ProgrammerRecentFlashFileID, _("Recent files ....."), recenteBestandenMenu, wxEmptyString);
    bestandMenu->Append(wxID_OPEN, _("&Open\tCtrl+O "), wxEmptyString, wxITEM_NORMAL);
    bestandMenu->Append(wxID_SAVEAS, _("Save As"), _("Save your file in a different executable format"), wxITEM_NORMAL);
    bestandMenu->AppendSeparator();
    bestandMenu->Append(ProgrammerSchrijfFlashID, _("Write flash"), wxEmptyString, wxITEM_NORMAL);
    bestandMenu->Append(ProgrammerEraseFlashID, _("Erase flash"), _("Erase the entire flash in the microcontroller"), wxITEM_NORMAL);
    bestandMenu->AppendSeparator();
    bestandMenu->Append(wxID_ABOUT, _("About"), wxEmptyString, wxITEM_NORMAL);
    bestandMenu->Append(HANLogoID, _("HAN Embedded Systems Engineering"), _("Kom ook Embedded Systems Engineering (ESE) studeren op de Hogeschool van Arnhem en Nijmegen"), wxITEM_NORMAL);
    bestandMenu->Append(wxID_EXIT, _("&Exit\tCtrl+Q"), wxEmptyString, wxITEM_NORMAL);
    bestandMenu->AppendSeparator();
    menubar->Append(bestandMenu, _("File"));
    wxMenu* connectMenu = new wxMenu();
    connectMenu->Append(ProgrammerVerbindID, _("Connect\tCtrl+K"), _("Connect or disconnect the target"), wxITEM_NORMAL);
    connectMenu->Append(ProgrammerDebugID, _("Start Debugging\tCtrl+D"), wxEmptyString, wxITEM_NORMAL);
    connectMenu->Append(ProgrammerSWOID, _("Start SWO Listerener\tCtrl+T"), wxEmptyString, wxITEM_NORMAL);
    menubar->Append(connectMenu, _("Connect"));
    wxMenu* loggingMenu = new wxMenu();
    loggingMenu->Append(ProgrammerKopieerSWOID, _("Copy ITM Software Trace Output\tCtrl+B"), _("Copy the SWO output window to the copy buffer"), wxITEM_NORMAL);
    loggingMenu->Append(wxID_SAVE, _("Save ITM Software Trace Output\tCtrl+S"), wxEmptyString, wxITEM_NORMAL);
    loggingMenu->Append(wxID_DELETE, _("Clear log windows"), wxEmptyString, wxITEM_NORMAL);
    menubar->Append(loggingMenu, _("Logging"));
    wxMenu* instellingenMenu = new wxMenu();
    instellingenMenu->Append(NicenessID, _("GDB Server niceness (Mac OS X/Linux)"), _("This settting will alter the GDB server process niceness. If GDB server uses too much processing time, this will help you reduce the load."), wxITEM_NORMAL);
    instellingenMenu->Append(ProgrammerSeggerDirID, _("Set Segger J-Link driver"), _("When found, SWO and GDB server can be started"), wxITEM_CHECK);
    instellingenMenu->Append(ProgrammerARMDirID, _("Set ARM EABI toolchain"), _("When found, converting binaries to ELF or HEX format is possible, and GDB can be used (on Mac and Linux)"), wxITEM_CHECK);
    instellingenMenu->Append(ProgrammerDDDFrontEndID, _("Set DDD frontend (Mac OS X/Linux)"), _("When found, a DDD frontend session for GDB can be started (Mac and Linux only)"), wxITEM_CHECK);
    menubar->Append(instellingenMenu, _("Settings"));
    SetMenuBar(menubar);
    statusbar = CreateStatusBar(1);
    const wxString jlinkConnectionRadioBox_choices[] = {
        _("USB connection"),
        _("Internet connection"),
    };
    jlinkConnectionRadioBox = new wxRadioBox(achtergrondPaneel, wxID_ANY, _("Jlink connection"), wxDefaultPosition, wxDefaultSize, 2, jlinkConnectionRadioBox_choices, 0, wxRA_SPECIFY_ROWS);
    USBSerialTextCtrl = new wxTextCtrl(achtergrondPaneel, USBSerialID, wxEmptyString);
    const wxString targetNameComboBox_choices[] = {
        _("STM32F103ZET6"),
        _("STM320F050R8"),
    };
    targetNameComboBox = new wxComboBox(achtergrondPaneel, JLinkTargetNameID, wxT(""), wxDefaultPosition, wxDefaultSize, 2, targetNameComboBox_choices, wxCB_DROPDOWN);
    bewaarButton = new wxButton(achtergrondPaneel, wxID_ADD, wxEmptyString);
    vindDeviceButton = new wxButton(achtergrondPaneel, wxID_FIND, wxEmptyString);
    verwijderButton = new wxButton(achtergrondPaneel, wxID_REMOVE, wxEmptyString);
    const wxString speedRadioBox_choices[] = {
        _("Auto selection"),
        _("Adaptive Clocking"),
        _("Manual"),
    };
    speedRadioBox = new wxRadioBox(achtergrondPaneel, JLinkTargetSpeedID, _("Speed"), wxDefaultPosition, wxDefaultSize, 3, speedRadioBox_choices, 0, wxRA_SPECIFY_ROWS);
    cpuFreqSpinCtrl = new wxSpinCtrl(achtergrondPaneel, CPUFreqSpinCtrl, wxT("72000000"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 1000000000);
    const wxString freqDimensieChoice_choices[] = {
        _("Hz"),
        _("kHz"),
        _("MHz"),
    };
    freqDimensieChoice = new wxChoice(achtergrondPaneel, CPUFreqDimensieID, wxDefaultPosition, wxDefaultSize, 3, freqDimensieChoice_choices);
    const wxString interfaceKeuzeChoice_choices[] = {
        _("JTAG"),
        _("SWD"),
    };
    interfaceKeuzeChoice = new wxChoice(achtergrondPaneel, JLinkInterfaceKeuzeID, wxDefaultPosition, wxDefaultSize, 2, interfaceKeuzeChoice_choices);
    const wxString endiannessChoice_choices[] = {
        _("Little Endian"),
        _("Big Endian"),
    };
    endiannessChoice = new wxChoice(achtergrondPaneel, TargetEndianessKeuzeID, wxDefaultPosition, wxDefaultSize, 2, endiannessChoice_choices);
    gdbScriptOpenPickerCtrl = new wxFilePickerCtrl(achtergrondPaneel, GDBScriptID, wxGetHomeDir(), _("Please select the GDB initialisation script"), wxT("GDB (*.gdb)|*.gdb"));
    statusTextCtrl = new wxTextCtrl(logPaneel, ProgrammerStatusveldID, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH2);
    swoTextCtrl = new wxTextCtrl(swoPaneel, ProgrammerSWOveldID, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH2);
    openKnop = new wxFilePickerCtrl(achtergrondPaneel, wxID_OPEN, wxGetHomeDir(), _("Please select an ELF, Hex or Binary file"), wxT("ELF (*.elf)|*.elf|HEX files(*.hex)|*.hex|BIN (*.bin)|*.bin"));
    verbindKnop = new wxToggleButton(achtergrondPaneel, ProgrammerVerbindID, _("Connect"));
    schrijfFlashKnop = new wxButton(achtergrondPaneel, ProgrammerSchrijfFlashID, _("Write flash"));
    flashLaadTextCtrl = new wxTextCtrl(achtergrondPaneel, ProgrammerLaadAdresID, wxEmptyString);
    veegUitKnop = new wxButton(achtergrondPaneel, ProgrammerEraseFlashID, _("Erase Flash"));
    haltButton = new wxButton(achtergrondPaneel, HaltTargetID, _("Halt target"));
    goButton = new wxButton(achtergrondPaneel, GoTargetID, _("Start target"));
    resetButton = new wxButton(achtergrondPaneel, ResetTargetID, _("Reset target"));
    statusBoom = new wxTreeCtrl(achtergrondPaneel, ProgrammerStatusBoomID, wxDefaultPosition, wxDefaultSize, wxBORDER_SUNKEN|wxTR_DEFAULT_STYLE|wxTR_FULL_ROW_HIGHLIGHT|wxTR_HAS_BUTTONS|wxTR_LINES_AT_ROOT|wxTR_NO_LINES);
    poortLabel = new wxStaticText(achtergrondPaneel, wxID_ANY, _("Port :"));
    gdbipPoortCtrl = new wxSpinCtrl(achtergrondPaneel, GDBIPPoortID, wxT("2331"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1024, 10000);
    gdbVerifyDownloadCheckBox = new wxCheckBox(achtergrondPaneel, GDBVerifyDownloadID, _("Verify Download"));
    gdbServerSilentCheckBox = new wxCheckBox(achtergrondPaneel, GDBServerSilentID, _("GDB server is silent"));
    gdbServerSingleRunCheckBox = new wxCheckBox(achtergrondPaneel, GDBServerSingleRunID, _("GDB Server does a single run"));
    debugKnop = new wxToggleButton(achtergrondPaneel, ProgrammerDebugID, _("Start GDB server"));
    gdbSwoKnop = new wxToggleButton(achtergrondPaneel, ProgrammerDebugSWOID, _("Start GDB SWO Client"));
    dddButton = new wxToggleButton(achtergrondPaneel, StartStopDDDFrontendID, _("Start DDD Frontend"));
    poortLabel_copy = new wxStaticText(achtergrondPaneel, wxID_ANY, _("Port :"));
    swoPoortCtrl = new wxSpinCtrl(achtergrondPaneel, SWOIPPoortID, wxT("2331"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1024, 10000);
    swoSpeedLabel = new wxStaticText(achtergrondPaneel, wxID_ANY, _("Speed :"));
    swoSpeedCtrl = new wxSpinCtrl(achtergrondPaneel, SWOSpeedID, wxT("1000"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 10, 6000);
    swoDimLabel = new wxStaticText(achtergrondPaneel, wxID_ANY, _("kHz"));
    swoButton = new wxToggleButton(achtergrondPaneel, ProgrammerSWOID, _("Start Listening"));
    swoCheckListBox = new wxCheckListBox(achtergrondPaneel, SWOChannelsID);
    sluitKnop = new wxButton(achtergrondPaneel, wxID_EXIT, wxEmptyString);

    set_properties();
    do_layout();
    // end wxGlade



    /* Stel de SWO kanalen in */
    wxArrayString swoMask;
	
    swoMask.Alloc(32);
    for (Teller i=0;i<32;i++)
        swoMask.Add(wxString::Format(wxT("Channel %d"),i));
    swoCheckListBox->Append(swoMask);
    for (Teller i=0;i<32;i++)
        swoCheckListBox->Check(i,CheckBit((UInt32)swoMaskBits,i));
					
    gdbipPoortCtrl->SetValue(debugPoort);
    gdbVerifyDownloadCheckBox->SetValue(gdbVerify);
    gdbServerSilentCheckBox->SetValue(gdbSilentRun);
    gdbServerSingleRunCheckBox->SetValue(gdbSingleRun);

    swoPoortCtrl->SetValue(swoPoort);
    swoSpeedCtrl->SetValue(swoFreq);	
    speedRadioBox->SetSelection((snelheid==JLINKARM_SPEED_AUTO) ? 0 : (snelheid==JLINKARM_SPEED_ADAPTIVE) ? 1 : 2);
	
    targetNameComboBox->Clear();
    for (Teller i=0;i<configLijst.GetCount();i++)
        targetNameComboBox->Append(configLijst[i].naam);

    /* stel knoppen in op het huidige target */
    zetKnoppen(configLijst[huidigTarget]);
    targetNameComboBox->SetSelection(huidigTarget);
	
    jlinkConnectionRadioBox->SetSelection(jlinkVerbinding);  /* voorlopig niet anders dan USB */

    log=wxLog::SetActiveTarget(new wxLogTextCtrl(statusTextCtrl));

    /* zet de text stijlen voor standaard en swo output */

    const wxTextAttr swoTextAttr(*wxBLUE,wxNullColour,*wxSMALL_FONT);
    swoTextCtrl->SetDefaultStyle(swoTextAttr);

    printGoed(_("J-Link ARM programmer tool."));
    wxLogMessage(_("Copyright SEGGER Microcontroller GmbH & Co. KG."));
    wxLogMessage(_("GUI wrapper Copyright E.J Boks, Hogeschool van Arnhem en Nijmegen, the Netherlands."));

    const bool seggerGedetecteerd = (seggerDirPad != seggerStandaardPad);

    wxMenuItem * const seggerAanwezigMenu = menubar->FindItem(ProgrammerSeggerDirID);
    seggerAanwezigMenu->Check(seggerGedetecteerd);

    if (false == seggerGedetecteerd)
    {
        printWaarschuwing(_("Please provide a path to the Segger J-Link directory. It must be set before you can use this tool."));
    }
   
    const bool armGedetecteerd = (armDirPad != armStandaardPad);

    wxMenuItem * const armAanwezigMenu = menubar->FindItem(ProgrammerARMDirID);
    armAanwezigMenu->Check(armGedetecteerd);

    if (false == armGedetecteerd)
    {	
        printWaarschuwing(_("Please provide a path to the ARM None EABI bin directory. It must be set before you can use this tool."));
    }
    else
    {
        printGoed(_("ARM EABI toolchain found (")+armDirPad+_(")"));
    }
	
#ifndef __WXMSW__
    const bool dddGedetecteerd = (dddPad != dddStandaardPad);
    wxMenuItem * const dddAanwezigMenu = menubar->FindItem(ProgrammerDDDFrontEndID);
    dddAanwezigMenu->Check(dddGedetecteerd);

    if (false == dddGedetecteerd)
    {	
        printWaarschuwing(_("Please find (and install) DDD through MacPorts. A debug session with DDD can be started once the location is known."));
    }
    else
        printGoed(_("DDD executable found (")+dddPad+_(")"));
#endif
	
    recenteBestandenMenu->Delete(ProgrammerDummyID);
    bestandGeschiedenis.UseMenu(recenteBestandenMenu);
    //   bestandGeschiedenis.Load(*appConfig);
#ifndef __WXMAC__
    bestandGeschiedenis.UseMenu(tbRecenteBestandenMenu);
#endif
    bestandGeschiedenis.Load(*appConfig);

    /* maak drag and drop aktief over de statusboom */
    statusBoom->SetDropTarget(new ProgrammeerDropTarget(this));



}

JLinkVensterKlasse::~JLinkVensterKlasse()
{
    wxGetApp().bewaarHoofdVensterGrootte();

    appConfig->SetPath(wxT("/Configuratie"));
	

    appConfig->Write(wxT("JLinkVerbindingInterface"),
                     jlinkConnectionRadioBox->GetSelection());

    appConfig->Write(wxT("SeggerDir"),seggerDirPad);
    appConfig->Write(wxT("ARMDir"),armDirPad);
    appConfig->Write(wxT("DDDpad"),dddPad);

    appConfig->Write(wxT("SWOBestandDir"),swoBestandPad);
    appConfig->Write(wxT("Favoriete Fabrikant"),favFabrikant);

    appConfig->Write(wxT("Snelheid"),snelheid);
    appConfig->Write(wxT("Niceness"),niceness);
    appConfig->Write(wxT("Debugpoort"),gdbipPoortCtrl->GetValue());
    appConfig->Write(wxT("GDBVerifyAan"),gdbVerifyDownloadCheckBox->IsChecked());
    appConfig->Write(wxT("GDBSingleRun"),gdbServerSingleRunCheckBox->IsChecked());
    appConfig->Write(wxT("GDBSilentRun"),gdbServerSilentCheckBox->IsChecked());

    appConfig->Write(wxT("SWOpoort"),swoPoortCtrl->GetValue());
    appConfig->Write(wxT("SWOFrequency"),swoSpeedCtrl->GetValue());

    const UInt32 swoMaskBits = leesSWOMaskBits();
    appConfig->Write(wxT("SWOMaskBits"),swoMaskBits);
	
    appConfig->SetPath(wxT("/Configuratie/Targets"));
    appConfig->Write(wxT("NumberOfTargets"),targetNameComboBox->GetCount());

	/* bewaar eerst het huidige target ook nog met de wijzigingen die in de GUI staan */
	configLijst[huidigTarget] = leesKnoppen();

    for (UInt32 i=0;i<configLijst.GetCount();i++)
    {
        const DeviceConfig device(configLijst[i]);
        appConfig->Write(wxString::Format(wxT("DebugTarget%d"),i),device.naam);
        appConfig->Write(wxString::Format(wxT("CPUFreq%d"),i),device.cpuFreq);
        appConfig->Write(wxString::Format(wxT("DebugInterface%d"),i),device.dbgIntf);
        appConfig->Write(wxString::Format(wxT("Endianess%d"),i),device.endianess);
        appConfig->Write(wxString::Format(wxT("BestandPad%d"),i),device.bestandPad);
        appConfig->Write(wxString::Format(wxT("FlashLaadAdres%d"),i),device.laadAdres);
        appConfig->Write(wxString::Format(wxT("GDBInitScript%d"),i),device.gdbInitScript);
        appConfig->Write(wxString::Format(wxT("SerNumberID%d"),i),device.jlinkSerialNumber);
    }
	


    appConfig->Write(wxT("CurrentTarget"),huidigTarget);

    bestandGeschiedenis.Save(*appConfig);

    /* ruim op */
    if ((DebugServerProcess *)Null != debugServer)
        delete debugServer;

    if ((DebuggerProcess *)Null != debugger)
        delete debugger;

    if ((SWOViewerProcess *)Null != swoViewer)
        delete swoViewer;

    delete log;

}


BEGIN_EVENT_TABLE(JLinkVensterKlasse, wxFrame)
     // begin wxGlade: JLinkVensterKlasse::event_table
     EVT_MENU(wxID_OPEN, JLinkVensterKlasse::openBestandHandler)
     EVT_MENU(wxID_SAVEAS, JLinkVensterKlasse::converteerBestandHandler)
     EVT_MENU(ProgrammerSchrijfFlashID, JLinkVensterKlasse::schrijfFlashHandler)
     EVT_MENU(ProgrammerEraseFlashID, JLinkVensterKlasse::eraseFlashHandler)
     EVT_MENU(wxID_ABOUT, JLinkVensterKlasse::overHandler)
     EVT_MENU(HANLogoID, JLinkVensterKlasse::hanWebsiteHandler)
     EVT_MENU(wxID_EXIT, JLinkVensterKlasse::eindeHandler)
     EVT_MENU(ProgrammerVerbindID, JLinkVensterKlasse::verbindMenuHandler)
     EVT_MENU(ProgrammerDebugID, JLinkVensterKlasse::startDebugHandler)
     EVT_MENU(ProgrammerSWOID, JLinkVensterKlasse::startSWOHandler)
     EVT_MENU(ProgrammerKopieerSWOID, JLinkVensterKlasse::copySWOHandler)
     EVT_MENU(wxID_SAVE, JLinkVensterKlasse::saveSWOHandler)
     EVT_MENU(wxID_DELETE, JLinkVensterKlasse::clearLogWindowsHandler)
     EVT_MENU(NicenessID, JLinkVensterKlasse::nicenessHandler)
     EVT_MENU(ProgrammerSeggerDirID, JLinkVensterKlasse::kiesSeggerDirHandler)
     EVT_MENU(ProgrammerARMDirID, JLinkVensterKlasse::kiesARMDirHandler)
     EVT_MENU(ProgrammerDDDFrontEndID, JLinkVensterKlasse::kiesDDDHandler)
     EVT_COMBOBOX(JLinkTargetNameID, JLinkVensterKlasse::targetWisselHandler)
     EVT_BUTTON(wxID_ADD, JLinkVensterKlasse::voegToeHandler)
     EVT_BUTTON(wxID_FIND, JLinkVensterKlasse::vindDeviceHandler)
     EVT_BUTTON(wxID_REMOVE, JLinkVensterKlasse::verwijderHandler)
     EVT_RADIOBOX(JLinkTargetSpeedID, JLinkVensterKlasse::speedSettingHandler)
     EVT_CHOICE(CPUFreqDimensieID, JLinkVensterKlasse::freqDimensieHandler)
     EVT_TOGGLEBUTTON(ProgrammerVerbindID, JLinkVensterKlasse::verbindHandler)
     EVT_BUTTON(ProgrammerSchrijfFlashID, JLinkVensterKlasse::schrijfFlashHandler)
     EVT_BUTTON(ProgrammerEraseFlashID, JLinkVensterKlasse::eraseFlashHandler)
     EVT_BUTTON(HaltTargetID, JLinkVensterKlasse::haltTargetHandler)
     EVT_BUTTON(GoTargetID, JLinkVensterKlasse::restartTargetHandler)
     EVT_BUTTON(ResetTargetID, JLinkVensterKlasse::resetTargetHandler)
     EVT_TOGGLEBUTTON(ProgrammerDebugID, JLinkVensterKlasse::startDebugHandler)
     EVT_TOGGLEBUTTON(ProgrammerDebugSWOID, JLinkVensterKlasse::startGDBSwoHandler)
     EVT_TOGGLEBUTTON(StartStopDDDFrontendID, JLinkVensterKlasse::startStopDDDHandler)
     EVT_TOGGLEBUTTON(ProgrammerSWOID, JLinkVensterKlasse::startSWOHandler)
     EVT_BUTTON(wxID_EXIT, JLinkVensterKlasse::eindeHandler)
     // end wxGlade

EVT_END_PROCESS(JLinkDebugServerEventID, JLinkVensterKlasse::onGDBServerProcessTerm)
EVT_END_PROCESS(DebuggerEventID, JLinkVensterKlasse::onDDDProcessTerm)
EVT_END_PROCESS(JLinkSWOViewerEventID, JLinkVensterKlasse::onSWOProcessTerm)
EVT_SOCKET(GDBSWOSocketID,JLinkVensterKlasse::gdbSwoSocketHandler)
EVT_FILEPICKER_CHANGED(wxID_OPEN,JLinkVensterKlasse::bestandGekozenHandler)
EVT_FILEPICKER_CHANGED(wxID_OPEN,JLinkVensterKlasse::gdbInitScriptGekozenHandler)
EVT_TIMER(ExtProcessPollingTimerID,JLinkVensterKlasse::extProcessTimerPollingEventHandler)
EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, JLinkVensterKlasse::oudBestandLadenHandler)

EVT_UPDATE_UI(wxID_ADD, JLinkVensterKlasse::magDeviceToevoegenHandler)
EVT_UPDATE_UI(wxID_REMOVE, JLinkVensterKlasse::magDeviceVerwijderenHandler)

//EVT_UPDATE_UI(ProgrammerRecentFlashFileID, JLinkVensterKlasse::connectKnopAktiefHandler)
//EVT_UPDATE_UI(wxID_OPEN, JLinkVensterKlasse::connectKnopAktiefHandler)
//EVT_UPDATE_UI(ProgrammerLaadAdresID, JLinkVensterKlasse::connectKnopAktiefHandler)
EVT_UPDATE_UI(ProgrammerSchrijfFlashID, JLinkVensterKlasse::connectKnopAktiefHandler)
EVT_UPDATE_UI(ProgrammerCheckFlashID, JLinkVensterKlasse::connectKnopAktiefHandler)
EVT_UPDATE_UI(ResetTargetID, JLinkVensterKlasse::connectKnopAktiefHandler)
EVT_UPDATE_UI(HaltTargetID, JLinkVensterKlasse::connectKnopAktiefHandler)
EVT_UPDATE_UI(GoTargetID, JLinkVensterKlasse::connectKnopAktiefHandler)
EVT_UPDATE_UI(ProgrammerEraseFlashID, JLinkVensterKlasse::connectKnopAktiefHandler)

EVT_UPDATE_UI(wxID_FIND, JLinkVensterKlasse::knopMagAanHandler)
EVT_UPDATE_UI(wxID_DELETE, JLinkVensterKlasse::knopMagAanHandler)
EVT_UPDATE_UI(wxID_EXIT, JLinkVensterKlasse::knopMagAanHandler)
EVT_UPDATE_UI(ProgrammerOpKeuzeID, JLinkVensterKlasse::knopMagAanHandler)
EVT_UPDATE_UI(ProgrammerSeggerDirID, JLinkVensterKlasse::knopMagAanHandler)
EVT_UPDATE_UI(ProgrammerARMDirID, JLinkVensterKlasse::knopMagAanHandler)
EVT_UPDATE_UI(JLinkInterfaceKeuzeID, JLinkVensterKlasse::knopMagAanHandler)
EVT_UPDATE_UI(TargetEndianessKeuzeID, JLinkVensterKlasse::knopMagAanHandler)
EVT_UPDATE_UI(JLinkTargetNameID, JLinkVensterKlasse::knopMagAanHandler)
EVT_UPDATE_UI(CPUFreqSpinCtrl, JLinkVensterKlasse::knopMagAanHandler)
EVT_UPDATE_UI(CPUFreqDimensieID, JLinkVensterKlasse::knopMagAanHandler)
EVT_UPDATE_UI(JLinkTargetSpeedID, JLinkVensterKlasse::knopMagAanHandler)

EVT_UPDATE_UI(NicenessID,JLinkVensterKlasse::nicenessUpdateHandler)
EVT_UPDATE_UI(ProgrammerDDDFrontEndID,JLinkVensterKlasse::nicenessUpdateHandler)
EVT_UPDATE_UI(GDBScriptID,JLinkVensterKlasse::nicenessUpdateHandler)
EVT_UPDATE_UI(ProgrammerDebugID, JLinkVensterKlasse::debugStandHandler)	
EVT_UPDATE_UI(GDBIPPoortID, JLinkVensterKlasse::debugStandHandler)	
EVT_UPDATE_UI(GDBVerifyDownloadID, JLinkVensterKlasse::debugStandHandler)
EVT_UPDATE_UI(GDBServerSilentID, JLinkVensterKlasse::debugStandHandler)
EVT_UPDATE_UI(GDBServerSingleRunID, JLinkVensterKlasse::debugStandHandler)

EVT_UPDATE_UI(StartStopDDDFrontendID, JLinkVensterKlasse::dddStandHandler)

EVT_UPDATE_UI(ProgrammerDebugSWOID, JLinkVensterKlasse::debugSWOStandHandler)	
EVT_UPDATE_UI(ProgrammerKopieerSWOID, JLinkVensterKlasse::debugStandHandler)	
EVT_UPDATE_UI(wxID_SAVE, JLinkVensterKlasse::debugStandHandler)	

EVT_UPDATE_UI(ProgrammerVerbindID, JLinkVensterKlasse::connectStandHandler)	
EVT_UPDATE_UI(ProgrammerStatusveldID, JLinkVensterKlasse::gdbServerSTDIOHandler)
EVT_UPDATE_UI(ProgrammerSWOveldID,  JLinkVensterKlasse::swoServerSTDIOHandler)


EVT_UPDATE_UI(SWOIPPoortID,JLinkVensterKlasse::swoStandHandler)
EVT_UPDATE_UI(ProgrammerSWOveldID,JLinkVensterKlasse::swoStandHandler)
EVT_UPDATE_UI(ProgrammerSWOID,JLinkVensterKlasse::swdStandHandler)
EVT_UPDATE_UI(SWOChannelsID,JLinkVensterKlasse::swoStandHandler)
EVT_UPDATE_UI(SWOSpeedID,JLinkVensterKlasse::swoStandHandler)

END_EVENT_TABLE();

void JLinkVensterKlasse::zetKnoppen(const DeviceConfig &device)
{
    const Teller deler[] = { 1,1000,1000000 };
    const Teller freq = device.cpuFreq/deler[freqDimensieChoice->GetSelection()];
 
    cpuFreqSpinCtrl->SetValue(freq);
    interfaceKeuzeChoice->SetSelection(device.dbgIntf);
    endiannessChoice->SetSelection(device.endianess);
    const wxFileName bestand(device.bestandPad);
//    wxLogDebug(wxT("bestandpad=")+bestandPad);
    openKnop->SetInitialDirectory(bestand.GetPath());
    openKnop->SetFileName(bestand);
	openKnop->SetToolTip(bestand.GetFullPath());
    USBSerialTextCtrl->SetValue(wxString::Format(wxT("%d"),device.jlinkSerialNumber));
    flashLaadTextCtrl->SetValue(wxString::Format(wxT("0x%x"),device.laadAdres));

    const wxFileName gdbInitScript(device.gdbInitScript);
    wxLogDebug(wxT("gdbinitscript=")+gdbInitScript.GetFullPath());
    gdbScriptOpenPickerCtrl->SetInitialDirectory(gdbInitScript.GetPath());
    gdbScriptOpenPickerCtrl->SetFileName(gdbInitScript);

}

DeviceConfig JLinkVensterKlasse::leesKnoppen() const
{
    const Teller deler[] = { 1,1000,1000000 };
    const Teller freq = cpuFreqSpinCtrl->GetValue()*
                        deler[freqDimensieChoice->GetSelection()];

    /* sla de huidige keuze op */
    const DeviceConfig device(configLijst[huidigTarget].naam,
                              freq,
                              interfaceKeuzeChoice->GetSelection(),
                              endiannessChoice->GetSelection(),
                              leesLaadAdres(),
                              gdbScriptOpenPickerCtrl->GetPath(),
                              leesUSBSerialID(),
                              openKnop->GetPath());

    return(device);
}

/* cortex core ids */
// TODO clean this up...
#define STM32VL_CORE_ID 0x1ba01477
#define STM32L1_CORE_ID 0x2ba01477
#define STM32F3_CORE_ID 0x2ba01477
#define STM32F4_CORE_ID 0x2ba01477
#define STM32F0_CORE_ID 0xbb11477
#define STM32L0_CORE_ID 0x0bc11477

#define CORE_M3_R1 0x1BA00477
#define CORE_M3_R2 0x4BA00477
#define CORE_M4_R0 0x2BA01477

/*
 * Chip IDs are explained in the appropriate programming manual for the
 * DBGMCU_IDCODE register (0xE0042000)
 */
// stm32 chipids, only lower 12 bits..
#define STM32_CHIPID_F05 0x440
#define STM32_CHIPID_F07 0x448
#define STM32_CHIPID_F1_MEDIUM 0x410
#define STM32_CHIPID_F2 0x411
#define STM32_CHIPID_F1_LOW 0x412
#define STM32_CHIPID_F3 0x422
#define STM32_CHIPID_F37x 0x432
#define STM32_CHIPID_F41 0x413
#define STM32_CHIPID_F42 0x419
#define STM32_CHIPID_F1_HIGH 0x414
#define STM32_CHIPID_L0x3 0x417
#define STM32_CHIPID_L1_MEDIUM 0x416
#define STM32_CHIPID_L1_MEDIUM_PLUS 0x436
#define STM32_CHIPID_L1_HIGH 0x436
#define STM32_CHIPID_F1_CONN 0x418
#define STM32_CHIPID_F1_VL_MEDIUM 0x420
#define STM32_CHIPID_F1_VL_HIGH 0x428
#define STM32_CHIPID_F1_XL 0x430

void JLinkVensterKlasse::stm32DeviceIDInit()
{
	stm32Devices[STM32_CHIPID_F05] = wxT("STM32 F05x entry Level Cortex-M0");
	stm32Devices[STM32_CHIPID_F07] = wxT("STM32 F07x entry Level Cortex-M0");

	stm32Devices[STM32_CHIPID_F1_LOW] = wxT("STM32 F1 Low Density");
	stm32Devices[STM32_CHIPID_F1_MEDIUM] = wxT("STM32 F1 Medium Density");
	stm32Devices[STM32_CHIPID_F1_HIGH] = wxT("STM32 F1 High Density");
	stm32Devices[STM32_CHIPID_F1_VL_HIGH] = wxT("STM32 F1 Very Large High Density Cortex-M3");
	stm32Devices[STM32_CHIPID_F1_CONN] = wxT("STM32 F1 Connectivity Line Cortex-M3");
	stm32Devices[STM32_CHIPID_F1_VL_MEDIUM] = wxT("STM32 F1 Very Large Medium Density Cortex-M3");
	stm32Devices[STM32_CHIPID_F1_VL_HIGH] = wxT("STM32 F1 Very Large High Density Cortex-M3");
        
	stm32Devices[STM32_CHIPID_F2] = wxT("STM32 F2 High Performance Cortex-M3");

	stm32Devices[STM32_CHIPID_F3] = wxT("STM32 F30x Mixed Signal Cortex-M4");
	stm32Devices[STM32_CHIPID_F37x] = wxT("STM32 F37x Mixed Signal Cortex-M4");
	stm32Devices[STM32_CHIPID_F41] = wxT("STM32 F40/1x High Performance Cortex-M4");
	stm32Devices[STM32_CHIPID_F42] = wxT("STM32 F42/3x High Performance Cortex-M4");

        stm32Devices[STM32_CHIPID_L0x3] =  wxT("STM32 L0 Ultra Low Power Cortex-M0+");

	stm32Devices[STM32_CHIPID_L1_MEDIUM] = wxT("STM32 L1 Low Power Medium Density Cortex-M3");
	stm32Devices[STM32_CHIPID_L1_MEDIUM_PLUS] = wxT("STM32 L1 Low Power Medium Plus Density Cortex-M3");
	stm32Devices[STM32_CHIPID_L1_HIGH] = wxT("STM32 L1 Low Power High Density Cortex-M3");

	stm32UniqueIDs[STM32_CHIPID_F05] = 0x1ffff7ac;
	stm32UniqueIDs[STM32_CHIPID_F07] = 0x1ffff7ac;

	stm32UniqueIDs[STM32_CHIPID_F1_LOW] = 0x1ffff7e0;
	stm32UniqueIDs[STM32_CHIPID_F1_MEDIUM] =  0x1ffff7e0;
	stm32UniqueIDs[STM32_CHIPID_F1_HIGH] =  0x1ffff7e0;
	stm32UniqueIDs[STM32_CHIPID_F1_VL_HIGH] =  0x1ffff7e0;
	stm32UniqueIDs[STM32_CHIPID_F1_CONN] = 0x1ffff7e0;
	stm32UniqueIDs[STM32_CHIPID_F1_VL_MEDIUM] = 0x1ffff7e0;
	stm32UniqueIDs[STM32_CHIPID_F1_VL_HIGH] = 0x1ffff7e0;

	stm32UniqueIDs[STM32_CHIPID_F2] = 0x1fff7a10;

	stm32UniqueIDs[STM32_CHIPID_F3] = 0x1ffff7ac; 
	stm32UniqueIDs[STM32_CHIPID_F37x] =  0x1ffff7ac; 

	stm32UniqueIDs[STM32_CHIPID_F41] = 0x1fff7a10;
	stm32UniqueIDs[STM32_CHIPID_F42] = 0x1fff7a10;

        stm32UniqueIDs[STM32_CHIPID_L0x3] = 0x1ff80050;

	stm32UniqueIDs[STM32_CHIPID_L1_MEDIUM] =  0x1ffff7e0;
	stm32UniqueIDs[STM32_CHIPID_L1_MEDIUM_PLUS] = 0x1ffff7e0;
	stm32UniqueIDs[STM32_CHIPID_L1_HIGH] = 0x1ffff7e0;

}

//
// Make sure SWD is ready for a start bit
//
const UInt8 JLinkVensterKlasse::aDir[33] = { 255, 255, 255, 255, 255, 255, 255, 255, 255,
                                             255, 255, 255, 255, 255, 255, 255, 255, 255,
                                             255, 255, 255, 255, 255, 255, 255, 255, 255,
                                             0xFF, 0, 0, 0, 0, 0xF0 // Read Id Register
};
//
// Make sure SWD is ready for a start bit
//
const UInt8 JLinkVensterKlasse::aIn[33] = { 255, 255, 255, 255, 255, 255, 255, 0x9E, 0xE7,
                                            255, 255, 255, 255, 255, 255, 255, 0xB6, 0xED,
                                            255, 255, 255, 255, 255, 255, 255, 0, 0,
                                            0xA5, 0, 0, 0, 0, 0 // Read Id Register
};

UInt32 JLinkVensterKlasse::leesUSBSerialID() const
{
    const wxString veld(USBSerialTextCtrl->GetValue());
    long unsigned int getal;
    if (false == veld.ToULong(&getal))
    {
        wxLogError(wxT("USB Serial ID field is not a number."));
        USBSerialTextCtrl->SetValue(wxT("0"));
        return(0);
    }
    else
        return(getal);
}

UInt32 JLinkVensterKlasse::leesLaadAdres() const
{
    const wxString adresTekst(flashLaadTextCtrl->GetValue());  
	
    long unsigned int adres;
    const bool resultaat = adresTekst.ToULong(&adres,16);
    wxASSERT(true == resultaat);
    if (false == resultaat)
    {
        statusTextCtrl->SetDefaultStyle(fouteStatusTextAttr);
        wxLogError(_("Could not convert field value ")+adresTekst+_(" to hexadecimal load address."));
        return(0);
    }
    else return(adres);
}

UInt32 JLinkVensterKlasse::leesSWOMaskBits() const
{
    UInt32 swoMaskBits=0;

    for (Teller i=0;i<32;i++)
        EnterBit(swoMaskBits,i,(swoCheckListBox->IsChecked(i)));

	
    return(swoMaskBits);
}


void JLinkVensterKlasse::speedSettingHandler(wxCommandEvent &event)
{
    switch(speedRadioBox->GetSelection())
    {
        case 0:
            snelheid = JLINKARM_SPEED_AUTO;
            break;
        case 1:
            snelheid = JLINKARM_SPEED_ADAPTIVE;
            break;
        case 2:
        {
            const UInt16 setwaarde = (((snelheid == JLINKARM_SPEED_AUTO) || (snelheid = JLINKARM_SPEED_ADAPTIVE)) ? 1000 : snelheid);
            wxNumberEntryDialog dialoog(this,
                                        _("Please select the value at which J-Link will communicate with the target"),
                                        _("speed (5-12000) in kHz"),
                                        _("J-Link speed selection dialogue"),
                                        setwaarde,5,12000);
			
            if (wxID_OK == dialoog.ShowModal())
                snelheid = dialoog.GetValue();
            else
            {
                snelheid=JLINKARM_SPEED_AUTO;
                speedRadioBox->SetSelection(0);  /* terug naar auto */
            }
        }
        break;
			
        default:
        {
            printFout(_("Unknown speed selection value"));
            wxFAIL_MSG(wxT("Unknown speed selection value"));
        }
        break;
    }
}

void JLinkVensterKlasse::verbindMenuHandler(wxCommandEvent &event)
{
	verbindKnop->SetValue((true == verbindKnop->GetValue()) ? false : true);
	verbindHandler(event);
}

void JLinkVensterKlasse::verbindHandler(wxCommandEvent &event)
{
    if (true == verbindKnop->GetValue())
    {
        /* kijk naar fouten */
        if (0 != JLINKARM_HasError())
            JLINKARM_ClrError();

        /* sluit eerst oude interface, indien aanwezig */
        if ((1 == JLINKARM_IsConnected()) || (1 == JLINKARM_IsOpen()))
            JLINKARM_Close();

        if (0 != jlinkConnectionRadioBox->GetSelection())
        {
            printGoed(_("Ethernet connection procedure initiated"));

            JLINKARM_EMU_SelectIPBySN(leesUSBSerialID());

            if (0 == JLINKARM_EMU_IsConnected())
            {
                printFout(wxString::Format(_("No Ethernet J-Link unit with serial number %d number present on the network."),leesUSBSerialID()));
                verbindKnop->SetValue(false);
                verbindKnop->SetLabel(_("Connect"));
            } 
            else
                verbind();

        }
        else
        {
            printGoed(_("USB connection procedure initiated"));

 
            if (0 > JLINKARM_EMU_SelectByUSBSN(leesUSBSerialID()))
            {
                printFout(wxString::Format(_("No USB J-Link unit with serial number %d number present on USB bus."),leesUSBSerialID()));
                verbindKnop->SetValue(false);
                verbindKnop->SetLabel(_("Connect"));
            }
            else
                verbind();
        }

    }
    else
    {
        JLINKARM_Close();

        verbindKnop->SetLabel(_("Connect"));
        printGoed(_("Connection terminated"));
        statusbar->SetStatusText(_("Disconnected from JLink target"));
        statusBoom->DeleteAllItems();
    }


}

void JLinkVensterKlasse::verbind()
{

    const char *errtekst = JLINKARM_Open();

    if ((char *)NULL != errtekst)
    {                
 
        if ((char *)NULL != errtekst)
            printFout(_("Error opening connection to J-Link and the target.\nThe error message is \"")+
                      wxString(errtekst)+wxString(wxT("\"")));
 
        verbindKnop->SetValue(false);
        verbindKnop->SetLabel(_("Connect"));
        printFout(_("Connection setup error"));
        statusbar->SetStatusText(_("JLink target connection wasn't established."));
        JLINKARM_ClrError();
        JLINKARM_Close();
    }
    else /* verbonden met JLink. Controleer JTAG of SWD  */
    {					
        if (0 == interfaceKeuzeChoice->GetSelection()) /* JTAG */
        {
            const int retconnect = JLINKARM_Connect();		
            if (0 != retconnect)
            {
                printFout(_("NO JTAG connection logic present on the target"));
                verbindKnop->SetValue(false);
                verbindKnop->SetLabel(_("Connect"));
                verbindKnop->SetValue(false);
                statusbar->SetStatusText(_("NO JTAG interface present."));
                JLINKARM_Close();
                return;
            }
        }
        else  /* SWD */
        {
            unsigned int Mask;
            JLINKARM_TIF_GetAvailable(&Mask);
            if ((false == CheckBit(Mask,JLINKARM_TIF_SWD)) ||
                (0 != JLINKARM_TIF_Select(JLINKARM_TIF_SWD)))
            {
                printFout(_("No SWD interface logic is present on target."));	
                verbindKnop->SetValue(false);
                verbindKnop->SetLabel(_("Connect"));
                verbindKnop->SetValue(false);
                statusbar->SetStatusText(_("NO SWD interface present."));
                JLINKARM_Close();
                return;
            }						
        }
			
        JLINKARM_SetInitRegsOnReset(0);		
        verbindKnop->SetLabel(_("Disconnect"));
        statusbar->SetStatusText(_("Connected to JLink target"));
					
        /* zet het device */
        const wxString targetNaam(targetNameComboBox->GetValue());
        const wxString deviceCommando(wxT("device=")+targetNaam);
                    
        if (false == JLinkExecCmd(deviceCommando))  /* het ging fout */
        {
            printFout(_("Selecting \"") +targetNaam+_("\" as target was not successfull."));
            JLINKARM_Close();
            return;
        }
        else
        {
            getSetMaxSpeed();  /* zet max snelheid */
						
            if (false == JLinkExecCmd(wxT("Map Reset")))  /* het ging fout */
            {
                printFout(_("Memory Map Reset on \"") +targetNaam+_("\" was not successfull."));
                JLINKARM_Close();
                return;
            }
            else
            {
                showDLLInfo();
                showFirmwareInfo();
							
                wxTreeItemId wortel = statusBoom->AddRoot(_("ARM processor"));
                const UInt32 chipid = JLINKARM_GetId();
							
                const UInt32 core = JLINKARM_CORE_GetFound();
                printGoed(wxString::Format(_("ARM Core ID 0x%.8x"),core));
							
                char acBuffer[50];
							
                JLINKARM_Core2CoreName(core, acBuffer, sizeof(acBuffer));
							
                const wxString coreNaam(_("Core Type : ")+acBuffer);
							
                JLINKARM_HW_STATUS Stat;
							
                const wxString spanning( ((JLINKARM_GetHWStatus(&Stat) == 0) ? 
                                          wxString::Format(wxT("VTarget : %d.%.3dV\n"), 
                                                           Stat.VTarget / 1000, 
                                                           Stat.VTarget % 1000) :
                                          _("Unknown target voltage")));

                const wxString chipidtekst(wxString::Format(wxT("Chip ID : 0x%08x"),chipid));
		printGoed(wxString::Format(_("ARM Chip ID 0x%.8x"),chipid));
                
                unsigned int uniqueid,stm32id;
                
                const UInt32 DBGMCU_IDCODE = (((chipid == STM32F0_CORE_ID) ||
                                               chipid == STM32L0_CORE_ID) ? 0x40015800 :  0xe0042000);
                JLINKARM_ReadMemU32(DBGMCU_IDCODE,1,&stm32id,NULL);
                stm32id &= 0xfff;
 
                statusBoom->AppendItem(wortel,chipidtekst);
                statusBoom->AppendItem(wortel,coreNaam);
					
                const wxString procNaam(stm32Devices[stm32id]);
                const UInt32 unAdres = stm32UniqueIDs[stm32id];

                if (0 == unAdres)
                    statusBoom->AppendItem(wortel,wxT("Unknown ARM device."));
                else
                {     
                    JLINKARM_ReadMemU32(unAdres,1,&uniqueid,NULL);
                    const wxString unTekst(wxString::Format(_("Unique ID:  0x%.8x"),uniqueid));
								
                    statusBoom->AppendItem(wortel,procNaam);
                    //procNaam);                
                    statusBoom->AppendItem(wortel,unTekst);
                    printGoed(wxString::Format(_("STM32 dev reg (0xe0042000) =  0x%.8x"),stm32id));
                }
							
                /* wxTreeItemId spanningtak = */
                statusBoom->AppendItem(wortel,spanning);
                statusBoom->ExpandAll();
            }
        }
    }
}
 

void JLinkVensterKlasse::laadAdresHandler(wxCommandEvent &event)
{
    leesLaadAdres();   /* voor test op getal */
}

void JLinkVensterKlasse::bestandGekozenHandler(wxFileDirPickerEvent &event)
{
    const DeviceConfig conf(leesKnoppen());

    configLijst[huidigTarget] = conf;

    bestandGeschiedenisUpdater();
}

void JLinkVensterKlasse::gdbInitScriptGekozenHandler(wxFileDirPickerEvent &event)
{
    const DeviceConfig conf(leesKnoppen());

    configLijst[huidigTarget] = conf;
}


void JLinkVensterKlasse::openBestandHandler(wxCommandEvent &event)
{
    wxFileName bestand(openKnop->GetPath());

    const wxString extensie(wxT("ELF files(*.elf)|*.elf|HEX files(*.hex)|*.hex|BIN files (*.bin)|*.bin"));

    wxFileDialog openDialoog(this,
                             _("Please select an ARM elf/hex/bin file."),
                             bestand.GetPath(),
                             bestand.GetName(),
                             extensie,
                             wxFD_OPEN|wxFD_FILE_MUST_EXIST);

    if (wxID_OK == openDialoog.ShowModal())
    {
        openKnop->SetPath(openDialoog.GetPath());
        openKnop->SetToolTip(openDialoog.GetPath());
        bestandGeschiedenisUpdater();
    }
}

void JLinkVensterKlasse::converteerBestandHandler(wxCommandEvent &event)
{
    const wxString extensie(wxT("ELF files(*.elf)|*.elf|HEX files(*.hex)|*.hex|BIN files (*.bin)|*.bin"));
	wxFileName bestand(openKnop->GetPath());

	wxFileDialog openDialoog(this,
                             _("Please select the ARM elf/hex/bin file to be converted."),
                             bestand.GetPath(),
                             bestand.GetName(),
                             extensie,
                             wxFD_OPEN|wxFD_FILE_MUST_EXIST);

    if (wxID_OK == openDialoog.ShowModal())
    {

    wxFileDialog saveDialoog(this,
                             _("Please enter the new filename and extension."),
                             bestand.GetPath(),
                             bestand.GetName(),
                             extensie,
                             wxFD_SAVE);

    if (wxID_OK == saveDialoog.ShowModal())
    {
		const wxFileName oud(openDialoog.GetPath());
		const wxFileName nieuw(saveDialoog.GetPath());

		if (Ok == converteerBestand(oud,nieuw))
			printGoed(_("The conversion from ")+oud.GetFullName()+_(" to ")+nieuw.GetFullName()+_(" was executed succesfully"));
		else
			printFout(_("The conversion from ")+oud.GetFullName()+_(" to ")+nieuw.GetFullName()+_(" did not proceed without errors. Aborted."));
	}
	}
}

FoutCode JLinkVensterKlasse::converteerBestand(const wxFileName &bronBestand,
                                               const wxFileName &bestBestand) const
{
    wxString bronext(bronBestand.GetExt());
    const wxString bestext(bestBestand.GetExt());

    WX_DECLARE_STRING_HASH_MAP( wxString, wxObjCopyHashMap );

    wxObjCopyHashMap objCopyBestandCommando;

    /* zet de array met de objcopy bestandtypen */
    objCopyBestandCommando[wxT("elf")] = wxT("elf32-little ");
    objCopyBestandCommando[wxT("bin")]= wxT("binary ");
    objCopyBestandCommando[wxT("hex")]= wxT("ihex ");


    if ((objCopyBestandCommando.end() == objCopyBestandCommando.find(bronext)) ||
        (objCopyBestandCommando.end() == objCopyBestandCommando.find(bestext)))
    {
        printFout(_("Only ELF, HEX or BIN files can be converted to each other."));
        return(Fout);
    }
    else
    {

        /* converteer indien de typen verschillend zijn ,anders een gewone kopieeraktie */
        if (true == bronext.IsSameAs(bestext))
        {
            wxCopyFile(bronBestand.GetFullPath(),bestBestand.GetFullPath());
            return(Ok);
        }
        else
        {

            const wxString prog(wxT(" -I ") + objCopyBestandCommando[bronext] + wxT(" -O ")  + objCopyBestandCommando[bestext] +
                                bronBestand.GetFullPath() + wxT(" ") + bestBestand.GetFullPath());

            const wxString objCopyPad(armDirPad+wxT("/bin/arm-none-eabi-objcopy"));
            const wxString cmd(objCopyPad+prog);
            wxLogDebug(wxT("ARM objcopy commando = ")+cmd);

            const long int resultaat = wxExecute(cmd,(wxEXEC_SYNC));
		
            if (-1 == resultaat)
            {
                printFout(_("ARM EABI objcopy process (\"")+cmd+_("\") could not be started. Please check the path."));
                return(Fout);
            }
            else
            {
                printGoed(bronBestand.GetFullName()+_(" was converted to " +bestext+_(" format.")));
                return(Ok);
            }
        }
    }
}

void JLinkVensterKlasse::bestandGeschiedenisUpdater()
{
    /* bestandgeschiedenis bijwerken */
    const wxString nieuwBestand(openKnop->GetPath());

    /* verwijder het oudste bestand uit de lijst als de lijst vol zit */
    if (bestandGeschiedenis.GetCount() == (Teller) bestandGeschiedenis.GetMaxFiles())
        bestandGeschiedenis.RemoveFileFromHistory(bestandGeschiedenis.GetMaxFiles()-1);

    /* voeg de laatste toe indien niet aanwezig */
    bool bestaatAl=false;
    for (Teller i=0;i<bestandGeschiedenis.GetCount();i++)
    {
        if (true == nieuwBestand.IsSameAs(bestandGeschiedenis.GetHistoryFile(i)))
        {
            bestaatAl=true;
            break;
        }
    }

    if (false == bestaatAl)
        bestandGeschiedenis.AddFileToHistory(nieuwBestand);
}
void JLinkVensterKlasse::clearLogWindowsHandler(wxCommandEvent &event)
{
    statusTextCtrl->Clear();
    swoTextCtrl->Clear();

}


void JLinkVensterKlasse::copySWOHandler(wxCommandEvent &event)
{

    if (false == wxTheClipboard->Open())
        printFout(_("Cannot open the clipboard"));
    else
    {
        wxTextDataObject * const kopieerObjekt = new wxTextDataObject(swoTextCtrl->GetValue());
        wxTheClipboard->SetData(kopieerObjekt);
        wxTheClipboard->Close();
		printGoed(_("ITM Trace output copied to the copy buffer."));
    }
   
}

void JLinkVensterKlasse::saveSWOHandler(wxCommandEvent &event)
{
    wxFileName swobestand(swoBestandPad);

    const wxString extensie(wxT("Text files (*.txt)|*.txt"));

    wxFileDialog saveDialoog(this,
                             _("Please enter the name of the file for saving the SWO output to"),
                             swobestand.GetPath(),
                             wxEmptyString,
                             extensie,
                             wxFD_SAVE|wxFD_OVERWRITE_PROMPT);

    if (wxID_OK == saveDialoog.ShowModal())
    {
        swoTextCtrl->SaveFile(swoBestandPad = saveDialoog.GetPath());
    }
}


bool JLinkVensterKlasse::verbonden() const
{
    return(true == verbindKnop->GetValue());
}

void JLinkVensterKlasse::schrijfFlashHandler(wxCommandEvent &event)
{
    const wxFileName bestand(openKnop->GetPath());

    if (false == bestand.FileExists())
    {
        printFout(_("File ")+bestand.GetFullPath()+_(" does not exist. Writing flash was cancelled."));
    }
    else
        schrijfFlash(bestand);
}

bool JLinkVensterKlasse::schrijfFlash(const wxFileName &bestand)
{
        bool retCode=true;

		wxFileName convBestand;
		convBestand.AssignTempFileName(wxT("JLinkProgrammer"));  /* maak tijdelijk bestand aan om bin in op te slaan */
		convBestand.SetExt(wxT("bin"));

		if (Ok != converteerBestand(bestand,convBestand))
			retCode = false;
		else
		{
	        wxLogDebug(wxT("convbestand = ")+convBestand.GetFullPath());

        wxFileInputStream instroom(convBestand.GetFullPath());
        do
        {

        } while (false == instroom.IsOk());

        const UInt32 grootte = instroom.GetSize();
        UInt8 * const dataruimte = new UInt8[grootte]; // laadgrootte];

        haltTarget();

        JLINKARM_BeginDownload(0); // Indicates start of flash download

        instroom.ReadAll(dataruimte,grootte);
        const Int32 controleaantal =JLINKARM_WriteMem(leesLaadAdres(), 
                                                      grootte, 
                                                      dataruimte);

        const Int32 eindcontrole=JLINKARM_EndDownload(); // Indicates end of flash download. DLL will
 
        switch(eindcontrole)
        {
            case -1:
                printFout(_("Segger JLink generic error."));
                statusbar->SetStatusText(_("Flash write error"));
                retCode=false;
                break;
            case -2:
                printFout(_("Error during compare phase (checking if flash content already matches the programming data)"));
                statusbar->SetStatusText(_("Flash write error"));
                retCode=false;
                break;
            case -3:
                printFout(_("Error during program/erase phase"));
                statusbar->SetStatusText(_("Flash write error"));
                retCode=false;
                break;
            case -4:
                printFout(_("Error during verification phase."));
                statusbar->SetStatusText(_("Flash write error"));
                retCode=false;
                break;
            default:
            {
                if (-1 != controleaantal)
                    printGoed(bestand.GetFullName()+wxString::Format(_(" (size = %.2f KBytes) was written to flash successfully."),(grootte/1024.0)));
                else
                    printFout(bestand.GetFullName()+wxString::Format(_(" (size = %.2f KBytes) was written to flash with error code -1."),(grootte/1024.0)));
                
                wxLogMessage(_("Flash write cycle exitcodes : (%d,%d)"),controleaantal,eindcontrole);
                statusbar->SetStatusText(_("Flash written"));
            }
            break;
        }

        delete[] dataruimte;
		}
        return(retCode);
}


void JLinkVensterKlasse::eraseFlashHandler(wxCommandEvent &event)
{
    wxBusyInfo wacht(_("Busy mass erasing flash"),this);

    JLINKARM_DEVICE_INFO DeviceInfo;

    U8                   EraseValue=0xff;
    Int32                  d;
    U32                  i;

    //
    // Get Flash Areas from Device Config
    //
    d = JLINKARM_DEVICE_GetIndex(NULL);
    //
    // Check if everything is O.K.
    //
    if(d == -1) 
    {
        printFout(_("Please select a device with \"device <DeviceName>\" before using this command."));
        return;
    }
    if(JLINKARM_IsHalted() == 0) {
        JLINKARM_Halt();
    }

    DeviceInfo.SizeOfStruct = sizeof(JLINKARM_DEVICE_INFO);
    JLINKARM_DEVICE_GetInfo(d, &DeviceInfo);
    //
    // For each Flash area, 
    // fill an array with erase value (FF) 
    // and write it
    //
    i = 0;
    printGoed(wxString::Format(_("Erasing device (%s)..."), DeviceInfo.sName));
    JLINKARM_BeginDownload(0);
    do {
        if (DeviceInfo.aFlashArea[i].Size == 0) {
            break;
        }
        if (i == COUNTOF(DeviceInfo.aFlashArea)) 
        {
            printWaarschuwing(_("maximum number of flash ranges (32) reached."));
        }
        //
        // Allocate and fill Databuffer with erase value
        //
        U8 * pFillData = new U8[DeviceInfo.aFlashArea[i].Size];
        if (pFillData == NULL) 
        {
            printFout(_("Failed to allocate memory."));
            return;
        }
        memset(pFillData, EraseValue, DeviceInfo.aFlashArea[i].Size);
        //
        // Download Data to J-Link
        //
        JLINKARM_WriteMem(DeviceInfo.aFlashArea[i].Addr, DeviceInfo.aFlashArea[i].Size, pFillData);
        i++;
        delete [] pFillData;
    } while (1);

    JLINKARM_EndDownload();
    printGoed(_("Erasing done."));
    statusbar->SetStatusText(_("Succesfully erased the entire flash."));

}

void JLinkVensterKlasse::resetTargetHandler(wxCommandEvent &event)
{
    reset(JLINKARM_RESET_TYPE_NORMAL,250);
}

void JLinkVensterKlasse::haltTargetHandler(wxCommandEvent &event)
{
    printGoed(_("Target is halted and will stop executing code."));
    haltTarget();
}
void JLinkVensterKlasse::restartTargetHandler(wxCommandEvent &event)
{
    printGoed(_("Target is restarted and will execute code."));
    JLINKARM_Go();
}

void JLinkVensterKlasse::haltTarget() const
{
    if (0 == JLINKARM_IsHalted())
        JLINKARM_Halt();
}

void JLinkVensterKlasse::reset(const JLINKARM_RESET_TYPE resetType,
                               const unsigned int delay) const 
{
    JLINKARM_SetResetType(resetType);
    const char* sName;
    const char* sDesc;
    JLINKARM_GetResetTypeDesc(resetType, &sName, &sDesc);
    printGoed(_("Target will be reset."));
    wxLogMessage(wxString::Format(wxT("Reset delay: %d ms"), delay));
    wxLogMessage(wxString::Format(wxT("Reset type %s: %s"), sName, sDesc));
    JLINKARM_SetResetDelay(delay);
    JLINKARM_Reset();
}

void JLinkVensterKlasse::getSetMaxSpeed()
{ 
    JLINKARM_SetSpeed(snelheid);
    JLINKARM_SetMaxSpeed(); 
	
    echteSnelheid = JLINKARM_GetSpeed(); 


    const wxString snelString((snelheid==JLINKARM_SPEED_AUTO) ? _("Auto detection.") :
                              (snelheid==JLINKARM_SPEED_ADAPTIVE) ? _("Adaptive clocking.") :
                              wxString::Format(wxT("%d kHz."),snelheid));
							  
    printGoed(wxString::Format(_("Speed Selection: start speed   : ")+snelString));						  
    wxLogMessage(wxString::Format(_("Speed Selection: current speed : %d kHz."), echteSnelheid));
}

void JLinkVensterKlasse::magDeviceToevoegenHandler(wxUpdateUIEvent &event)
{
    const wxString cbvalue(targetNameComboBox->GetValue());
    Int32 index =  targetNameComboBox->FindString(cbvalue);
	
    const bool overig = ((false == verbindKnop->GetValue()) && 
                         (false == debugKnop->GetValue()) &&
                         (false == swoButton->GetValue()));
    event.Enable((true == overig) && (wxNOT_FOUND == index));
}

void JLinkVensterKlasse::magDeviceVerwijderenHandler(wxUpdateUIEvent &event)
{
    const wxString cbvalue(targetNameComboBox->GetValue());
    Int32 index =  targetNameComboBox->FindString(cbvalue);
	
    const bool overig = ((false == verbindKnop->GetValue()) && 
                         (false == debugKnop->GetValue()) &&
                         (false == swoButton->GetValue()));
	
    event.Enable((true == overig) && (wxNOT_FOUND != index));
}

void JLinkVensterKlasse::voegToeHandler(wxCommandEvent &event)
{
    const wxString cbvalue(targetNameComboBox->GetValue());
    const Int32 index =  targetNameComboBox->FindString(cbvalue);
	
    if (wxNOT_FOUND == index)
    {
        /* voeg toe */
        DeviceConfig device(leesKnoppen());
		
        device.naam = cbvalue;

        huidigTarget = targetNameComboBox->Append(cbvalue);
        configLijst.Add(device);
    }
	
    targetNameComboBox->SetSelection(huidigTarget);
}

void JLinkVensterKlasse::verwijderHandler(wxCommandEvent &event)
{
    const wxString cbvalue(targetNameComboBox->GetValue());
    Int32 index =  targetNameComboBox->FindString(cbvalue);
	
    if (wxNOT_FOUND == index)
        printFout(_("Cannot remove unselected device."));
    else if (configLijst.GetCount() <2)
        printFout(_("Cannot remove last device. At least one device must be available."));
    else
    {
        configLijst.RemoveAt(index);
					   
        targetNameComboBox->Clear();
        for (Teller i=0;i<configLijst.GetCount();i++)
            targetNameComboBox->Append(configLijst[i].naam);
		
        targetNameComboBox->SetSelection(huidigTarget=0);
		
        const DeviceConfig nieuwDevice(configLijst[huidigTarget]);

        zetKnoppen(nieuwDevice);
		
        // const Teller deler[] = { 1,1000,1000000 };
        // const Teller freq = nieuwDevice.cpuFreq/deler[freqDimensieChoice->GetSelection()];
        // cpuFreqSpinCtrl->SetValue(freq);
        // interfaceKeuzeChoice->SetSelection(nieuwDevice.dbgIntf);
        // endiannessChoice->SetSelection(nieuwDevice.endianess);
   }
}


void JLinkVensterKlasse::targetWisselHandler(wxCommandEvent &event)
{
    const Int32 index =  targetNameComboBox->GetSelection();
	
    if ((index != (Int32)huidigTarget) && (index < (Int32)configLijst.GetCount()))
    {
        /* sla de huidige keuze op */
        const DeviceConfig oudDevice(leesKnoppen());
	
        configLijst[huidigTarget] = oudDevice;  /* kopieer er over heen */
	
        /* laad de nieuwe keuze in */
        huidigTarget=index;
        const DeviceConfig nieuwDevice(configLijst[huidigTarget]);
		
        zetKnoppen(nieuwDevice);
		
    }
	
}

void JLinkVensterKlasse::nicenessHandler(wxCommandEvent &event)
{
    wxNumberEntryDialog dialoog(this,_("Please enter the BSD niceness number for the GDB Server/SWO process.\nNiceness inversely affects the priority of the process.\nThe higher the niceness, the lower the priority of the process will become."),_("Niceness:"),_("BSD process niceness"),niceness,-20,20);

    if (wxID_OK == dialoog.ShowModal())
    {
        niceness = dialoog.GetValue();
    } 
}

void JLinkVensterKlasse::startDebugHandler(wxCommandEvent &event)
{
    if (debugServer == (DebugServerProcess *)Null)
    {	
        wxIPV4address adres;

        const wxString debugServerNaam(seggerDirPad+wxT("/")+
#ifdef __WXMAC__
                                       wxT("JLinkGDBServer")
#elif defined(__WXMSW__)
                                       wxT("JLinkGDBServerCL.exe")
#elif defined(__LINUX__)
                                       wxT("JLinkGDBServer")
#endif
            );

        debugServer = new DebugServerProcess(this,
                                             JLinkDebugServerEventID,
                                             niceness,
                                             debugServerNaam,
                                             wxString::Format(wxT("%d"),leesUSBSerialID()),
                                             swoPoortCtrl->GetValue());

        const bool gestart = debugServer->startServer(targetNameComboBox->GetValue(),
                                                      (bool)endiannessChoice->GetSelection(),
                                                      (bool)(interfaceKeuzeChoice->GetSelection()), /* JTAG/SWD */
                                                      true,  /* init cpu regs */
                                                      gdbVerifyDownloadCheckBox->IsChecked(),
                                                      gdbServerSingleRunCheckBox->IsChecked(),
                                                      gdbServerSilentCheckBox->IsChecked(),
                                                      echteSnelheid,
                                                      leesSWOMaskBits());   


        if (true == gestart)
        {
            printGoed(_("JLink GDB server session started."));
            debugKnop->SetLabel(_("Stop GDB server"));
            debugKnop->SetValue(true);
            statusbar->SetStatusText(_("JLink GDB server started"));	
            timer.Start(500,false);
        }
        else
        {
            debugServer = (DebugServerProcess *)Null;
            debugKnop->SetValue(false);
            debugKnop->SetLabel(_("Start GDB server"));
            printFout(_("(Start Debug) Could not start GDB server."));
        }
    }
    else
    {

#ifdef wxUSE_LOG_DEBUG
        wxLogDebug(wxString::Format(wxT("gestopt = %d"),debugServer->stopServer()));
#endif

        debugServer = (DebugServerProcess *)Null;		
        timer.Stop();
        debugKnop->SetValue(false);
        debugKnop->SetLabel(_("Start GDB Server"));
        statusbar->SetStatusText(_("JLink GDB server session ceased"));
        printGoed(_("JLink GDB server session terminated."));
    }

   
}

void JLinkVensterKlasse::startStopDDDHandler(wxCommandEvent &event)
{
  if (debugger == (DebuggerProcess *)Null)
    {	
      const wxString gdbPad = armDirPad+wxT("/bin/arm-none-eabi-gdb");
      const wxFileName elfBestand(openKnop->GetPath());

      debugger = new DebuggerProcess(this,
				     DebuggerEventID,
				     niceness,
				     dddPad,
				     gdbPad);

      const bool gestart = debugger->startDebugger(gdbScriptOpenPickerCtrl->GetPath(),
                                                   elfBestand);   


      if (true == gestart)
        {
	  printGoed(_("DDD session started."));
	  dddButton->SetLabel(_("Stop DDD Frontend"));
	  dddButton->SetValue(true);
	  statusbar->SetStatusText(_("DDD session started"));	
	  timer.Start(500,false);
        }
      else
        {
	  debugger = (DebuggerProcess *)Null;
	  dddButton->SetValue(false);
	  dddButton->SetLabel(_("Start DDD Frontend"));
	  printFout(_("(Start Debug) Could not start DDD Frontend."));
        }
    }
  else
    {

#ifdef wxUSE_LOG_DEBUG
      wxLogDebug(wxString::Format(wxT("gestopt = %d"),debugger->stopDebugger()));
 #endif

      debugger = (DebuggerProcess *)Null;		
      timer.Stop();
      dddButton->SetValue(false);
      dddButton->SetLabel(_("Start DDD Frontend"));
      statusbar->SetStatusText(_("DDD session ceased"));
      printGoed(_("DDD session terminated."));
    }

}

void JLinkVensterKlasse::onDDDProcessTerm( wxProcessEvent& WXUNUSED(event) )
{
    delete debugger;
    debugger = (DebuggerProcess *)Null;
    timer.Stop();
    dddButton->SetValue(false);
    dddButton->SetLabel(_("Start DDD Frontend"));
    statusbar->SetStatusText(_("DDD session ceased"));
    printGoed(_("DDD session terminated."));
}

void JLinkVensterKlasse::startGDBSwoHandler(wxCommandEvent &event)
{
  if ((wxSocketClient *)Null == gdbSwoClient)
    {

      /* start de GDB SWO socket client indien gewenst */
      wxIPV4address swoAdres;
      /* start SWO socket om te luisteren */
      swoAdres.Hostname(wxT("localhost"));
      swoAdres.Service(swoPoortCtrl->GetValue());
				
      gdbSwoClient = new wxSocketClient();
				
      gdbSwoClient->SetEventHandler(*this,GDBSWOSocketID);
      gdbSwoClient->SetNotify((wxSOCKET_CONNECTION+wxSOCKET_INPUT+wxSOCKET_LOST));
      gdbSwoClient->Notify(true);
      gdbSwoClient->Connect(swoAdres,false);		
      gdbSwoKnop->SetLabel(_("Stop GDB SWO Client"));


    }
  else
    {
      gdbSwoClient->Destroy();
      gdbSwoClient = (wxSocketClient *)Null;
      gdbSwoKnop->SetLabel(_("Start GDB SWO Client"));

      const wxString connTekst(wxString::Format(_("GDB server SWO Client was disconnected from port %d\n"),
						swoPoortCtrl->GetValue()));
			
      swoTextCtrl->AppendText(connTekst);
    }
}


void JLinkVensterKlasse::onGDBServerProcessTerm( wxProcessEvent& WXUNUSED(event) )
{
    delete debugServer;
    debugServer = (DebugServerProcess *)Null;
    timer.Stop();
    debugKnop->SetValue(false);
    debugKnop->SetLabel(_("Start Debugging"));
    statusbar->SetStatusText(_("Debugging session ceased"));
    printGoed(_("Debugging session terminated."));
}

void JLinkVensterKlasse::gdbSwoSocketHandler(wxSocketEvent &event)
{
    wxSocketBase * const socket = event.GetSocket();
	
    switch(event.GetSocketEvent())
    {
        case wxSOCKET_CONNECTION:
        {
            const wxString connTekst(wxString::Format(_("GDB server SWO Client is connected on port %d\n"),
                                                      swoPoortCtrl->GetValue()));
            swoTextCtrl->AppendText(connTekst);
        }
        break;
			
        case wxSOCKET_INPUT:
        {
            wxLogDebug(_("GDB server SWO Client data was received."));
            wxSocketInputStream instroom(*socket);
            char buffer[32];

            instroom.Read(buffer,32);
			
            const Teller aantal = instroom.LastRead();
			
            const wxString tekst(buffer,aantal);
            swoTextCtrl->AppendText(tekst);
						
        }
        break;
			

        case wxSOCKET_LOST:
        {
            const wxString connTekst(wxString::Format(_("GDB server SWO Client was disconnected from port %d\n"),
                                                      swoPoortCtrl->GetValue()));
			
            swoTextCtrl->AppendText(connTekst);

            socket->Destroy();
            gdbSwoClient = (wxSocketClient *)Null;
            gdbSwoKnop->SetLabel(_("Start GDB SWO Client"));
            gdbSwoKnop->SetValue(false);
        }
        break;

        default:
        {
            printFout(_("Unknown socket event in SWO Socket interface"));
        }
        break;
    }
			
	
}

void JLinkVensterKlasse::startSWOHandler(wxCommandEvent &event)
{
	
    if (swoViewer == (SWOViewerProcess *)Null)
    {	
        const UInt32 swoMaskBits = leesSWOMaskBits();
		
        if (0 == swoMaskBits)
        {
            swoButton->SetValue(false);
            swoButton->SetLabel(_("Start Listening"));
            printFout(_("No ITM Mask bits are set. The SWO Viewer process wil not start."));
        }
        else
        {
            const wxString swoViewerNaam(seggerDirPad+wxT("/")+
#ifdef __WXMAC__
                                         wxT("JLinkSWOViewer")
#elif defined(__WXMSW__)
                                         wxT("JLinkSWOViewerCL.exe")
#elif defined(__LINUX__)
                                         wxT("JLinkSWOViewer")
#endif
                );
			
            swoViewer = new SWOViewerProcess(this,
                                             JLinkSWOViewerEventID,
                                             niceness,
                                             swoViewerNaam);
			
            const bool gestart = swoViewer->startViewer(targetNameComboBox->GetValue(),
                                                        cpuFreqSpinCtrl->GetValue(),
                                                        swoSpeedCtrl->GetValue(),
                                                        leesSWOMaskBits());
			
            if (true == gestart)
            {
                timer.Start(500,false);
                printGoed(_("SWO Viewer session started."));
                swoButton->SetValue(true);
                swoButton->SetLabel(_("Stop Listening"));
                statusbar->SetStatusText(_("SWO Viewer active"));	
            }
            else
            {
                swoViewer = (SWOViewerProcess *)Null;
                swoButton->SetValue(false);
                swoButton->SetLabel(_("Start Listening"));
                printFout(_("(Start SWO Viewer) Could not start SWO Viewer."));
            }
        }
    }
    else
    {
		
#ifdef wxUSE_LOG_DEBUG
        wxLogDebug(wxString::Format(wxT("gestopt = %d"),swoViewer->stopViewer()));
#endif
        swoViewer = (SWOViewerProcess *)Null;
        timer.Stop();
        swoButton->SetValue(false);
        swoButton->SetLabel(_("Start Listening"));
        statusbar->SetStatusText(_("SWO Viewer session ceased"));
        printGoed(_("SWO Viewer session terminated."));
    }
}

void JLinkVensterKlasse::onSWOProcessTerm( wxProcessEvent& WXUNUSED(event) )
{
    delete swoViewer;
    swoViewer = (SWOViewerProcess *)Null;
    timer.Stop();
    swoButton->SetValue(false);
    swoButton->SetLabel(_("Start Listening"));
    statusbar->SetStatusText(_("SWO Viewer session ceased"));
    printGoed(_("SWO Viewer session terminated."));
}



void JLinkVensterKlasse::overHandler(wxCommandEvent &event)
{
    wxGetApp().geefCopyright(wxT("J-Link Programmer"),
                             _("This tool provides a GUI wrapper around\n - Segger JLink Commander\n - Segger GDB Server\n - Segger SWO Viewer\n")+
                             _("Linked against JLink library : ")+JLinkVersieString  
#ifndef GeenIkoon
                             ,logo);
#else
    );
#endif
}

void JLinkVensterKlasse::kiesSeggerDirHandler(wxCommandEvent &event)
{
    if (true == event.IsChecked())
    {
        wxFileName seggerdir(laatstePad);
        wxDirDialog openDialoog(this,
                                _("Please select the Segger J-Link directory."),
                                seggerdir.GetPath(),
                                (wxDD_DEFAULT_STYLE+wxDD_DIR_MUST_EXIST));

        if (wxID_OK == openDialoog.ShowModal())
        {
            laatstePad = seggerDirPad = openDialoog.GetPath();
            printGoed(_("Segger J-Link directory selected (")+seggerDirPad+_(")."));
            statusbar->SetStatusText(_("Segger J-Link directory selected"));
        }
		else
		{
			wxMenuItem * const seggerAanwezigMenu = menubar->FindItem(ProgrammerSeggerDirID);
			seggerAanwezigMenu->Check(false);
		}
    }
    else
	{
        seggerDirPad = seggerStandaardPad;
	}
} 


void JLinkVensterKlasse::kiesARMDirHandler(wxCommandEvent &event)
{
    if (true == event.IsChecked())
    {
        wxFileName armdir(laatstePad);
        wxDirDialog openDialoog(this,
                                _("Please select the ARM-none-EABI base directory."),
                                armdir.GetPath(),
                                (wxDD_DEFAULT_STYLE+wxDD_DIR_MUST_EXIST));
	
        if (wxID_OK == openDialoog.ShowModal())
        {

			laatstePad = openDialoog.GetPath();
            wxFileName armccCompiler(laatstePad=openDialoog.GetPath());
			
			//armccCompiler.AppendDir(wxT("bin"));  ///arm-none-eabi-gcc"));
			//armccCompiler.SetName(wxT("arm-none-eabi-gcc"));

			if (false == armccCompiler.Exists())
			{
                printFout(_("The selected dir (")+openDialoog.GetPath()+_(") does not contain an executable \"bin/arm-none-eabi-gcc\""));
				wxMenuItem * const armAanwezigMenu = menubar->FindItem(ProgrammerARMDirID);
				armAanwezigMenu->Check(false);
			}
			else
            {
                armDirPad = openDialoog.GetPath();
                printGoed(_("ARM EABI dir found (")+armDirPad+_(")."));
                statusbar->SetStatusText(_("ARM EABI toolchain found"));
            }
		}
		else
		{
			wxMenuItem * const armAanwezigMenu = menubar->FindItem(ProgrammerARMDirID);
			armAanwezigMenu->Check(false);
		}
    }
    else
	{
        armDirPad = armStandaardPad;
	}
}

void JLinkVensterKlasse::kiesDDDHandler(wxCommandEvent &event)
{
    if (true == event.IsChecked())
    {
        wxFileName ddd(laatstePad);
        wxFileDialog openDialoog(this,
                                 _("Please select the DDD executable."),
                                 ddd.GetPath(),
                                 ddd.GetName(),
                                 wxFileSelectorDefaultWildcardStr,
                                 (wxFD_OPEN+wxFD_FILE_MUST_EXIST));
	
        if (wxID_OK == openDialoog.ShowModal())
        {

            const wxFileName dddGekozenPad(laatstePad = openDialoog.GetPath());
            if (false == dddGekozenPad.IsFileExecutable())
			{
                printFout(_("The selected file (")+dddGekozenPad.GetPath()+_(") is not an executable"));
				wxMenuItem * const dddAanwezigMenu = menubar->FindItem(ProgrammerDDDFrontEndID);
				dddAanwezigMenu->Check(false);
			}
			else
            {
                printGoed(_("DDD executable found (")+dddGekozenPad.GetFullPath()+_(")."));
                statusbar->SetStatusText(_("DDD executable found"));
                dddPad = dddGekozenPad.GetFullPath();
            }            
        }
		else
		{
			wxMenuItem * const dddAanwezigMenu = menubar->FindItem(ProgrammerDDDFrontEndID);
			dddAanwezigMenu->Check(false);
		}
    }
    else
	{

        dddPad = dddStandaardPad;
	}
}

void JLinkVensterKlasse::vindDeviceHandler(wxCommandEvent &event)
{

    wxTextEntryDialog dialoog(this,
                              _("Please give the manufacturer's name of the devices you want to find."),
                              _("Manufacturer's name"),
                              favFabrikant);

    if (wxID_OK == dialoog.ShowModal())
    {
        favFabrikant = dialoog.GetValue();
        wxLaunchDefaultBrowser(wxT("http://www.segger.de/jlink_supported_devices.html?m=")+favFabrikant);
    }

}

void JLinkVensterKlasse::hanWebsiteHandler(wxCommandEvent &event)
{
    wxLaunchDefaultBrowser(wxT("http://www.hanese.nl"));
}


void JLinkVensterKlasse::connectKnopAktiefHandler(wxUpdateUIEvent &event)
{
    event.Enable(((true == verbindKnop->GetValue()) && 
                  (false == debugKnop->GetValue()) &&
                  (false == swoButton->GetValue())));
}

void JLinkVensterKlasse::knopMagAanHandler(wxUpdateUIEvent &event)
{
    event.Enable((false == verbindKnop->GetValue()) && 
                 (false == debugKnop->GetValue()) &&
                 (false == swoButton->GetValue()));
}


void JLinkVensterKlasse::gdbServerSTDIOHandler(wxUpdateUIEvent &event)
{
    if (((DebugServerProcess *)Null) != debugServer)
    {
        const bool stdOut = debugServer->printStdOut(statusTextCtrl);
        const bool errOut = debugServer->printStdErr(statusTextCtrl);

        if ((true == stdOut) || (true == errOut) )
            statusTextCtrl->Refresh();
    }
}

void JLinkVensterKlasse::swoServerSTDIOHandler(wxUpdateUIEvent &event)
{
    if (((SWOViewerProcess *)Null) != swoViewer)
    {
        const bool stdOut = swoViewer->printStdOut(swoTextCtrl);
        const bool errOut = swoViewer->printStdErr(swoTextCtrl);

        if ((true == stdOut) || (true == errOut))
            swoTextCtrl->Refresh();
    }
}

void JLinkVensterKlasse::nicenessUpdateHandler(wxUpdateUIEvent &event)
{
#ifdef __WXMSW__
    const bool conditie = false;
#else
    const bool conditie = ((0==debugKnop->GetValue()) && (0==swoButton->GetValue()));
#endif
    event.Enable(conditie);
}

void JLinkVensterKlasse::extProcessTimerPollingEventHandler(wxTimerEvent &event)
{
    if (((DebugServerProcess *)Null) != debugServer)
    {
        const bool stdOut = debugServer->printStdOut(statusTextCtrl);
        const bool errOut = debugServer->printStdErr(statusTextCtrl);
		
        if ((true == stdOut) || (true == errOut) )
            statusTextCtrl->Refresh();
    }
	
    if (((SWOViewerProcess *)Null) != swoViewer)
    {
        const bool stdOut = swoViewer->printStdOut(swoTextCtrl);
        const bool errOut = swoViewer->printStdErr(swoTextCtrl);
		
        if ((true == stdOut) || (true == errOut))
            swoTextCtrl->Refresh();
    }
}

void JLinkVensterKlasse::oudBestandLadenHandler(wxCommandEvent &event)
{	
    const Teller index = event.GetId() - wxID_FILE-1;
    const wxString oudBestandNaam(bestandGeschiedenis.GetHistoryFile(index));
    const wxFileName oudBestand(oudBestandNaam);
    openKnop->SetFileName(oudBestand);
}

void JLinkVensterKlasse::connectStandHandler(wxUpdateUIEvent &event)
{
    event.Enable((0==debugKnop->GetValue()) && (0==swoButton->GetValue()));
}

void JLinkVensterKlasse::debugStandHandler(wxUpdateUIEvent &event)
{
	wxMenuItem * const armAanwezigMenu = menubar->FindItem(ProgrammerARMDirID);
    wxMenuItem * const seggerAanwezigMenu = menubar->FindItem(ProgrammerSeggerDirID);
    const bool seggerArmAanwezig = ((true == armAanwezigMenu->IsChecked()) &&
									(true == seggerAanwezigMenu->IsChecked()));

#ifdef __WXMSW__
    const bool conditie = ((true == seggerArmAanwezig) && 
                           (false==gdbSwoKnop->GetValue()) &&
                           (false==swoButton->GetValue()));
#else
    const bool conditie = ((true == seggerArmAanwezig) && 
                           (false==gdbSwoKnop->GetValue()) &&
                           (false==swoButton->GetValue()) && 
                           (false==verbindKnop->GetValue()));
#endif

    event.Enable(conditie);	
}

void JLinkVensterKlasse::dddStandHandler(wxUpdateUIEvent &event)
{
    wxMenuItem * const armAanwezigMenu = menubar->FindItem(ProgrammerARMDirID);
    wxMenuItem * const dddAanwezigMenu = menubar->FindItem(ProgrammerDDDFrontEndID);
    const bool dddAanwezig = ((true == armAanwezigMenu->IsChecked()) &&
                              (true == dddAanwezigMenu->IsChecked()));

#ifdef __WXMSW__
    const bool conditie = false;
#else
    const bool conditie = ((true == dddAanwezig) && 
                           (true==debugKnop->GetValue()) &&
                           (false==swoButton->GetValue()) && 
                           (false==verbindKnop->GetValue()));
#endif

    event.Enable(conditie);	
}

void JLinkVensterKlasse::debugSWOStandHandler(wxUpdateUIEvent &event)
{
    wxMenuItem * const seggerAanwezigMenu = menubar->FindItem(ProgrammerSeggerDirID);
    const bool seggerAanwezig = seggerAanwezigMenu->IsChecked();

    event.Enable( (true == seggerAanwezig) &&
                  (true==debugKnop->GetValue()) &&
                  (false==swoButton->GetValue()) && 
                  (false==verbindKnop->GetValue()) && 
                  (1==interfaceKeuzeChoice->GetSelection()));
	
}

void JLinkVensterKlasse::swdStandHandler(wxUpdateUIEvent &event)
{
    wxMenuItem * const seggerAanwezigMenu = menubar->FindItem(ProgrammerSeggerDirID);
    const bool seggerAanwezig = seggerAanwezigMenu->IsChecked();

#ifdef __WXMSW__
    const bool conditie = ( (true == seggerAanwezig) && 
                            (false==debugKnop->GetValue()) && 
                            (1==interfaceKeuzeChoice->GetSelection()));
#else
    const bool conditie = ( (true == seggerAanwezig) && 
                            (false==debugKnop->GetValue()) && 
                           (false==verbindKnop->GetValue()) && 
                           (1==interfaceKeuzeChoice->GetSelection()));
#endif
    event.Enable(conditie);
}

void JLinkVensterKlasse::swoStandHandler(wxUpdateUIEvent &event)
{
    wxMenuItem * const seggerAanwezigMenu = menubar->FindItem(ProgrammerSeggerDirID);
    const bool seggerAanwezig = seggerAanwezigMenu->IsChecked();

    event.Enable( (true == seggerAanwezig) &&
                  (false==swoButton->GetValue()) && 
                  (false==debugKnop->GetValue()) && 
                  (false==verbindKnop->GetValue()) && 
                  (1==interfaceKeuzeChoice->GetSelection()));

}


void JLinkVensterKlasse::eindeHandler(wxCommandEvent &event)
{
    const wxString cbvalue(targetNameComboBox->GetValue());
    Int32 index =  targetNameComboBox->FindString(cbvalue);
    if (wxNOT_FOUND == index)
    {
        const int answer = wxMessageBox(_("You entered a device name (")+
                                        cbvalue+
                                        _(") that wasn't added to your settings with the \"Add\" button.\nWould you like to add it now?"), 
                                        _("Confirm storing ")+cbvalue,
                                        (wxYES_NO),this);
        if (answer == wxYES)
        {
            /* sla de huidige keuze nog op */
            DeviceConfig vergetenDevice(leesKnoppen());
            vergetenDevice.naam = targetNameComboBox->GetValue();

            huidigTarget = targetNameComboBox->Append(cbvalue);
            configLijst.Add(vergetenDevice);
//            configLijst[huidigTarget] = oudDevice;  /* kopieer er over heen */
        }
    }	

    Close(); /* sluit nu af */
}



void JLinkVensterKlasse::showDLLInfo() const
{
    char acRev[8] = {0};
    const int Version  = JLINKARM_GetDLLVersion();
    int Revision = Version % 100;
    if (Revision > 26) {
        Revision -= 26;
        acRev[0] = 'z';
        acRev[1] = '0' + (Revision / 10);
        acRev[2] = '0' + (Revision % 10);
    } else if (Revision > 0) {
        acRev[0] = 'a' + Revision - 1;
    }
    printGoed(wxString::Format(wxT("DLL version V%d.%.2d%s, compiled %s"), Version / 10000, Version / 100 % 100, acRev, JLINKARM_GetCompileDateTime())); 
}


void JLinkVensterKlasse::showFirmwareInfo() const
{
    char ac[256];
    JLINKARM_GetFirmwareString(ac, sizeof(ac));
    if (ac[0]) 
    {
        printGoed(wxString::Format(wxT("Firmware: %s"), ac));
        const int Version = JLINKARM_GetHardwareVersion();
        if (0 != Version) 
        {
            printGoed(wxString::Format(wxT("Hardware: V%d.%.2d"), 
                                       Version / 10000 % 100, Version / 100 % 100));
        }
    } 
    else 
    {
        printWaarschuwing(wxT("Unable to retrieve firmware info !"));
    }
}

bool JLinkVensterKlasse::JLinkExecCmd(const wxString &deviceCommando) const
{
    /* voer het commando uit  */
    char acOut[256];
    JLINKARM_ExecCommand(deviceCommando.c_str(),
                         acOut,
                         sizeof(deviceCommando.c_str()));
					
    if (acOut[0] != 0)  /* het ging fout */
    {
        printFout(_("Execution of Cmd String resulted in errors."));
        printFout(wxString(acOut));
        return(false);
    }
    else return(true);
}

void JLinkVensterKlasse::targetInterfaceKeuzeHandler(wxCommandEvent &event)
{

}


void JLinkVensterKlasse::targetSpeedKeuzeHandler(wxCommandEvent &event)
{


}


void JLinkVensterKlasse::freqDimensieHandler(wxCommandEvent &event)
{
    const Int32 index =  targetNameComboBox->GetSelection();

    if (index < (Int32)configLijst.GetCount())
    {
        const DeviceConfig huidigDevice(configLijst[huidigTarget]);
	
        const Teller deler[] = { 1,1000,1000000 };
        const Teller freq = huidigDevice.cpuFreq/deler[freqDimensieChoice->GetSelection()];
        cpuFreqSpinCtrl->SetValue(freq);
    }
}


void JLinkVensterKlasse::printGoed(const wxString &tekst) const
{
    statusTextCtrl->SetDefaultStyle(goedeStatusTextAttr);
    wxLogMessage(tekst);
}

void JLinkVensterKlasse::printWaarschuwing(const wxString &tekst) const
{
    statusTextCtrl->SetDefaultStyle(waarschuwingStatusTextAttr);
    wxLogWarning(tekst);
}

void JLinkVensterKlasse::printFout(const wxString &tekst) const
{
    statusTextCtrl->SetDefaultStyle(fouteStatusTextAttr);
    wxLogError(tekst);
}

// wxGlade: add JLinkVensterKlasse event handlers



void JLinkVensterKlasse::set_properties()
{

    wxImage::AddHandler(new wxXPMHandler);

#ifndef GeenIkoon
    wxIcon ikoon((const char **)logo);
    SetIcon(ikoon);
#endif

     // begin wxGlade: JLinkVensterKlasse::set_properties
     SetTitle(_("J-Link ARM Programmer"));
     int statusbar_widths[] = { -1 };
     statusbar->SetStatusWidths(1, statusbar_widths);
     
     // statusbar fields
     const wxString statusbar_fields[] = {
          _("Welcome to the J-Link programming tool"),
     };
     for(int i = 0; i < statusbar->GetFieldsCount(); ++i) {
          statusbar->SetStatusText(statusbar_fields[i], i);
     }
     jlinkConnectionRadioBox->SetToolTip(_("Select the connection type to your J-Link"));
     jlinkConnectionRadioBox->SetSelection(0);
     USBSerialTextCtrl->SetFont(wxFont(12, wxDEFAULT, wxNORMAL, wxNORMAL, 0, wxT("MS Shell Dlg 2")));
     USBSerialTextCtrl->SetToolTip(_("Provide your J-Link serial number"));
     targetNameComboBox->SetSelection(-1);
     bewaarButton->SetToolTip(_("Add the device to your list of devices"));
     vindDeviceButton->SetToolTip(_("Find the device name on Segger's website."));
     verwijderButton->SetToolTip(_("Remove the device from your list of devices"));
     speedRadioBox->SetSelection(0);
     cpuFreqSpinCtrl->SetToolTip(_("Enter the device's main clock frequency (in Hz)"));
     freqDimensieChoice->SetSelection(0);
     interfaceKeuzeChoice->SetToolTip(_("Selecte the debugger interface protocol"));
     interfaceKeuzeChoice->SetSelection(1);
     endiannessChoice->SetToolTip(_("Select the target's endianess"));
     endiannessChoice->SetSelection(0);
     gdbScriptOpenPickerCtrl->SetToolTip(_("(Mac OS X/Linux only) Select the GDB script (.gdb) that will be used to start the GDB debugger"));
     statusTextCtrl->SetMinSize(wxSize(80, 34));
     logPaneel->SetScrollRate(10, 10);
     swoTextCtrl->SetMinSize(wxSize(80, 34));
     swoPaneel->SetScrollRate(10, 10);
     openKnop->SetToolTip(_("Select the file that will be written to the target's flash"));
     verbindKnop->SetToolTip(_("Connect to to the target"));
     verbindKnop->SetFocus();
     schrijfFlashKnop->SetToolTip(_("Write the target's main program flash"));
     flashLaadTextCtrl->SetToolTip(_("Provide the load addres at which the program is loaded into the target"));
     veegUitKnop->SetToolTip(_("Erase the entire program flash in the target"));
     haltButton->SetToolTip(_("Halt the target"));
     goButton->SetToolTip(_("Start the target "));
     resetButton->SetToolTip(_("Execute a HW reset on the target "));
     statusBoom->SetMinSize(wxSize(350,200));
     gdbVerifyDownloadCheckBox->SetValue(1);
     debugKnop->SetToolTip(_("Start the external JLink GDB server"));
     gdbSwoKnop->SetToolTip(_("Start the SWO client for the GDB Server"));
     swoButton->SetToolTip(_("Start the external JLink SWO viewer"));
     swoCheckListBox->SetMinSize(wxSize(180,70));
     swoCheckListBox->SetToolTip(_("Select the SWO channels that will be listened on "));
     sluitKnop->SetToolTip(_("Quit the program"));
     // end wxGlade
}


void JLinkVensterKlasse::do_layout()
{
     // begin wxGlade: JLinkVensterKlasse::do_layout
     wxBoxSizer* hoofdSizer = new wxBoxSizer(wxVERTICAL);
     wxBoxSizer* sizer_2 = new wxBoxSizer(wxVERTICAL);
     wxBoxSizer* sizer_19 = new wxBoxSizer(wxVERTICAL);
     wxBoxSizer* sizer_3 = new wxBoxSizer(wxHORIZONTAL);
     wxBoxSizer* programmeerHoofdSizer = new wxBoxSizer(wxVERTICAL);
     debugSizer_staticbox->Lower();
     wxStaticBoxSizer* debugSizer = new wxStaticBoxSizer(debugSizer_staticbox, wxVERTICAL);
     jlinkSWOSizer_staticbox->Lower();
     wxStaticBoxSizer* jlinkSWOSizer = new wxStaticBoxSizer(jlinkSWOSizer_staticbox, wxHORIZONTAL);
     wxBoxSizer* sizer_21 = new wxBoxSizer(wxVERTICAL);
     wxBoxSizer* sizer_25 = new wxBoxSizer(wxVERTICAL);
     wxFlexGridSizer* swoGridSizer = new wxFlexGridSizer(2, 3, 0, 0);
     wxBoxSizer* sizer_4 = new wxBoxSizer(wxVERTICAL);
     sizer_26_staticbox->Lower();
     wxStaticBoxSizer* sizer_26 = new wxStaticBoxSizer(sizer_26_staticbox, wxHORIZONTAL);
     jlinkGDBSizer_staticbox->Lower();
     wxStaticBoxSizer* jlinkGDBSizer = new wxStaticBoxSizer(jlinkGDBSizer_staticbox, wxHORIZONTAL);
     wxBoxSizer* sizer_23 = new wxBoxSizer(wxVERTICAL);
     wxBoxSizer* sizer_22 = new wxBoxSizer(wxVERTICAL);
     wxBoxSizer* sizer_24 = new wxBoxSizer(wxHORIZONTAL);
     flashSizer_staticbox->Lower();
     wxStaticBoxSizer* flashSizer = new wxStaticBoxSizer(flashSizer_staticbox, wxVERTICAL);
     wxBoxSizer* sizer_5 = new wxBoxSizer(wxHORIZONTAL);
     wxBoxSizer* sizer_16 = new wxBoxSizer(wxHORIZONTAL);
     wxBoxSizer* sizer_29 = new wxBoxSizer(wxVERTICAL);
     wxGridSizer* grid_sizer_2 = new wxGridSizer(3, 2, 0, 0);
     sizer_8_staticbox->Lower();
     wxStaticBoxSizer* sizer_8 = new wxStaticBoxSizer(sizer_8_staticbox, wxHORIZONTAL);
     sizer_14_staticbox->Lower();
     wxStaticBoxSizer* sizer_14 = new wxStaticBoxSizer(sizer_14_staticbox, wxHORIZONTAL);
     wxBoxSizer* sizer_7 = new wxBoxSizer(wxVERTICAL);
     wxBoxSizer* sizer_15 = new wxBoxSizer(wxVERTICAL);
     swoSizer_staticbox->Lower();
     wxStaticBoxSizer* swoSizer = new wxStaticBoxSizer(swoSizer_staticbox, wxHORIZONTAL);
     wxBoxSizer* swoOnderSizer = new wxBoxSizer(wxHORIZONTAL);
     logSizer_staticbox->Lower();
     wxStaticBoxSizer* logSizer = new wxStaticBoxSizer(logSizer_staticbox, wxHORIZONTAL);
     wxBoxSizer* logOnderSizer = new wxBoxSizer(wxHORIZONTAL);
     sizer_10_staticbox->Lower();
     wxStaticBoxSizer* sizer_10 = new wxStaticBoxSizer(sizer_10_staticbox, wxVERTICAL);
     sizer_12_staticbox->Lower();
     wxStaticBoxSizer* sizer_12 = new wxStaticBoxSizer(sizer_12_staticbox, wxHORIZONTAL);
     wxBoxSizer* sizer_13 = new wxBoxSizer(wxVERTICAL);
     wxBoxSizer* sizer_17 = new wxBoxSizer(wxHORIZONTAL);
     gdbPickerCtrl_staticbox->Lower();
     wxStaticBoxSizer* gdbPickerCtrl = new wxStaticBoxSizer(gdbPickerCtrl_staticbox, wxHORIZONTAL);
     wxBoxSizer* sizer_27 = new wxBoxSizer(wxVERTICAL);
     sizer_18_staticbox->Lower();
     wxStaticBoxSizer* sizer_18 = new wxStaticBoxSizer(sizer_18_staticbox, wxHORIZONTAL);
     wxBoxSizer* sizer_9 = new wxBoxSizer(wxHORIZONTAL);
     wxFlexGridSizer* grid_sizer_1 = new wxFlexGridSizer(2, 2, 2, 2);
     wxBoxSizer* sizer_11 = new wxBoxSizer(wxHORIZONTAL);
     sizer_20_staticbox->Lower();
     wxStaticBoxSizer* sizer_20 = new wxStaticBoxSizer(sizer_20_staticbox, wxHORIZONTAL);
     sizer_11->Add(jlinkConnectionRadioBox, 0, wxALL, 5);
     sizer_20->Add(USBSerialTextCtrl, 1, wxALIGN_CENTER_VERTICAL, 0);
     sizer_11->Add(sizer_20, 1, wxEXPAND, 0);
     sizer_10->Add(sizer_11, 0, wxEXPAND, 0);
     grid_sizer_1->Add(targetNameComboBox, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
     grid_sizer_1->Add(bewaarButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
     grid_sizer_1->Add(vindDeviceButton, 0, wxALL, 5);
     grid_sizer_1->Add(verwijderButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
     sizer_9->Add(grid_sizer_1, 1, wxEXPAND, 0);
     sizer_9->Add(speedRadioBox, 0, wxALL, 5);
     sizer_13->Add(sizer_9, 0, wxEXPAND, 0);
     sizer_18->Add(cpuFreqSpinCtrl, 2, wxALIGN_CENTER_VERTICAL|wxALL, 5);
     sizer_18->Add(freqDimensieChoice, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
     sizer_13->Add(sizer_18, 0, wxEXPAND, 1);
     sizer_27->Add(interfaceKeuzeChoice, 1, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5);
     sizer_27->Add(endiannessChoice, 1, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5);
     sizer_17->Add(sizer_27, 1, wxEXPAND, 0);
     gdbPickerCtrl->Add(gdbScriptOpenPickerCtrl, 2, wxALIGN_CENTER_VERTICAL, 0);
     sizer_17->Add(gdbPickerCtrl, 0, wxALIGN_CENTER_VERTICAL, 0);
     sizer_13->Add(sizer_17, 0, wxEXPAND, 0);
     sizer_12->Add(sizer_13, 1, wxEXPAND, 0);
     sizer_10->Add(sizer_12, 0, wxEXPAND, 0);
     sizer_7->Add(sizer_10, 1, wxEXPAND, 0);
     logOnderSizer->Add(statusTextCtrl, 1, wxEXPAND, 0);
     logPaneel->SetSizer(logOnderSizer);
     logSizer->Add(logPaneel, 1, wxEXPAND, 0);
     sizer_15->Add(logSizer, 1, wxEXPAND, 0);
     swoOnderSizer->Add(swoTextCtrl, 1, wxEXPAND, 0);
     swoPaneel->SetSizer(swoOnderSizer);
     swoSizer->Add(swoPaneel, 1, wxEXPAND, 0);
     sizer_15->Add(swoSizer, 1, wxEXPAND, 0);
     sizer_7->Add(sizer_15, 1, wxEXPAND, 0);
     sizer_3->Add(sizer_7, 0, wxEXPAND, 0);
     sizer_14->Add(openKnop, 2, wxALIGN_CENTER_VERTICAL, 0);
     flashSizer->Add(sizer_14, 0, wxALL|wxEXPAND, 5);
     sizer_29->Add(verbindKnop, 0, wxALL|wxEXPAND, 10);
     grid_sizer_2->Add(schrijfFlashKnop, 1, wxALL|wxEXPAND, 10);
     sizer_8->Add(flashLaadTextCtrl, 0, wxALL|wxEXPAND, 10);
     grid_sizer_2->Add(sizer_8, 0, 0, 0);
     grid_sizer_2->Add(veegUitKnop, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
     grid_sizer_2->Add(haltButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
     grid_sizer_2->Add(goButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
     grid_sizer_2->Add(resetButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
     sizer_29->Add(grid_sizer_2, 0, 0, 0);
     sizer_5->Add(sizer_29, 1, wxEXPAND, 0);
     sizer_16->Add(statusBoom, 2, wxEXPAND, 5);
     sizer_5->Add(sizer_16, 2, wxEXPAND, 0);
     flashSizer->Add(sizer_5, 1, wxEXPAND, 0);
     programmeerHoofdSizer->Add(flashSizer, 0, wxEXPAND, 0);
     sizer_24->Add(poortLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
     sizer_24->Add(gdbipPoortCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5);
     sizer_22->Add(sizer_24, 1, wxEXPAND, 0);
     sizer_22->Add(gdbVerifyDownloadCheckBox, 0, wxLEFT|wxRIGHT, 5);
     sizer_22->Add(gdbServerSilentCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxLEFT|wxRIGHT, 5);
     sizer_22->Add(gdbServerSingleRunCheckBox, 0, wxEXPAND|wxLEFT|wxRIGHT, 5);
     jlinkGDBSizer->Add(sizer_22, 1, wxEXPAND, 0);
     sizer_23->Add(debugKnop, 0, wxALL, 5);
     sizer_23->Add(gdbSwoKnop, 0, wxALL, 5);
     jlinkGDBSizer->Add(sizer_23, 1, wxEXPAND, 0);
     sizer_4->Add(jlinkGDBSizer, 0, wxEXPAND, 0);
     sizer_26->Add(dddButton, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
     sizer_4->Add(sizer_26, 1, wxEXPAND, 0);
     debugSizer->Add(sizer_4, 1, wxEXPAND, 0);
     swoGridSizer->Add(poortLabel_copy, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
     swoGridSizer->Add(swoPoortCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5);
     swoGridSizer->Add(20, 20, 0, 0, 0);
     swoGridSizer->Add(swoSpeedLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
     swoGridSizer->Add(swoSpeedCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5);
     swoGridSizer->Add(swoDimLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
     sizer_25->Add(swoGridSizer, 1, wxEXPAND, 0);
     sizer_25->Add(swoButton, 0, 0, 5);
     jlinkSWOSizer->Add(sizer_25, 1, wxEXPAND, 0);
     sizer_21->Add(swoCheckListBox, 1, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5);
     jlinkSWOSizer->Add(sizer_21, 1, wxEXPAND, 0);
     debugSizer->Add(jlinkSWOSizer, 0, wxEXPAND, 0);
     programmeerHoofdSizer->Add(debugSizer, 0, wxEXPAND, 0);
     sizer_3->Add(programmeerHoofdSizer, 1, wxEXPAND, 0);
     sizer_19->Add(sizer_3, 1, wxEXPAND, 0);
     sizer_19->Add(sluitKnop, 0, wxALL|wxEXPAND, 10);
     sizer_2->Add(sizer_19, 1, wxEXPAND, 0);
     achtergrondPaneel->SetSizer(sizer_2);
     hoofdSizer->Add(achtergrondPaneel, 1, wxEXPAND, 0);
     SetSizer(hoofdSizer);
     hoofdSizer->Fit(this);
     Layout();
     // end wxGlade
}


ProgrammeerDropTarget::ProgrammeerDropTarget(JLinkVensterKlasse * const parent) : ouder(parent)
{

}

wxDragResult ProgrammeerDropTarget::OnDragOver(wxCoord x,
                                               wxCoord y,
                                               wxDragResult res)
{

    const wxDragResult resultaat = ((true == ouder->verbonden()) ? res : wxDragNone );
    return(resultaat);
}



bool ProgrammeerDropTarget::OnDropFiles(wxCoord x,
                                        wxCoord y, 
                                        const wxArrayString &bestanden)
{

    const wxFileName bestand(bestanden[0]);

    return(ouder->schrijfFlash(bestand));

}


IMPLEMENT_APP(JLinkProgrammerKlasse)

JLinkProgrammerKlasse::JLinkProgrammerKlasse() : DesktopApp(wxT("JLinkProgrammer"))
{

}

bool JLinkProgrammerKlasse::OnInit()
{
    wxSocketBase::Initialize();

    JLinkVensterKlasse * const JLinkVenster = new JLinkVensterKlasse(NULL, wxID_ANY, wxEmptyString);

    zetHoofdVenster(JLinkVenster);

    JLinkVenster->Show();

    return(true);
}