stm32-serial-flash/main.c

182 lines
4.6 KiB
C

/*
* Description: STM32 Microcontroller flashing utility
* Author: Mario Hüttel
*
* Version: 0.1
* License: --
*
*
*/
#include <stdio.h>
#include <gtk/gtk.h>
#include <string.h>
#include <stdint.h>
#include <pthread.h>
#define ISOPT(var) (!strcmp(argv[i], var))
#define GETOPT(var) if (++i < argc) strcpy(var, argv[i])
#define MAXPARAMLENGTH 100
enum ValueAvail {hasNoVal, hasVal};
typedef struct _parameter {
char *name;
enum ValueAvail hasValue;
void *value;
} parameter;
typedef struct _builderWidget {
char *widgetId;
GtkWidget **widget;
}builderWidget;
struct flasher {
gboolean is_active;
GtkWidget **progressBar;
GtkWidget **fileEntry;
GtkWidget **portEntry;
};
static gboolean main_window_close(GtkWidget *widget, gpointer foo)
{
struct flasher *flash = (struct flasher *)foo;
if (flash->is_active == TRUE) {
g_print("Flashing operation in progress. Can't close window.\n");
return TRUE;
}
gtk_widget_destroy(widget);
gtk_main_quit();
return TRUE;
}
void parseParams(parameter *progParams, int argc, char **argv);
void parseBuilder(GtkBuilder *builder, builderWidget *builderWidgets);
void startFlash();
int main(int argc, char *argv[]) {
static int gui = 0;
static char port[MAXPARAMLENGTH] = {0};
static char fileName[MAXPARAMLENGTH] = {0};
static GtkWidget *startButton;
static GtkWidget *fileDialogButton;
static GtkWidget *main_window;
static GtkWidget *fileEntry;
static GtkWidget *portEntry;
static GtkWidget *progressBar;
static GtkWidget *fileDialog;
static struct flasher stmFlasher =
{ .is_active = FALSE
};
static parameter progParams[] = {
{
.name = "--gui",
.hasValue = hasNoVal,
.value = (void*)&gui
},
{.name = "--port",.hasValue = hasVal,.value = (void*)port},{.name = "--file",.hasValue = hasVal,.value = (void*)fileName},{.name = NULL}};
static builderWidget builderWidgets[] = {
{
.widgetId = "startButton",
.widget = &startButton
},
{
.widgetId = "fileDialogButton",
.widget = &fileDialogButton
},
{
.widgetId = "fileEntry",
.widget = &fileEntry
},
{
.widgetId = "portEntry",
.widget = &portEntry
},
{
.widgetId = "progressBar",
.widget = &progressBar
},
{
.widgetId = "Dialog",
.widget = &fileDialog
},
{
.widgetId = "mainWindow",
.widget = &main_window
},
{
.widgetId = NULL,
.widget = NULL
}
};
GtkBuilder *builder;
parseParams(progParams, argc, argv);
// Create flasher and fill elements
// TODO: remove widgets from flasher. use strings instead
stmFlasher.fileEntry = &fileEntry;
stmFlasher.portEntry = &portEntry;
// TODO: above
if (gui) {
gtk_init(&argc, &argv);
g_object_set(gtk_settings_get_default(),
"gtk-application-prefer-dark-theme", TRUE,
NULL);
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "window.glade", NULL);
//Get Widgets from Builder
parseBuilder(builder, builderWidgets);
g_signal_connect(startButton, "clicked", G_CALLBACK(startFlash), &stmFlasher);
g_signal_connect(main_window, "delete-event", G_CALLBACK(main_window_close), &stmFlasher);
gtk_main();
} else {
startFlash(&stmFlasher);
}
return 0;
}
void startFlash(struct flasher *flashObj) {
printf("Flasher started\n");
return;
}
void parseParams(parameter* progParams, int argc, char **argv)
{
int i = 0;
parameter* paramptr = NULL;
for (i = 0; i < argc; i++) {
for (paramptr = progParams; paramptr->name; paramptr++) {
if (paramptr->hasValue == hasNoVal) *(int*)paramptr->value = 0;
if (ISOPT(paramptr->name))
{
if (paramptr->hasValue == hasNoVal) {
*(int*)paramptr->value = 1;
} else {
printf("setting\n");
GETOPT((char*)paramptr->value);
}
}
}
}
}
void parseBuilder(GtkBuilder *builder, builderWidget *builderWidgets) {
builderWidget *ptr = NULL;
for (ptr = builderWidgets; ptr->widgetId;ptr++) {
*(ptr->widget) = GTK_WIDGET(gtk_builder_get_object(builder, (gchar*)ptr->widgetId));
}
}