//-----------------------------------------------------------------------------
// Copyright 2007 Jonathan Westhues
//
// This file is part of LDmicro.
//
// LDmicro is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// LDmicro is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with LDmicro. If not, see .
//------
//
// Dialog for setting the overall PLC parameters. Mostly this relates to
// timing; to set up the timers we need to know the desired cycle time,
// which is configurable, plus the MCU clock (i.e. crystal frequency).
// Jonathan Westhues, Nov 2004
//-----------------------------------------------------------------------------
#include
#include
#include
#include
//#include
#include "ldmicro.h"
using namespace std;
static QDialog* ConfDialog;
static QLineEdit* CrystalTextbox;
static QLineEdit* CycleTextbox;
static QLineEdit* BaudTextbox;
static QDialogButtonBox* ButtonBox;
static LONG_PTR PrevCrystalProc;
static LONG_PTR PrevCycleProc;
static LONG_PTR PrevBaudProc;
QGridLayout* ConfGrid;
static inline void DestroyWindow()
{
delete ConfDialog;
delete CrystalTextbox;
delete CycleTextbox;
delete BaudTextbox;
delete ButtonBox;
delete ConfGrid;
}
static void MakeControls(void)
{
// Creating text labels
QLabel* textLabel = new QLabel(_("Cycle Time (ms):"));
QLabel* textLabel2 = new QLabel(_("Crystal Frequency (MHz):"));
QLabel* textLabel3 = new QLabel(_("UART Baud Rate (bps):"));
CycleTextbox = new QLineEdit();
CrystalTextbox = new QLineEdit();
BaudTextbox = new QLineEdit();
CycleTextbox->setValidator(
new QRegExpValidator(
QRegExp("[0-9]+")));
CrystalTextbox->setValidator(
new QRegExpValidator(
QRegExp("[0-9]+")));
BaudTextbox->setValidator(
new QRegExpValidator(
QRegExp("[0-9]+")));
if(!UartFunctionUsed()) {
BaudTextbox->setEnabled(FALSE);
textLabel3->setEnabled(FALSE);
}
if(Prog.mcu && (Prog.mcu->whichIsa == ISA_ANSIC ||
Prog.mcu->whichIsa == ISA_INTERPRETED))
{
CrystalTextbox->setEnabled(FALSE);
textLabel2->setEnabled(FALSE);
}
ButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok
| QDialogButtonBox::Cancel, Qt::Vertical,
ConfDialog);
char explanation[1024] = "";
if(UartFunctionUsed()) {
if(Prog.mcu && Prog.mcu->uartNeeds.rxPin != 0) {
sprintf(explanation,
_("Serial (UART) will use pins %d and %d.\r\n\r\n"),
Prog.mcu->uartNeeds.rxPin, Prog.mcu->uartNeeds.txPin);
}
else {
strcpy(explanation,
_("Please select a micro with a UART.\r\n\r\n"));
}
}
else {
strcpy(explanation, _("No serial instructions (UART Send/UART Receive) "
"are in use; add one to program before setting baud rate.\r\n\r\n") );
}
strcat(explanation,
_("The cycle time for the 'PLC' runtime generated by LDmicro is user-"
"configurable. Very short cycle times may not be achievable due "
"to processor speed constraints, and very long cycle times may not "
"be achievable due to hardware overflows. Cycle times between 10 ms "
"and 100 ms will usually be practical.\r\n\r\n"
"The compiler must know what speed crystal you are using with the "
"micro to convert between timing in clock cycles and timing in "
"seconds. A 4 MHz to 20 MHz crystal is typical; check the speed "
"grade of the part you are using to determine the maximum allowable "
"clock speed before choosing a crystal."));
QLabel* textLabel4 = new QLabel(explanation);
textLabel4->setAlignment(Qt::AlignJustify);
textLabel4->setMaximumWidth(310);
textLabel4->setWordWrap(TRUE);
// Creating required containers for packing
ConfGrid->addWidget(textLabel, 0,0);
ConfGrid->addWidget(CycleTextbox, 0,1);
ConfGrid->addWidget(ButtonBox, 0, 2, 0, 2);
ConfGrid->addWidget(textLabel2, 1, 0);
ConfGrid->addWidget(CrystalTextbox, 1, 1);
ConfGrid->addWidget(textLabel3, 2, 0);
ConfGrid->addWidget(BaudTextbox, 2, 1);
ConfGrid->addWidget(textLabel4, 3, 0, 2, 0,
Qt::AlignJustify);
NiceFont(ConfDialog);
CycleTextbox->setFocus();
// int height = textLabel4->pos().y();
// printf("Height:%d\n", height);
// ConfDialog->setSize(ConfGrid->sizeHint());
ConfDialog->adjustSize();
QObject::connect(ButtonBox, SIGNAL(accepted()), ConfDialog, SLOT(accept()));
QObject::connect(ButtonBox, SIGNAL(rejected()), ConfDialog, SLOT(reject()));
// PrevCycleProc = SetWindowLongPtr(CycleTextbox, GWLP_WNDPROC,
// (LONG_PTR)MyNumberProc);
// PrevCrystalProc = SetWindowLongPtr(CrystalTextbox, GWLP_WNDPROC,
// (LONG_PTR)MyNumberProc);
// PrevBaudProc = SetWindowLongPtr(BaudTextbox, GWLP_WNDPROC,
// (LONG_PTR)MyNumberProc);
}
/*
//-----------------------------------------------------------------------------
// Don't allow any characters other than 0-9. in the text boxes.
//-----------------------------------------------------------------------------
void ConfDialogMyNumberProc (GtkEditable *editable, gchar *NewText, gint length,
gint *position, gpointer data){
gtk_widget_set_sensitive (MainWindow, TRUE);
for (int i = 0; i < length; i++){
if (!(isdigit (NewText[i]) || NewText[i] == '.' || NewText[i] == '\b')){
g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
return;
}
}
}
// Gets data from the text boxes
void ConfDialogGetData (GtkWidget* widget, gpointer data){
char* buf;
buf = const_cast (gtk_entry_get_text (GTK_ENTRY (CycleTextbox)));
Prog.cycleTime = (int)(1000*atof(buf) + 0.5);
if(Prog.cycleTime == 0) {
Error(_("Zero cycle time not valid; resetting to 10 ms."));
Prog.cycleTime = 10000;
}
buf = const_cast (gtk_entry_get_text (GTK_ENTRY(CrystalTextbox)));
Prog.mcuClock = (int)(1e6*atof(buf) + 0.5);
buf = const_cast (gtk_entry_get_text (GTK_ENTRY(BaudTextbox)));
Prog.baudRate = atoi(buf);
DestroyWindow (ConfDialog);
ProgramChanged();
}
// Checks for the required key press
gboolean ConfDialogKeyPress (GtkWidget* widget, GdkEventKey* event, gpointer data){
if (event -> keyval == GDK_KEY_Return){
ConfDialogGetData(NULL, NULL);
}
else if (event -> keyval == GDK_KEY_Escape){
DestroyWindow (ConfDialog);
ProgramChanged();
gtk_widget_set_sensitive (MainWindow, TRUE);
}
return FALSE;
}
void ConfCallDestroyWindow (HWID widget, gpointer data){
DestroyWindow (ConfDialog);
ProgramChanged();
gtk_widget_set_sensitive (MainWindow, TRUE);
}
// Consists of all the signal calls
void ConfDialogSignalCall () {
g_signal_connect (G_OBJECT(CycleTextbox), "insert-text",
G_CALLBACK(ConfDialogMyNumberProc), NULL);
g_signal_connect (G_OBJECT(CrystalTextbox), "insert-text",
G_CALLBACK(ConfDialogMyNumberProc), NULL);
g_signal_connect (G_OBJECT(BaudTextbox), "insert-text",
G_CALLBACK(ConfDialogMyNumberProc), NULL);
g_signal_connect (G_OBJECT (ConfDialog), "key-press-event",
G_CALLBACK(ConfDialogKeyPress), NULL);
g_signal_connect (G_OBJECT (OkButton), "clicked",
G_CALLBACK(ConfDialogGetData), NULL);
g_signal_connect (G_OBJECT (CancelButton), "clicked",
G_CALLBACK(ConfCallDestroyWindow), NULL);
g_signal_connect (ConfDialog, "delete_event", G_CALLBACK (ConfCallDestroyWindow), NULL);
}
*/
void ShowConfDialog(void)
{
// The window's height will be resized later, to fit the explanation text.
ConfDialog = CreateWindowClient(_("PLC Configuration"),
100, 100, 0, 0, MainWindow);
ConfGrid = new QGridLayout(ConfDialog);
MakeControls();
char buf[16];
sprintf(buf, "%.1f", (Prog.cycleTime / 1000.0));
CycleTextbox->setText(buf);
sprintf(buf, "%.6f", Prog.mcuClock / 1e6);
CrystalTextbox->setText(buf);
sprintf(buf, "%d", Prog.baudRate);
BaudTextbox->setText(buf);
int ret = ConfDialog->exec();
switch(ret)
{
case QDialog::Accepted:
{
char buf[16];
strncpy(buf, CycleTextbox->text().toStdString().c_str(),16);
Prog.cycleTime = (int)(1000*atof(buf) + 0.5);
if(Prog.cycleTime == 0) {
Error(_("Zero cycle time not valid; resetting to 10 ms."));
Prog.cycleTime = 10000;
}
strncpy(buf, CrystalTextbox->text().toStdString().c_str(),16);
Prog.mcuClock = (int)(1e6*atof(buf) + 0.5);
strncpy(buf, BaudTextbox->text().toStdString().c_str(),16);
Prog.baudRate = atoi(buf);
}
break;
case QDialog::Rejected:
break;
}
// DestroyWindow();
/* GdkEventKey* event;
ConfDialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(ConfDialog), "PLC Configuration");
gtk_window_set_default_size(GTK_WINDOW(ConfDialog), 200, 250);
gtk_window_set_resizable (GTK_WINDOW (ConfDialog), FALSE);
gtk_container_add(GTK_CONTAINER(ConfDialog), ConfPackingBox);
gtk_widget_add_events (ConfDialog, GDK_KEY_PRESS_MASK);
gtk_widget_add_events (ConfDialog, GDK_BUTTON_PRESS_MASK);
char buf[16];
sprintf(buf, "%.1f", (Prog.cycleTime / 1000.0));
gtk_entry_set_text (GTK_ENTRY (CycleTextbox), buf);
sprintf(buf, "%.6f", Prog.mcuClock / 1e6);
gtk_entry_set_text (GTK_ENTRY (CrystalTextbox), buf);
sprintf(buf, "%d", Prog.baudRate);
gtk_entry_set_text (GTK_ENTRY (BaudTextbox), buf);
gtk_widget_set_sensitive (MainWindow, FALSE);
gtk_widget_grab_focus (OkButton);
gtk_widget_set_state_flags (CycleTextbox, GTK_STATE_FLAG_FOCUSED, TRUE);
gtk_widget_grab_focus (CycleTextbox);
gtk_widget_show_all (ConfDialog);
ConfDialogSignalCall();
return;*/
}