summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNao Pross <naopross@thearcway.org>2017-08-23 16:43:56 +0200
committerNao Pross <naopross@thearcway.org>2017-08-23 16:43:56 +0200
commitc7925cbb73f319a390507b33e4df44f106822683 (patch)
treeb7890e18d481822e6f38f6739b43fbd9d02b587f
parentupdated .gitignore (diff)
downloadz80uPC-c7925cbb73f319a390507b33e4df44f106822683.tar.gz
z80uPC-c7925cbb73f319a390507b33e4df44f106822683.zip
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.
-rw-r--r--sw/programmer/avr/fileinfo.h13
-rw-r--r--sw/programmer/avr/main.c42
-rw-r--r--sw/programmer/avr/makefile2
-rw-r--r--sw/programmer/linux/src/flash.c59
-rw-r--r--sw/programmer/linux/src/flash.h22
-rw-r--r--sw/programmer/linux/src/makefile.am6
-rw-r--r--sw/programmer/linux/src/serial.c3
-rw-r--r--sw/programmer/linux/src/serial.h6
-rw-r--r--sw/programmer/linux/src/ui.c126
-rw-r--r--sw/programmer/linux/src/ui.h11
-rwxr-xr-xsw/programmer/linux/src/z80progbin34688 -> 48160 bytes
-rw-r--r--sw/programmer/linux/src/z80prog.ui43
12 files changed, 234 insertions, 99 deletions
diff --git a/sw/programmer/avr/fileinfo.h b/sw/programmer/avr/fileinfo.h
deleted file mode 100644
index 6c831ed..0000000
--- a/sw/programmer/avr/fileinfo.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __FILEINFO_H__
-#define __FILEINFO_H__
-
-#include <stdio.h>
-
-struct file_info
-{
- size_t size;
- size_t blklen;
- uint16_t start_addr;
-};
-
-#endif
diff --git a/sw/programmer/avr/main.c b/sw/programmer/avr/main.c
index 90d05fa..9cdc35d 100644
--- a/sw/programmer/avr/main.c
+++ b/sw/programmer/avr/main.c
@@ -1,5 +1,6 @@
-#include "fileinfo.h"
#include "usart.h"
+
+#include <stdio.h>
#include <util/delay.h>
#define EEPROM_TICK_MS 10
@@ -18,6 +19,11 @@
#define EEPROM_RD 1
#define EEPROM_CLK 2
+struct file_blk
+{
+ uint16_t addr;
+ uint16_t size;
+};
void eeprom_write(uint16_t addr, uint8_t byte);
void eeprom_tick();
@@ -25,10 +31,10 @@ void eeprom_tick();
int main(void)
{
uint8_t *buffer, i;
- uint16_t addr;
size_t read;
+ char str[64];
- struct file_info *finfo = malloc(sizeof(struct file_info));
+ struct file_blk *blk = malloc(sizeof(struct file_blk));
DDRB = 0x7F;
DDRC = 0x83;
@@ -36,28 +42,32 @@ int main(void)
/* get configuration */
usart_init(1200);
+ usart_print("programmer Ready\n<waiting for binary>\n\r");
- usart_print("EEPROM Programmer\n\r");
-
- do {
- usart_print("Waiting for configuration\n\r");
- read = usart_read((uint8_t *) finfo, sizeof(struct file_info));
- } while (read != sizeof(struct file_info));
+ while (usart_read((uint8_t *) blk, sizeof(struct file_blk))) {
+ buffer = malloc(blk->size);
+ read = usart_read(buffer, blk->size);
- usart_print("Programmer Ready\n<waiting for binary>\n\r");
+#ifdef DEBUG
+ sprintf(str, "info : reading block from addr %d of size %d\n\r",
+ blk->addr, blk->size);
+ usart_print(str);
- buffer = malloc(finfo->blklen);
- addr = finfo->start_addr;
+ if (read != blk->size) {
+ sprintf(str, "error: expected %d but read %d\n\r",
+ blk->size, read);
+ usart_print(str);
+ }
+#endif
- /* read file */
- while ((read = usart_read(buffer, finfo->blklen))) {
for (i = 0; i < read; i++) {
- eeprom_write(addr + i, *(buffer++));
+ eeprom_write(blk->addr +i, buffer[i]);
}
- addr += finfo->blklen;
+ free(buffer);
}
+ free(blk);
return 0;
}
diff --git a/sw/programmer/avr/makefile b/sw/programmer/avr/makefile
index 95fb5fe..ba2a709 100644
--- a/sw/programmer/avr/makefile
+++ b/sw/programmer/avr/makefile
@@ -12,7 +12,7 @@ PORT := /dev/ttyUSB0
MCU := atmega328p
CFLAGS := -g -Wall -mcall-prologues -mmcu=$(MCU) -Os -I . \
- -DF_CPU=1000000UL
+ -DF_CPU=1000000UL -DDEBUG
LDFLAGS := -Wl,-gc-sections -Wl,-relax
.PHONY: all clean program
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 <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#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 <fcntl.h>
#include <termios.h>
-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 <stdbool.h>
#include <string.h>
#include <gtk/gtk.h>
+#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
--- a/sw/programmer/linux/src/z80prog
+++ b/sw/programmer/linux/src/z80prog
Binary files 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 @@
<object class="GtkEntry" id="devpath">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="placeholder_text" translatable="yes">Enter path</property>
+ <property name="text" translatable="yes">/dev/tty</property>
+ <property name="placeholder_text" translatable="yes">Enter device path</property>
</object>
<packing>
<property name="expand">True</property>
@@ -59,14 +60,14 @@
<property name="width_chars">0</property>
<property name="max_width_chars">7</property>
<property name="overwrite_mode">True</property>
- <property name="placeholder_text" translatable="yes">9600</property>
+ <property name="placeholder_text" translatable="yes">1200</property>
<property name="input_purpose">number</property>
<property name="adjustment">baudrateadjust</property>
<property name="climb_rate">10</property>
<property name="snap_to_ticks">True</property>
<property name="numeric">True</property>
<property name="update_policy">if-valid</property>
- <property name="value">9600</property>
+ <property name="value">1200</property>
</object>
<packing>
<property name="expand">False</property>
@@ -104,7 +105,7 @@
<object class="GtkEntry" id="filepath">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="placeholder_text" translatable="yes">Binary Path</property>
+ <property name="placeholder_text" translatable="yes">Enter binary path</property>
</object>
<packing>
<property name="expand">True</property>
@@ -173,21 +174,21 @@
</packing>
</child>
<child>
- <object class="GtkScrolledWindow" id="logscrolled">
+ <object class="GtkViewport" id="logviewport">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="shadow_type">in</property>
+ <property name="can_focus">False</property>
<child>
- <object class="GtkViewport" id="logviewport">
+ <object class="GtkExpander" id="logexpander">
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="can_focus">True</property>
+ <property name="expanded">True</property>
+ <property name="label_fill">True</property>
+ <property name="resize_toplevel">True</property>
<child>
- <object class="GtkExpander" id="logexpander">
+ <object class="GtkScrolledWindow" id="logscroller">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="expanded">True</property>
- <property name="label_fill">True</property>
- <property name="resize_toplevel">True</property>
+ <property name="shadow_type">in</property>
<child>
<object class="GtkTextView" id="logview">
<property name="visible">True</property>
@@ -198,13 +199,13 @@
<property name="monospace">True</property>
</object>
</child>
- <child type="label">
- <object class="GtkLabel" id="loglabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Logs</property>
- </object>
- </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="loglabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Logs</property>
</object>
</child>
</object>
@@ -213,7 +214,7 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">4</property>
+ <property name="position">3</property>
</packing>
</child>
</object>