summaryrefslogtreecommitdiffstats
path: root/sw/programmer
diff options
context:
space:
mode:
authorNao Pross <naopross@thearcway.org>2017-10-19 17:56:29 +0200
committerNao Pross <naopross@thearcway.org>2017-10-19 17:56:29 +0200
commit57640a10a66a97a07b954a25e976ff0d3a5d28b0 (patch)
tree0d0bb15f54b781c03a25adfbf39979dbc2d657a6 /sw/programmer
parentFix for PIO driver and its test and deletes build files (diff)
downloadz80uPC-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.c82
-rw-r--r--sw/programmer/avr/usart.c2
-rw-r--r--sw/programmer/avr/usart.h2
-rw-r--r--sw/programmer/linux/src/flash.c12
-rw-r--r--sw/programmer/linux/src/serial.c63
-rw-r--r--sw/programmer/linux/src/serial.h4
-rwxr-xr-xsw/programmer/linux/src/z80progbin49856 -> 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
index 9787e67..e2876ee 100755
--- a/sw/programmer/linux/src/z80prog
+++ b/sw/programmer/linux/src/z80prog
Binary files differ