diff options
-rw-r--r-- | .gitignore | 54 | ||||
-rw-r--r-- | sw/linux/src/makefile.am | 7 | ||||
-rw-r--r-- | sw/linux/src/ui.c | 90 | ||||
-rwxr-xr-x | sw/linux/src/z80prog | bin | 34688 -> 0 bytes | |||
-rw-r--r-- | sw/programmer/avr/main.c | 119 | ||||
-rw-r--r-- | sw/programmer/avr/makefile | 31 | ||||
-rw-r--r-- | sw/programmer/avr/usart.c | 107 | ||||
-rw-r--r-- | sw/programmer/avr/usart.h | 96 | ||||
-rw-r--r-- | sw/programmer/linux/config.h (renamed from sw/linux/config.h) | 0 | ||||
-rw-r--r-- | sw/programmer/linux/configure.ac (renamed from sw/linux/configure.ac) | 0 | ||||
-rw-r--r-- | sw/programmer/linux/makefile.am (renamed from sw/linux/makefile.am) | 0 | ||||
-rw-r--r-- | sw/programmer/linux/reading_links.txt (renamed from sw/linux/reading_links.txt) | 0 | ||||
-rw-r--r-- | sw/programmer/linux/src/flash.c | 59 | ||||
-rw-r--r-- | sw/programmer/linux/src/flash.h | 22 | ||||
-rw-r--r-- | sw/programmer/linux/src/main.c (renamed from sw/linux/src/main.c) | 0 | ||||
-rw-r--r-- | sw/programmer/linux/src/makefile.am | 7 | ||||
-rw-r--r-- | sw/programmer/linux/src/serial.c (renamed from sw/linux/src/serial.c) | 3 | ||||
-rw-r--r-- | sw/programmer/linux/src/serial.h (renamed from sw/linux/src/serial.h) | 6 | ||||
-rw-r--r-- | sw/programmer/linux/src/ui.c | 142 | ||||
-rw-r--r-- | sw/programmer/linux/src/ui.h (renamed from sw/linux/src/ui.h) | 11 | ||||
-rwxr-xr-x | sw/programmer/linux/src/z80prog | bin | 0 -> 48160 bytes | |||
-rw-r--r-- | sw/programmer/linux/src/z80prog.ui (renamed from sw/linux/src/z80prog.ui) | 43 |
22 files changed, 644 insertions, 153 deletions
@@ -13,33 +13,33 @@ doc/**/*.log ## sw related # autotools -sw/linux/**/makefile -sw/linux/**/makefile.in -sw/linux/**/ar-lib -sw/linux/**/mdate-sh -sw/linux/**/py-compile -sw/linux/**/test-driver -sw/linux/**/ylwrap -sw/linux/**/autom4te.cache -sw/linux/**/autoscan.log -sw/linux/**/autoscan-*.log -sw/linux/**/aclocal.m4 -sw/linux/**/compile -sw/linux/**/config.guess -sw/linux/**/config.h.in -sw/linux/**/config.log -sw/linux/**/config.status -sw/linux/**/config.sub -sw/linux/**/configure -sw/linux/**/configure.scan -sw/linux/**/depcomp -sw/linux/**/install-sh -sw/linux/**/missing -sw/linux/**/stamp-h* -sw/linux/**/build-aux -sw/linux/**/ltmain.sh -sw/linux/**/texinfo.tex -sw/linux/**/.deps +sw/programmer/linux/**/makefile +sw/programmer/linux/**/makefile.in +sw/programmer/linux/**/ar-lib +sw/programmer/linux/**/mdate-sh +sw/programmer/linux/**/py-compile +sw/programmer/linux/**/test-driver +sw/programmer/linux/**/ylwrap +sw/programmer/linux/**/autom4te.cache +sw/programmer/linux/**/autoscan.log +sw/programmer/linux/**/autoscan-*.log +sw/programmer/linux/**/aclocal.m4 +sw/programmer/linux/**/compile +sw/programmer/linux/**/config.guess +sw/programmer/linux/**/config.h.in +sw/programmer/linux/**/config.log +sw/programmer/linux/**/config.status +sw/programmer/linux/**/config.sub +sw/programmer/linux/**/configure +sw/programmer/linux/**/configure.scan +sw/programmer/linux/**/depcomp +sw/programmer/linux/**/install-sh +sw/programmer/linux/**/missing +sw/programmer/linux/**/stamp-h* +sw/programmer/linux/**/build-aux +sw/programmer/linux/**/ltmain.sh +sw/programmer/linux/**/texinfo.tex +sw/programmer/linux/**/.deps # binaries sw/**/*.hex diff --git a/sw/linux/src/makefile.am b/sw/linux/src/makefile.am deleted file mode 100644 index 492c3ec..0000000 --- a/sw/linux/src/makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -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/linux/src/ui.c b/sw/linux/src/ui.c deleted file mode 100644 index b33aa04..0000000 --- a/sw/linux/src/ui.c +++ /dev/null @@ -1,90 +0,0 @@ -#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/linux/src/z80prog b/sw/linux/src/z80prog Binary files differdeleted file mode 100755 index 878683b..0000000 --- a/sw/linux/src/z80prog +++ /dev/null diff --git a/sw/programmer/avr/main.c b/sw/programmer/avr/main.c new file mode 100644 index 0000000..9cdc35d --- /dev/null +++ b/sw/programmer/avr/main.c @@ -0,0 +1,119 @@ +#include "usart.h" + +#include <stdio.h> +#include <util/delay.h> + +#define EEPROM_TICK_MS 10 + +#define ADDRCR PORTB +#define EEPROMCR PORTC +#define EEPROMDR PORTD + +#define ADDR_BIT 0 +#define ADDR_EL 3 +#define ADDR_EH 4 +#define ADDR_DL 5 +#define ADDR_DH 6 + +#define EEPROM_WR 0 +#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(); + +int main(void) +{ + uint8_t *buffer, i; + size_t read; + char str[64]; + + struct file_blk *blk = malloc(sizeof(struct file_blk)); + + DDRB = 0x7F; + DDRC = 0x83; + DDRD = 0xFC; + + /* get configuration */ + usart_init(1200); + usart_print("programmer Ready\n<waiting for binary>\n\r"); + + while (usart_read((uint8_t *) blk, sizeof(struct file_blk))) { + buffer = malloc(blk->size); + read = usart_read(buffer, blk->size); + +#ifdef DEBUG + sprintf(str, "info : reading block from addr %d of size %d\n\r", + blk->addr, blk->size); + usart_print(str); + + if (read != blk->size) { + sprintf(str, "error: expected %d but read %d\n\r", + blk->size, read); + usart_print(str); + } +#endif + + for (i = 0; i < read; i++) { + eeprom_write(blk->addr +i, buffer[i]); + } + + free(buffer); + } + + free(blk); + return 0; +} + + +void eeprom_write(uint16_t addr, uint8_t byte) +{ + int bit; + + /* set address */ + for (bit = 0; bit < 8; bit++) { + // clear bit + ADDRCR &= ~0x07; + // select the bit + ADDRCR |= bit; + + // write bit for lower byte + if (addr & _BV(bit)) + ADDRCR |= _BV(ADDR_DL); + else + ADDRCR &= ~_BV(ADDR_DL); + + // write bit for higher byte + if ((addr>>8) & _BV(bit)) + ADDRCR |= _BV(ADDR_DH); + else + ADDRCR &= ~_BV(ADDR_DH); + } + + /* set data */ + EEPROMDR = byte; + EEPROMCR &= ~(_BV(ADDR_EH) | _BV(ADDR_EL)); + + /* write eeprom */ + EEPROMCR &= ~_BV(EEPROM_WR); + eeprom_tick(); + + EEPROMCR |= _BV(EEPROM_WR); + EEPROMCR |= _BV(ADDR_EH) | _BV(ADDR_EL); +} + +/* pulse the clock line for the eeprom */ +void eeprom_tick() +{ + EEPROMCR |= _BV(EEPROM_CLK); + _delay_ms(EEPROM_TICK_MS); + EEPROMCR &= ~_BV(EEPROM_CLK); + _delay_ms(EEPROM_TICK_MS); +} + diff --git a/sw/programmer/avr/makefile b/sw/programmer/avr/makefile new file mode 100644 index 0000000..ba2a709 --- /dev/null +++ b/sw/programmer/avr/makefile @@ -0,0 +1,31 @@ +### +# Project settings +# +TARGET := programmer +SOURCES := $(wildcard *.c) + +### +# Compiler settings +# +CC := avr-gcc +PORT := /dev/ttyUSB0 +MCU := atmega328p + +CFLAGS := -g -Wall -mcall-prologues -mmcu=$(MCU) -Os -I . \ + -DF_CPU=1000000UL -DDEBUG +LDFLAGS := -Wl,-gc-sections -Wl,-relax + +.PHONY: all clean program +all: $(TARGET).hex + +clean: + rm -f *.o *.hex *.obj *.bin + +$(TARGET).hex: $(TARGET).bin + avr-objcopy -R .eeprom -O ihex $(TARGET).bin $@ + +$(TARGET).bin: $(SOURCES) + $(CC) $(CFLAGS) $(SOURCES) -o $@ $(LDFLAGS) + +program: $(TARGET).hex + avrdude -p $(MCU) -c usbasp -P usb -U flash:w:$(TARGET).hex diff --git a/sw/programmer/avr/usart.c b/sw/programmer/avr/usart.c new file mode 100644 index 0000000..8c2eb38 --- /dev/null +++ b/sw/programmer/avr/usart.c @@ -0,0 +1,107 @@ +#include "usart.h" + +static uint16_t usart_baudrate; +static uint16_t usart_baud_prescale; + +void usart_init(uint16_t baudrate) +{ + // enable RX and TX + UCSR0B |= _BV(RXEN0) | _BV(TXEN0); + + // set 8 bit size char + UCSR0C |= _BV(UCSZ01) | _BV(UCSZ00); + + // set baudrate + usart_baudrate = baudrate; + usart_baud_prescale = (F_CPU / (usart_baudrate * 16)) -1; + + UBRR0L = usart_baud_prescale; + UBRR0H = usart_baud_prescale >> 8; +} + +void usart_send_byte(uint8_t data) +{ + while (!(UCSR0A & _BV(UDRE0))); + UDR0 = data; +} + +void usart_send(uint8_t *data, size_t len) +{ + uint8_t *p = data; + + while (len--) { + usart_send_byte(*(p++)); + } +} + +void usart_print(char *str) +{ + char *p = str; + size_t len = 0; + + while (*p++ != '\0') { + len++; + } + + usart_send((uint8_t *) str, len); +} + +int usart_read_byte(uint8_t *byte) +{ + uint16_t timeout = USART_TIMEOUT; + + do { + if (UCSR0A & _BV(RXC0)) { + *byte = UDR0; + return 0; + } + } while (timeout--); + + return -1; +} + +uint8_t usart_read_byte_nt(void) +{ + while ((UCSR0A & _BV(RXC0)) == 0); + return UDR0; +} + + +size_t usart_read(uint8_t *buffer, size_t len) +{ + size_t read = 0; + uint8_t *p = buffer; + + while (len--) { + if (usart_read_byte(p) == 0) { + p++; + read++; + } + } + + return read; +} + +int usart_read_line(uint8_t *buffer, size_t len) +{ + uint8_t ch; + uint8_t *p = buffer; + size_t read = 0; + + while (len--) { + if (usart_read_byte(&ch) != 0) + continue; + else + read++; + + if (ch == '\n') + break; + else + *(p++) = ch; + } + + if (ch != '\n') + return -1; + + return 0; +} diff --git a/sw/programmer/avr/usart.h b/sw/programmer/avr/usart.h new file mode 100644 index 0000000..1bb6607 --- /dev/null +++ b/sw/programmer/avr/usart.h @@ -0,0 +1,96 @@ +#ifndef __USART_H__ +#define __USART_H__ +/*** + * USART REGISTERS {{{ + * + * UCSR: control and status regisers, composed from 3 registers: + * +------------------------------------------------------------------------+ + * | UCSRA :| RXC | TXC | UDRE | FE | DOR | PE | U2X | MPCM | + * +------------------------------------------------------------------------+ + * UCSRA is a status register (read only) + * Relevant bits: + * - RXC : set to 1 if data is present on the receive buffer + * - TXC : set to 1 when data is transferred to the transfer register + * - UDRE: set to 1 when trasmit buffer is empty (data sent) + * +------------------------------------------------------------------------+ + * | UCSRB :| RXCIE | TXCIE | UDRIE | RXEN | TXEN | UCSZ2 | RXB8 | TXB8 | + * +------------------------------------------------------------------------+ + * UCSRB is used to setup hardware configuration + * Relevant bits: + * - RXCIE: RX complete interrupt enabled when set to 1 + * - TXCIE: TX complete interrupt enabled when set to 1 + * - UDRIE: data register empty interrupt enabled when set to 1 + * - RXEN : uart receiver enabled when set to 1 + * - TXEN : uart transmitter enabled when set to 1 + * +------------------------------------------------------------------------+ + * | UCSRC :| URSEL | UMSEL | UPM1 | UPM0 | USBS | UCSZ1 | UCSZ0 | UCPOL | + * +------------------------------------------------------------------------+ + * UCSRB is used to setup protocol configuration + * Relevant bits: + * - URSEL: register select (location is shared with UBRRH and UCSRC) + * - UMSEL: mode select + * 1 -> synchronous + * 0 -> asynchronous + * - UMP1 + UPM0: set parity + * 00 -> no parity + * 01 -> reserved + * 10 -> even + * 11 -> odd + * - UCSZ2 + UCSZ1 + UCSZ0: set data frame (char size) + * 000 -> 5 bit + * 001 -> 6 bit + * 010 -> 7 bit + * 011 -> 8 bit + * 100 to 110 -> reserved + * 111 -> 9 bit + * + * UBRR: baudrate register + * +------------------------------------------------------------------------+ + * | UBRRH :| URSEL | | | | UBRR11| UBRR10| UBRR9 | UBRR8 | + * +------------------------------------------------------------------------+ + * | UBRRL :| UBRR7 | UBRR6 | UBRR5 | UBRR4 | UBRR3 | UBRR2 | UBRR1 | UBRR0 | + * +------------------------------------------------------------------------+ + * UBRR is composed of 2 8 bit registers to store a 12 bit baudrate value. + * The value to be stored in this register is calculated with the following + * formula (approximate to integer): + * UBRR = ( XTAL_frequency ) / ( 16 * BAUDRATE ) -1 + * + * in C code corresponds to: + * #define USART_BAUDRATE 9600 + * #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) + * + * Relevant bits: + * - URSEL: register select (location is share with UCSRC) + * + * UDR : data register + * This register is shared between RX and TX + * + * }}} + */ + +#include <stdint.h> +#include <stdlib.h> + +#include <avr/io.h> + +#define USART_TIMEOUT 5000 + +// struct usart_conf +// { +// uint16_t baudrate; +// }; + +void usart_init(uint16_t baudrate); +// void usart_init_conf(struct usart_conf *conf); + +void usart_send_byte(uint8_t data); +void usart_send(uint8_t *data, size_t len); + +void usart_print(char *str); + +int usart_read_byte(uint8_t *byte); +uint8_t usart_read_byte_nt(void); +size_t usart_read(uint8_t *buffer, size_t len); +int uart_read_line(uint8_t *buffer, size_t len); + +#endif diff --git a/sw/linux/config.h b/sw/programmer/linux/config.h index d319f43..d319f43 100644 --- a/sw/linux/config.h +++ b/sw/programmer/linux/config.h diff --git a/sw/linux/configure.ac b/sw/programmer/linux/configure.ac index a5c4b3b..a5c4b3b 100644 --- a/sw/linux/configure.ac +++ b/sw/programmer/linux/configure.ac diff --git a/sw/linux/makefile.am b/sw/programmer/linux/makefile.am index 4d27cea..4d27cea 100644 --- a/sw/linux/makefile.am +++ b/sw/programmer/linux/makefile.am diff --git a/sw/linux/reading_links.txt b/sw/programmer/linux/reading_links.txt index 83c62f4..83c62f4 100644 --- a/sw/linux/reading_links.txt +++ b/sw/programmer/linux/reading_links.txt 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/linux/src/main.c b/sw/programmer/linux/src/main.c index 769992a..769992a 100644 --- a/sw/linux/src/main.c +++ b/sw/programmer/linux/src/main.c diff --git a/sw/programmer/linux/src/makefile.am b/sw/programmer/linux/src/makefile.am new file mode 100644 index 0000000..33ae438 --- /dev/null +++ b/sw/programmer/linux/src/makefile.am @@ -0,0 +1,7 @@ +bin_PROGRAMS = z80prog +z80prog_SOURCES = main.c ui.c serial.c flash.c + +z80prog_CFLAGS = -Wall -g $(gtk3_CFLAGS) -pthread +z80prog_LDADD = $(gtk3_LIBS) + +CLEANFILES = *~ diff --git a/sw/linux/src/serial.c b/sw/programmer/linux/src/serial.c index 564676b..e2544be 100644 --- a/sw/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/linux/src/serial.h b/sw/programmer/linux/src/serial.h index 6123e42..fe21524 100644 --- a/sw/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 new file mode 100644 index 0000000..87dc0c7 --- /dev/null +++ b/sw/programmer/linux/src/ui.c @@ -0,0 +1,142 @@ +#include "ui.h" + +static bool ui_connected, ui_fileset; +static GtkBuilder *ui_builder; + +void ui_init(int *argc, char **argv[]) +{ + GtkWindow *window; + GtkFileChooserButton *filechoosebtn; + GtkButton *connectbtn, *flashbtn; + + ui_connected = ui_fileset = false; + + gtk_init(argc, argv); + + ui_builder = gtk_builder_new(); + gtk_builder_add_from_file(ui_builder, "z80prog.ui", NULL); + + /* 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 = GTK_BUTTON(gtk_builder_get_object(ui_builder, "connectbtn")); + g_signal_connect(connectbtn, "clicked", G_CALLBACK(ui_connect_clicked), NULL); + + flashbtn = GTK_BUTTON(gtk_builder_get_object(ui_builder, "flashbtn")); + g_signal_connect(flashbtn, "clicked", G_CALLBACK(ui_flash_clicked), NULL); + + 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) +{ + GtkTextIter end; + GtkTextView *ui_log; + + static GtkTextBuffer *ui_logbuf = NULL; + + ui_log = GTK_TEXT_VIEW(gtk_builder_get_object(ui_builder, "logview")); + + 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, msg, -1); + gtk_text_view_scroll_to_iter(ui_log, &end, .0, TRUE, .0, .1); +} + +void ui_check_enable_flashbtn(void) +{ + GtkWidget *ui_flashbtn = GTK_WIDGET(gtk_builder_get_object(ui_builder, "flashbtn")); + + if (ui_connected && ui_fileset) + gtk_widget_set_sensitive(ui_flashbtn, TRUE); + else + gtk_widget_set_sensitive(ui_flashbtn, FALSE); +} + +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/linux/src/ui.h b/sw/programmer/linux/src/ui.h index 44314d6..510537a 100644 --- a/sw/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 Binary files differnew file mode 100755 index 0000000..2f0d230 --- /dev/null +++ b/sw/programmer/linux/src/z80prog diff --git a/sw/linux/src/z80prog.ui b/sw/programmer/linux/src/z80prog.ui index 3735efa..6c652ec 100644 --- a/sw/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> |