From d0801b36b47d8f3da610597160fde92059fd7e62 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Mon, 7 Aug 2017 19:27:05 +0200 Subject: implementation for avr programmer the programmer will receive the binary in blocks of defined size by a program under sw/programmer/linux (moved from sw/linux). --- sw/programmer/linux/src/main.c | 13 +++ sw/programmer/linux/src/makefile.am | 7 ++ sw/programmer/linux/src/serial.c | 42 +++++++ sw/programmer/linux/src/serial.h | 17 +++ sw/programmer/linux/src/ui.c | 90 +++++++++++++++ sw/programmer/linux/src/ui.h | 17 +++ sw/programmer/linux/src/z80prog | Bin 0 -> 34688 bytes sw/programmer/linux/src/z80prog.ui | 222 ++++++++++++++++++++++++++++++++++++ 8 files changed, 408 insertions(+) create mode 100644 sw/programmer/linux/src/main.c create mode 100644 sw/programmer/linux/src/makefile.am create mode 100644 sw/programmer/linux/src/serial.c create mode 100644 sw/programmer/linux/src/serial.h create mode 100644 sw/programmer/linux/src/ui.c create mode 100644 sw/programmer/linux/src/ui.h create mode 100755 sw/programmer/linux/src/z80prog create mode 100644 sw/programmer/linux/src/z80prog.ui (limited to 'sw/programmer/linux/src') diff --git a/sw/programmer/linux/src/main.c b/sw/programmer/linux/src/main.c new file mode 100644 index 0000000..769992a --- /dev/null +++ b/sw/programmer/linux/src/main.c @@ -0,0 +1,13 @@ +#include "config.h" +#include "ui.h" + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + ui_init(&argc, &argv); + return 0; +} + diff --git a/sw/programmer/linux/src/makefile.am b/sw/programmer/linux/src/makefile.am new file mode 100644 index 0000000..492c3ec --- /dev/null +++ b/sw/programmer/linux/src/makefile.am @@ -0,0 +1,7 @@ +bin_PROGRAMS = z80prog +z80prog_SOURCES = main.c ui.c serial.c + +z80prog_CFLAGS = -Wall -Werror -g $(gtk3_CFLAGS) +z80prog_LDADD = $(gtk3_LIBS) + +CLEANFILES = *~ diff --git a/sw/programmer/linux/src/serial.c b/sw/programmer/linux/src/serial.c new file mode 100644 index 0000000..564676b --- /dev/null +++ b/sw/programmer/linux/src/serial.c @@ -0,0 +1,42 @@ +#include "serial.h" + +int serial_connect(const char *devpath, long baudrate) +{ + int fd; + struct termios tty; + // struct termios tty_old; + + // open device + if ((fd = open(devpath, O_RDWR | O_NOCTTY)) < 0) { + return -1; + } + + // set parameters + if (tcgetattr(fd, &tty) != 0) { + return -1; + } + + // TODO: update UI or add support for custom baudrate + // cfsetospeed(&tty, + // cfsetispeed(&tty, + + tty.c_cflag &= ~PARENB; // no parity + tty.c_cflag &= ~CSTOPB; // no stop bit + tty.c_cflag |= CS8; // 8 bit data + tty.c_cflag &= ~CRTSCTS; // no flow control + + tty.c_lflag = 0; // no signaling chars, no echo, no canonical processing + tty.c_oflag = 0; // no remapping, no delays + tty.c_cc[VMIN] = 0; // no block read + tty.c_cc[VTIME] = .5; // .5 seconds read timeout + + tty.c_cflag |= CREAD | CLOCAL; // turn on read and ignore ctrl lines + tty.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl + tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw + tty.c_oflag &= ~OPOST; // make raw + + tcflush(fd , TCIFLUSH); + // if (tcsetaddr( + + return fd; +} diff --git a/sw/programmer/linux/src/serial.h b/sw/programmer/linux/src/serial.h new file mode 100644 index 0000000..6123e42 --- /dev/null +++ b/sw/programmer/linux/src/serial.h @@ -0,0 +1,17 @@ +#ifndef __Z80PROG_SERIAL_H__ +#define __Z80PROG_SERIAL_H__ + +#include +#include +#include +#include +#include +#include + +int serial_connect(const char *devpath, long baudrate); +void serial_close(int fd); + +void serial_program(const char *rompath); +void serial_read_rom(const char *rom); + +#endif diff --git a/sw/programmer/linux/src/ui.c b/sw/programmer/linux/src/ui.c new file mode 100644 index 0000000..b33aa04 --- /dev/null +++ b/sw/programmer/linux/src/ui.c @@ -0,0 +1,90 @@ +#include "ui.h" + +static bool ui_connected, ui_fileset; +static GtkTextBuffer *ui_logbuf; +static GtkBuilder *ui_builder; + +void ui_init(int *argc, char **argv[]) +{ + GtkWindow *window; + GtkTextView *logview; + GtkFileChooserButton *filechoosebtn; + GtkButton *connectbtn, *flashbtn; + + /* set ui global variables */ + ui_connected = ui_fileset = false; + + /* start gtk */ + gtk_init(argc, argv); + + /* load glade gtk ui */ + ui_builder = gtk_builder_new(); + gtk_builder_add_from_file(ui_builder, "gbprog.ui", NULL); + + /* connect logger buffer (extern variable) */ + ui_logbuf = gtk_text_buffer_new(NULL); + logview = GTK_TEXT_VIEW(gtk_builder_get_object(ui_builder, "logview")); + + gtk_text_view_set_buffer(logview, ui_logbuf); + + /* connect objects to function calls */ + // window + window = GTK_WINDOW(gtk_builder_get_object(ui_builder, "window")); + g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + + // connectbtn + connectbtn = GTK_BUTTON(gtk_builder_get_object(ui_builder, "flashbtn")); + g_signal_connect(connectbtn, "clicked", + G_CALLBACK(ui_connect_clicked), NULL); + + // flashbtn + flashbtn = GTK_BUTTON(gtk_builder_get_object(ui_builder, "flashbtn")); + g_signal_connect(flashbtn, "clicked", G_CALLBACK(ui_flash_clicked), NULL); + + // file chooser + filechoosebtn = GTK_FILE_CHOOSER_BUTTON( + gtk_builder_get_object(ui_builder, "filechoosebtn")); + g_signal_connect(filechoosebtn, "file-set", G_CALLBACK(ui_file_set), NULL); + + /* start gtk window */ + gtk_main(); +} + +void ui_log(const char *msg, char type) +{ + GtkTextIter end; + gchar typech[4] = "[ ] "; + + switch (type) { + case 'm': typech[1] = '@'; break; // message + case 'w': typech[1] = '#'; break; // warning + case 'e': typech[1] = '!'; break; // error + } + + gtk_text_buffer_get_end_iter(ui_logbuf, &end); + gtk_text_buffer_insert(ui_logbuf, &end, typech, 4); + gtk_text_buffer_get_end_iter(ui_logbuf, &end); + gtk_text_buffer_insert(ui_logbuf, &end, (const gchar *) msg, strlen(msg)); +} + +void ui_file_set(GtkFileChooserButton *btn, gpointer user_data) +{ + GtkEntry *filepath = + GTK_ENTRY(gtk_builder_get_object(ui_builder, "filepath")); + + gtk_entry_set_text(filepath, + gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(btn))); + + ui_log("File set\n", 'm'); + ui_fileset = true; +} + +void ui_connect_clicked(void) +{ + +} + +void ui_flash_clicked(void) +{ + +} diff --git a/sw/programmer/linux/src/ui.h b/sw/programmer/linux/src/ui.h new file mode 100644 index 0000000..44314d6 --- /dev/null +++ b/sw/programmer/linux/src/ui.h @@ -0,0 +1,17 @@ +#ifndef __Z80PROG_UI_H__ +#define __Z80PROG_UI_H_ + +#include +#include + +#include + +void ui_init(int *argc, char **argv[]); +void ui_log(const char *msg, char type); + +void ui_file_set(GtkFileChooserButton *btn, gpointer user_data); + +void ui_connect_clicked(void); +void ui_flash_clicked(void); + +#endif diff --git a/sw/programmer/linux/src/z80prog b/sw/programmer/linux/src/z80prog new file mode 100755 index 0000000..878683b Binary files /dev/null and b/sw/programmer/linux/src/z80prog differ diff --git a/sw/programmer/linux/src/z80prog.ui b/sw/programmer/linux/src/z80prog.ui new file mode 100644 index 0000000..3735efa --- /dev/null +++ b/sw/programmer/linux/src/z80prog.ui @@ -0,0 +1,222 @@ + + + + + + 1000000 + 9600 + 1 + 10 + + + + *.bin + *.gb + *.gba + *.gbc + *.hex + + + + 450 + 250 + True + False + Z80 ROM Programmer + 450 + 200 + + + True + False + 10 + 10 + 10 + 10 + vertical + 10 + + + True + False + 10 + + + True + True + Enter path + + + True + True + 0 + + + + + True + True + 0 + 7 + True + 9600 + number + baudrateadjust + 10 + True + True + if-valid + 9600 + + + False + True + 1 + + + + + gtk-connect + True + True + True + True + + + False + True + 2 + + + + + False + True + 0 + + + + + True + False + 10 + + + True + True + Binary Path + + + True + True + 0 + + + + + True + False + gbbinfilter + + + + False + True + 1 + + + + + False + True + 1 + + + + + True + False + vertical + 10 + + + True + False + True + start + + + True + True + 0 + + + + + Flash + True + False + True + True + + + False + True + 1 + + + + + False + True + 2 + + + + + True + True + in + + + True + False + + + True + True + True + True + True + + + True + True + True + True + False + True + + + + + True + False + Logs + + + + + + + + + True + True + 4 + + + + + + -- cgit v1.2.1 From c7925cbb73f319a390507b33e4df44f106822683 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Wed, 23 Aug 2017 16:43:56 +0200 Subject: new programmer interface for linux there is a new program with GUI (gtk3) to send data to its avr conterpart. it needs to be tested, since there may be a few bugs in it; building a GUI was a terrible idea. --- sw/programmer/linux/src/flash.c | 59 +++++++++++++++++ sw/programmer/linux/src/flash.h | 22 +++++++ sw/programmer/linux/src/makefile.am | 6 +- sw/programmer/linux/src/serial.c | 3 +- sw/programmer/linux/src/serial.h | 6 +- sw/programmer/linux/src/ui.c | 126 +++++++++++++++++++++++++----------- sw/programmer/linux/src/ui.h | 11 +++- sw/programmer/linux/src/z80prog | Bin 34688 -> 48160 bytes sw/programmer/linux/src/z80prog.ui | 43 ++++++------ 9 files changed, 207 insertions(+), 69 deletions(-) create mode 100644 sw/programmer/linux/src/flash.c create mode 100644 sw/programmer/linux/src/flash.h (limited to 'sw/programmer/linux/src') diff --git a/sw/programmer/linux/src/flash.c b/sw/programmer/linux/src/flash.c new file mode 100644 index 0000000..48189da --- /dev/null +++ b/sw/programmer/linux/src/flash.c @@ -0,0 +1,59 @@ +#include "flash.h" + +static int flash_serial_fd = -1; + +int flash_open(const char *path, unsigned long baudrate) +{ + flash_serial_fd = serial_open(path, baudrate); + + if (flash_serial_fd < 0) + return -1; + + return 0; +} + +int flash_write(const char *romfile, void (*log)(const char *)) +{ + int romfd; + ssize_t written; + + struct stat romst; + struct flash_blk head; + + uint8_t *buffer = malloc(FLASH_BLOCK_SIZE); + + romfd = open(romfile, O_RDONLY); + + if (fstat(romfd, &romst) != 0) + goto exit_romfd; + + while ((head.size = read(romfd, buffer, FLASH_BLOCK_SIZE))) { + head.addr = (uint16_t) lseek(romfd, 0, SEEK_CUR); + + written = write(flash_serial_fd, &head, sizeof(struct flash_blk)); + if (written < 0) { + // error + } + + written = write(flash_serial_fd, buffer, head.size); + if (written < 0) { + // error + } + + char logbuf[64]; + sprintf(logbuf, "[@] Written %d bytes at address %d\n", head.size, head.addr); + log(logbuf); + } + +exit_romfd: + close(romfd); + + free(buffer); + return 0; +} + +void flash_close(void) +{ + if (flash_serial_fd >= 0) + close(flash_serial_fd); +} \ No newline at end of file diff --git a/sw/programmer/linux/src/flash.h b/sw/programmer/linux/src/flash.h new file mode 100644 index 0000000..373ebf3 --- /dev/null +++ b/sw/programmer/linux/src/flash.h @@ -0,0 +1,22 @@ +#ifndef __FLASH_H__ +#define __FLASH_H__ + +#include "serial.h" + +#include +#include +#include + +#define FLASH_BLOCK_SIZE 512 + +struct flash_blk +{ + uint16_t addr; + uint16_t size; +}; + +int flash_open(const char *devpath, unsigned long baudrate); +int flash_write(const char *romfile, void (*log)(const char *)); +void flash_close(void); + +#endif diff --git a/sw/programmer/linux/src/makefile.am b/sw/programmer/linux/src/makefile.am index 492c3ec..33ae438 100644 --- a/sw/programmer/linux/src/makefile.am +++ b/sw/programmer/linux/src/makefile.am @@ -1,7 +1,7 @@ bin_PROGRAMS = z80prog -z80prog_SOURCES = main.c ui.c serial.c +z80prog_SOURCES = main.c ui.c serial.c flash.c -z80prog_CFLAGS = -Wall -Werror -g $(gtk3_CFLAGS) -z80prog_LDADD = $(gtk3_LIBS) +z80prog_CFLAGS = -Wall -g $(gtk3_CFLAGS) -pthread +z80prog_LDADD = $(gtk3_LIBS) CLEANFILES = *~ diff --git a/sw/programmer/linux/src/serial.c b/sw/programmer/linux/src/serial.c index 564676b..e2544be 100644 --- a/sw/programmer/linux/src/serial.c +++ b/sw/programmer/linux/src/serial.c @@ -1,6 +1,6 @@ #include "serial.h" -int serial_connect(const char *devpath, long baudrate) +int serial_open(const char *devpath, unsigned long baudrate) { int fd; struct termios tty; @@ -40,3 +40,4 @@ int serial_connect(const char *devpath, long baudrate) return fd; } + diff --git a/sw/programmer/linux/src/serial.h b/sw/programmer/linux/src/serial.h index 6123e42..fe21524 100644 --- a/sw/programmer/linux/src/serial.h +++ b/sw/programmer/linux/src/serial.h @@ -8,10 +8,6 @@ #include #include -int serial_connect(const char *devpath, long baudrate); -void serial_close(int fd); - -void serial_program(const char *rompath); -void serial_read_rom(const char *rom); +int serial_open(const char *devpath, unsigned long baudrate); #endif diff --git a/sw/programmer/linux/src/ui.c b/sw/programmer/linux/src/ui.c index b33aa04..87dc0c7 100644 --- a/sw/programmer/linux/src/ui.c +++ b/sw/programmer/linux/src/ui.c @@ -1,90 +1,142 @@ #include "ui.h" static bool ui_connected, ui_fileset; -static GtkTextBuffer *ui_logbuf; static GtkBuilder *ui_builder; void ui_init(int *argc, char **argv[]) { GtkWindow *window; - GtkTextView *logview; GtkFileChooserButton *filechoosebtn; GtkButton *connectbtn, *flashbtn; - /* set ui global variables */ ui_connected = ui_fileset = false; - /* start gtk */ gtk_init(argc, argv); - /* load glade gtk ui */ ui_builder = gtk_builder_new(); - gtk_builder_add_from_file(ui_builder, "gbprog.ui", NULL); + gtk_builder_add_from_file(ui_builder, "z80prog.ui", NULL); - /* connect logger buffer (extern variable) */ - ui_logbuf = gtk_text_buffer_new(NULL); - logview = GTK_TEXT_VIEW(gtk_builder_get_object(ui_builder, "logview")); - - gtk_text_view_set_buffer(logview, ui_logbuf); - - /* connect objects to function calls */ - // window + /* connect objects to callbacks */ window = GTK_WINDOW(gtk_builder_get_object(ui_builder, "window")); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); - // connectbtn - connectbtn = GTK_BUTTON(gtk_builder_get_object(ui_builder, "flashbtn")); - g_signal_connect(connectbtn, "clicked", - G_CALLBACK(ui_connect_clicked), NULL); + connectbtn = GTK_BUTTON(gtk_builder_get_object(ui_builder, "connectbtn")); + g_signal_connect(connectbtn, "clicked", G_CALLBACK(ui_connect_clicked), NULL); - // flashbtn flashbtn = GTK_BUTTON(gtk_builder_get_object(ui_builder, "flashbtn")); g_signal_connect(flashbtn, "clicked", G_CALLBACK(ui_flash_clicked), NULL); - // file chooser - filechoosebtn = GTK_FILE_CHOOSER_BUTTON( - gtk_builder_get_object(ui_builder, "filechoosebtn")); + filechoosebtn = GTK_FILE_CHOOSER_BUTTON(gtk_builder_get_object(ui_builder, "filechoosebtn")); g_signal_connect(filechoosebtn, "file-set", G_CALLBACK(ui_file_set), NULL); /* start gtk window */ gtk_main(); } -void ui_log(const char *msg, char type) +void ui_log(const char *msg) { GtkTextIter end; - gchar typech[4] = "[ ] "; + GtkTextView *ui_log; + + static GtkTextBuffer *ui_logbuf = NULL; + + ui_log = GTK_TEXT_VIEW(gtk_builder_get_object(ui_builder, "logview")); - switch (type) { - case 'm': typech[1] = '@'; break; // message - case 'w': typech[1] = '#'; break; // warning - case 'e': typech[1] = '!'; break; // error + if (ui_logbuf == NULL) { + ui_logbuf = gtk_text_buffer_new(NULL); + gtk_text_view_set_buffer(ui_log, ui_logbuf); } gtk_text_buffer_get_end_iter(ui_logbuf, &end); - gtk_text_buffer_insert(ui_logbuf, &end, typech, 4); - gtk_text_buffer_get_end_iter(ui_logbuf, &end); - gtk_text_buffer_insert(ui_logbuf, &end, (const gchar *) msg, strlen(msg)); + gtk_text_buffer_insert(ui_logbuf, &end, msg, -1); + gtk_text_view_scroll_to_iter(ui_log, &end, .0, TRUE, .0, .1); } -void ui_file_set(GtkFileChooserButton *btn, gpointer user_data) +void ui_check_enable_flashbtn(void) { - GtkEntry *filepath = - GTK_ENTRY(gtk_builder_get_object(ui_builder, "filepath")); + GtkWidget *ui_flashbtn = GTK_WIDGET(gtk_builder_get_object(ui_builder, "flashbtn")); - gtk_entry_set_text(filepath, - gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(btn))); + if (ui_connected && ui_fileset) + gtk_widget_set_sensitive(ui_flashbtn, TRUE); + else + gtk_widget_set_sensitive(ui_flashbtn, FALSE); +} - ui_log("File set\n", 'm'); +void ui_file_set(GtkFileChooserButton *btn, gpointer user_data) +{ + GtkEntry *filepath = GTK_ENTRY(gtk_builder_get_object(ui_builder, "filepath")); + + gtk_entry_set_text(filepath, gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(btn))); + ui_log(UI_LOG_MSG "file set\n"); ui_fileset = true; + + ui_check_enable_flashbtn(); } void ui_connect_clicked(void) { + GtkEntry *ui_devpath = GTK_ENTRY(gtk_builder_get_object(ui_builder, "devpath")); + GtkSpinButton *ui_baudrate = GTK_SPIN_BUTTON(gtk_builder_get_object(ui_builder, "devbaudrate")); + GtkButton *ui_connectbtn = GTK_BUTTON(gtk_builder_get_object(ui_builder, "connectbtn")); + + unsigned long baudrate = gtk_spin_button_get_value_as_int(ui_baudrate); + const char *devpath = gtk_entry_get_text(ui_devpath); + + if (flash_open(devpath, baudrate) != 0) { + ui_log(UI_LOG_ERR "failed to open serial device\n"); + } else { + ui_connected = true; + ui_log(UI_LOG_MSG "connected to serial device "); + ui_log(devpath); + ui_log("\n"); + + g_signal_handlers_disconnect_by_func(ui_connectbtn, G_CALLBACK(ui_connect_clicked), NULL); + g_signal_connect(ui_connectbtn, "clicked", G_CALLBACK(ui_disconnect_clicked), NULL); + + gtk_button_set_label(ui_connectbtn, "gtk-disconnect"); + ui_check_enable_flashbtn(); + } +} +void ui_disconnect_clicked(void) +{ + GtkButton *ui_connectbtn = GTK_BUTTON(gtk_builder_get_object(ui_builder, "connectbtn")); + + flash_close(); + + ui_connected = false; + ui_log(UI_LOG_MSG "disconnected\n"); + + g_signal_handlers_disconnect_by_func(ui_connectbtn, G_CALLBACK(ui_disconnect_clicked), NULL); + g_signal_connect(ui_connectbtn, "clicked", G_CALLBACK(ui_connect_clicked), NULL); + + gtk_button_set_label(ui_connectbtn, "gtk-connect"); + ui_check_enable_flashbtn(); +} + +int ui_flash_write_start(void *ptr) +{ + const char *filepath = (const char *) ptr; + + flash_write(filepath, ui_log); + ui_check_enable_flashbtn(); + + return 0; } void ui_flash_clicked(void) { + GtkWidget *ui_flashbtn = GTK_WIDGET(gtk_builder_get_object(ui_builder, "flashbtn")); + GtkEntry *ui_filepath = GTK_ENTRY(gtk_builder_get_object(ui_builder, "filepath")); + + const char *filepath = gtk_entry_get_text(ui_filepath); + + gdk_threads_add_idle_full( + G_PRIORITY_HIGH_IDLE, + ui_flash_write_start, + (void *) filepath, + NULL + ); + gtk_widget_set_sensitive(ui_flashbtn, FALSE); } diff --git a/sw/programmer/linux/src/ui.h b/sw/programmer/linux/src/ui.h index 44314d6..510537a 100644 --- a/sw/programmer/linux/src/ui.h +++ b/sw/programmer/linux/src/ui.h @@ -1,17 +1,24 @@ #ifndef __Z80PROG_UI_H__ #define __Z80PROG_UI_H_ +#include "flash.h" + #include #include #include +#define UI_LOG_ERR "[!] " +#define UI_LOG_WARN "[#] " +#define UI_LOG_MSG "[@] " + void ui_init(int *argc, char **argv[]); -void ui_log(const char *msg, char type); +void ui_log(const char *msg); +void ui_check_enable_flashbtn(void); void ui_file_set(GtkFileChooserButton *btn, gpointer user_data); - void ui_connect_clicked(void); +void ui_disconnect_clicked(void); void ui_flash_clicked(void); #endif diff --git a/sw/programmer/linux/src/z80prog b/sw/programmer/linux/src/z80prog index 878683b..2f0d230 100755 Binary files a/sw/programmer/linux/src/z80prog and b/sw/programmer/linux/src/z80prog differ diff --git a/sw/programmer/linux/src/z80prog.ui b/sw/programmer/linux/src/z80prog.ui index 3735efa..6c652ec 100644 --- a/sw/programmer/linux/src/z80prog.ui +++ b/sw/programmer/linux/src/z80prog.ui @@ -44,7 +44,8 @@ True True - Enter path + /dev/tty + Enter device path True @@ -59,14 +60,14 @@ 0 7 True - 9600 + 1200 number baudrateadjust 10 True True if-valid - 9600 + 1200 False @@ -104,7 +105,7 @@ True True - Binary Path + Enter binary path True @@ -173,21 +174,21 @@ - + True - True - in + False - + True - False + True + True + True + True - + True True - True - True - True + in True @@ -198,13 +199,13 @@ True - - - True - False - Logs - - + + + + + True + False + Logs @@ -213,7 +214,7 @@ True True - 4 + 3 -- cgit v1.2.1