diff options
author | Nao Pross <naopross@thearcway.org> | 2017-10-19 17:56:29 +0200 |
---|---|---|
committer | Nao Pross <naopross@thearcway.org> | 2017-10-19 17:56:29 +0200 |
commit | 57640a10a66a97a07b954a25e976ff0d3a5d28b0 (patch) | |
tree | 0d0bb15f54b781c03a25adfbf39979dbc2d657a6 /sw/programmer | |
parent | Fix for PIO driver and its test and deletes build files (diff) | |
download | z80uPC-57640a10a66a97a07b954a25e976ff0d3a5d28b0.tar.gz z80uPC-57640a10a66a97a07b954a25e976ff0d3a5d28b0.zip |
Got a real rom programmer, this code is still broken but I don't care
Diffstat (limited to '')
-rw-r--r-- | sw/programmer/avr/main.c | 82 | ||||
-rw-r--r-- | sw/programmer/avr/usart.c | 2 | ||||
-rw-r--r-- | sw/programmer/avr/usart.h | 2 | ||||
-rw-r--r-- | sw/programmer/linux/src/flash.c | 12 | ||||
-rw-r--r-- | sw/programmer/linux/src/serial.c | 63 | ||||
-rw-r--r-- | sw/programmer/linux/src/serial.h | 4 | ||||
-rwxr-xr-x | sw/programmer/linux/src/z80prog | bin | 49856 -> 52072 bytes |
7 files changed, 119 insertions, 46 deletions
diff --git a/sw/programmer/avr/main.c b/sw/programmer/avr/main.c index 4f39100..e9fec62 100644 --- a/sw/programmer/avr/main.c +++ b/sw/programmer/avr/main.c @@ -19,66 +19,57 @@ #define EEPROM_RD 1 #define EEPROM_CLK 2 + struct file_blk { uint16_t addr; uint16_t size; }; +void eeprom_set_addr(uint16_t addr); void eeprom_write(uint16_t addr, uint8_t byte); -void eeprom_tick(); +uint8_t eeprom_read(uint16_t addr); 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; + DDRC = 0x1F; + DDRD = 0xFD; /* 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]); + _delay_ms(5); + eeprom_read(blk->addr +i); // != buffer[i]; } free(buffer); + usart_send_byte(0x06); + usart_send_byte(0x06); + usart_send_byte(0x06); } free(blk); return 0; } - -void eeprom_write(uint16_t addr, uint8_t byte) +void eeprom_set_addr(uint16_t addr) { int bit; - /* set address */ for (bit = 0; bit < 8; bit++) { - // clear bit + // clear bits ADDRCR &= ~0x07; // select the bit ADDRCR |= bit; @@ -94,31 +85,56 @@ void eeprom_write(uint16_t addr, uint8_t byte) ADDRCR |= _BV(ADDR_DH); else ADDRCR &= ~_BV(ADDR_DH); + + _delay_ms(5); } +} + +void eeprom_write(uint16_t addr, uint8_t byte) +{ + eeprom_set_addr(addr); + + DDRC |= 0x18; // ED1 ED0 + DDRD |= 0xFC; // ED7-ED2 /* set data */ - EEPROMDR = byte; + EEPROMDR = byte & 0xFC; // because EEPROMDR0 and EEPROMDR1 are used by Tx and Rx - EEPROMCR = (PINC & 0x07) | (byte & 0x03)<<3; + EEPROMCR = (PINC & 0xE7) | (byte & 0x03)<<3; + + /* enable address output */ EEPROMCR &= ~(_BV(ADDR_EH) | _BV(ADDR_EL)); /* write eeprom */ EEPROMCR &= ~_BV(EEPROM_WR); + _delay_ms(5); - // eeprom_tick(); - + /* reset */ EEPROMCR |= _BV(EEPROM_WR); EEPROMCR |= _BV(ADDR_EH) | _BV(ADDR_EL); } -#if 0 -/* pulse the clock line for the eeprom */ -void eeprom_tick() +uint8_t eeprom_read(uint16_t addr) { - EEPROMCR |= _BV(EEPROM_CLK); - _delay_ms(EEPROM_TICK_MS); - EEPROMCR &= ~_BV(EEPROM_CLK); - _delay_ms(EEPROM_TICK_MS); + uint8_t data; + + eeprom_set_addr(addr); + + DDRC &= ~0x18; + DDRD &= ~0xFC; + + /* enable address output */ + EEPROMCR &= ~(_BV(ADDR_EH) | _BV(ADDR_EL)); + + /* enable read eeprom */ + EEPROMCR &= ~_BV(EEPROM_RD); + data = (PINC & 0x18) | (PIND & 0xFB); + _delay_ms(5); + + /* reset */ + EEPROMCR |= _BV(EEPROM_RD); + EEPROMCR |= _BV(ADDR_EH) | _BV(ADDR_EL); + + return data; } -#endif
\ No newline at end of file diff --git a/sw/programmer/avr/usart.c b/sw/programmer/avr/usart.c index 8c2eb38..3d5faf6 100644 --- a/sw/programmer/avr/usart.c +++ b/sw/programmer/avr/usart.c @@ -73,7 +73,7 @@ size_t usart_read(uint8_t *buffer, size_t len) uint8_t *p = buffer; while (len--) { - if (usart_read_byte(p) == 0) { + if (usart_read_byte(p) == 0) { p++; read++; } diff --git a/sw/programmer/avr/usart.h b/sw/programmer/avr/usart.h index 1bb6607..0cf85f2 100644 --- a/sw/programmer/avr/usart.h +++ b/sw/programmer/avr/usart.h @@ -73,7 +73,7 @@ #include <avr/io.h> -#define USART_TIMEOUT 5000 +#define USART_TIMEOUT 50000 // struct usart_conf // { diff --git a/sw/programmer/linux/src/flash.c b/sw/programmer/linux/src/flash.c index 24d5269..3527de8 100644 --- a/sw/programmer/linux/src/flash.c +++ b/sw/programmer/linux/src/flash.c @@ -15,6 +15,7 @@ int flash_open(const char *path, unsigned long baudrate) int flash_write(const char *romfile, void (*log)(const char *)) { int romfd; + int v; ssize_t written; struct stat romst; @@ -33,7 +34,11 @@ int flash_write(const char *romfile, void (*log)(const char *)) break; } - head.addr = (uint16_t) lseek(romfd, 0, SEEK_CUR); + head.addr = (uint16_t) lseek(romfd, 0, SEEK_CUR) - head.size; + + char logbuf[64]; + sprintf(logbuf, "[@] Writing a block of size %d at addr %d\n", head.size, head.addr); + log(logbuf); written = write(flash_serial_fd, &head, sizeof(struct flash_blk)); if (written != sizeof(struct flash_blk)) { @@ -45,8 +50,9 @@ int flash_write(const char *romfile, void (*log)(const char *)) log("[#] Some bytes might not have been written\n"); } - char logbuf[64]; - sprintf(logbuf, "[@] Written %d bytes at address %d\n", head.size, head.addr); + while (!read(flash_serial_fd, &v, 1)); + + sprintf(logbuf, "[@] Written %d bytes at address %d\n", head.size, head.addr); log(logbuf); } diff --git a/sw/programmer/linux/src/serial.c b/sw/programmer/linux/src/serial.c index e2544be..42f021e 100644 --- a/sw/programmer/linux/src/serial.c +++ b/sw/programmer/linux/src/serial.c @@ -1,9 +1,23 @@ #include "serial.h" +static int rate_to_constant(int baudrate) { +#define B(x) case x: return B##x + switch(baudrate) { + B(50); B(75); B(110); B(134); B(150); + B(200); B(300); B(600); B(1200); B(1800); + B(2400); B(4800); B(9600); B(19200); B(38400); + B(57600); B(115200); B(230400); B(460800); B(500000); + B(576000); B(921600); B(1000000);B(1152000);B(1500000); + default: return 0; + } +#undef B +} + int serial_open(const char *devpath, unsigned long baudrate) { - int fd; + int fd, speed; struct termios tty; + struct serial_struct serinfo; // struct termios tty_old; // open device @@ -11,14 +25,44 @@ int serial_open(const char *devpath, unsigned long baudrate) return -1; } + speed = rate_to_constant(baudrate); + if (speed == 0) { + /* custom divisor */ + serinfo.reserved_char[0] = 0; + if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0) + return -1; + serinfo.flags &= ~ASYNC_SPD_MASK; + serinfo.flags |= ASYNC_SPD_CUST; + serinfo.custom_divisor = (serinfo.baud_base + (baudrate / 2)) / baudrate; + + if (serinfo.custom_divisor < 1) + serinfo.custom_divisor = 1; + if (ioctl(fd, TIOCSSERIAL, &serinfo) < 0) + return -1; + if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0) + return -1; + if (serinfo.custom_divisor * baudrate != serinfo.baud_base) { + warnx("actual baudrate is %d / %d = %f", + serinfo.baud_base, serinfo.custom_divisor, + (float)serinfo.baud_base / serinfo.custom_divisor); + } + } + + // set custom baudrate + ioctl(fd, TIOCGSERIAL, &serinfo); + serinfo.flags = ASYNC_SPD_CUST | ASYNC_LOW_LATENCY; + serinfo.custom_divisor = serinfo.baud_base / baudrate; + ioctl(fd, TIOCSSERIAL, &serinfo); + // set parameters if (tcgetattr(fd, &tty) != 0) { + // perror("failed tcgetattr"); return -1; } - // TODO: update UI or add support for custom baudrate - // cfsetospeed(&tty, - // cfsetispeed(&tty, + cfsetispeed(&tty, speed ?: B38400); + cfsetospeed(&tty, speed ?: B38400); + cfmakeraw(&tty); tty.c_cflag &= ~PARENB; // no parity tty.c_cflag &= ~CSTOPB; // no stop bit @@ -28,16 +72,19 @@ int serial_open(const char *devpath, unsigned long baudrate) 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_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( + tcflush(fd , TCIFLUSH); // ? + + if (tcsetattr (fd, TCSANOW, &tty) != 0) { + // perror("failed tcsetattr to set serial port.\n"); + return -1; + } return fd; } - diff --git a/sw/programmer/linux/src/serial.h b/sw/programmer/linux/src/serial.h index fe21524..dd70756 100644 --- a/sw/programmer/linux/src/serial.h +++ b/sw/programmer/linux/src/serial.h @@ -7,6 +7,10 @@ #include <unistd.h> #include <fcntl.h> #include <termios.h> +#include <sys/ioctl.h> +#include <termio.h> +#include <err.h> +#include <linux/serial.h> int serial_open(const char *devpath, unsigned long baudrate); diff --git a/sw/programmer/linux/src/z80prog b/sw/programmer/linux/src/z80prog Binary files differindex 9787e67..e2876ee 100755 --- a/sw/programmer/linux/src/z80prog +++ b/sw/programmer/linux/src/z80prog |