Working version
This commit is contained in:
parent
5ab1e36fc7
commit
39ac0fb6d0
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@ build
|
|||||||
twiboot
|
twiboot
|
||||||
mpmboot
|
mpmboot
|
||||||
funkboot
|
funkboot
|
||||||
|
eprom_prog
|
||||||
|
4
Makefile
4
Makefile
@ -1,8 +1,8 @@
|
|||||||
TARGETS=twiboot mpmboot funkboot
|
TARGETS=twiboot mpmboot funkboot eprom_prog
|
||||||
TARGET_DIR=~/bin
|
TARGET_DIR=~/bin
|
||||||
BUILD_DIR = build
|
BUILD_DIR = build
|
||||||
|
|
||||||
CFLAGS= -pipe -O2 -Wall -Wno-unused-result
|
CFLAGS= -pipe -O2 -Wall -Wextra -Wno-unused-result
|
||||||
CFLAGS+= -MMD -MP -MF $(BUILD_DIR)/$(*D)/$(*F).d
|
CFLAGS+= -MMD -MP -MF $(BUILD_DIR)/$(*D)/$(*F).d
|
||||||
LDFLAGS=
|
LDFLAGS=
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ static struct chipinfo chips[] =
|
|||||||
* ************************************************************************* */
|
* ************************************************************************* */
|
||||||
const char * chipinfo_get_avr_name(const uint8_t *sig)
|
const char * chipinfo_get_avr_name(const uint8_t *sig)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(chips); i++)
|
for (i = 0; i < ARRAY_SIZE(chips); i++)
|
||||||
{
|
{
|
||||||
|
936
eprom_prog.c
Normal file
936
eprom_prog.c
Normal file
@ -0,0 +1,936 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include "multiboot.h"
|
||||||
|
#include "optarg.h"
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x))
|
||||||
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
|
#define MEMTYPE_EPROM 1
|
||||||
|
|
||||||
|
#define SERIAL_BAUDRATE B115200
|
||||||
|
#define SERIAL_TIMEOUT 1000
|
||||||
|
#define SERIAL_TIMEOUT_SYNC 5
|
||||||
|
|
||||||
|
#define MSGTYPE_SYNC 0x00 /* trigger { MSGTYPE_ERROR_RSP, 1, ERROR_UNKNOWN_COMMAND } */
|
||||||
|
#define MSGTYPE_VERSION_REQ 0x01 /* no payload */
|
||||||
|
#define MSGTYPE_PAGESIZE_REQ 0x02 /* no payload */
|
||||||
|
#define MSGTYPE_CONFIG_REQ 0x03 /* eprom_type(1), pagesize(1), reset_polarity(1) */
|
||||||
|
#define MSGTYPE_PROGMODE_REQ 0x04 /* progmode(1) */
|
||||||
|
#define MSGTYPE_SETADDRESS_REQ 0x05 /* address(3) msb first */
|
||||||
|
#define MSGTYPE_WRITE_REQ 0x06 /* data(0-pagesize) */
|
||||||
|
#define MSGTYPE_READ_REQ 0x07 /* length(1) */
|
||||||
|
|
||||||
|
#define MSGTYPE_ERROR_RSP 0x80 /* error_code(1) */
|
||||||
|
#define MSGTYPE_VERSION_RSP 0x81 /* version(?) */
|
||||||
|
#define MSGTYPE_PAGESIZE_RSP 0x82 /* pagesize(1) */
|
||||||
|
#define MSGTYPE_CONFIG_RSP 0x83 /* no payload */
|
||||||
|
#define MSGTYPE_PROGMODE_RSP 0x84 /* no payload */
|
||||||
|
#define MSGTYPE_SETADDRESS_RSP 0x85 /* no payload */
|
||||||
|
#define MSGTYPE_WRITE_RSP 0x86 /* no payload */
|
||||||
|
#define MSGTYPE_READ_RSP 0x87 /* data(0-pagesize) */
|
||||||
|
|
||||||
|
#define SUCCESS 0x00
|
||||||
|
#define ERROR_UNKNOWN_COMMAND 0x01 /* unknown message type */
|
||||||
|
#define ERROR_NOT_SUPPORTED 0x02 /* command not supported */
|
||||||
|
#define ERROR_INVALID_MODE 0x03 /* invalid progmode */
|
||||||
|
#define ERROR_INVALID_PARAMETER 0x04 /* invalid parameter in request */
|
||||||
|
#define ERROR_INVALID_ADDRESS 0x05 /* write outside of configured region */
|
||||||
|
|
||||||
|
#define RESET_POLARITY_LOW 0x00 /* low active reset */
|
||||||
|
#define RESET_POLARITY_HIGH 0x01 /* high active reset */
|
||||||
|
|
||||||
|
#define EPROM_TYPE_2K 0x02 /* 2716 */
|
||||||
|
#define EPROM_TYPE_4K 0x04 /* 2732 */
|
||||||
|
#define EPROM_TYPE_8K 0x08 /* 2764 */
|
||||||
|
#define EPROM_TYPE_16K 0x10 /* 27128 */
|
||||||
|
#define EPROM_TYPE_32K 0x20 /* 27256 */
|
||||||
|
#define EPROM_TYPE_64K 0x40 /* 27512 */
|
||||||
|
#define EPROM_TYPE_128K 0x80 /* 27010 */
|
||||||
|
|
||||||
|
#define PROGMODE_DISABLED 0x00 /* target running, no write access to RAM */
|
||||||
|
#define PROGMODE_ENABLED 0x01 /* target reset, write access to RAM */
|
||||||
|
|
||||||
|
|
||||||
|
struct multiboot_ops eprog_ops;
|
||||||
|
|
||||||
|
struct eprog_privdata
|
||||||
|
{
|
||||||
|
char * device;
|
||||||
|
struct termios oldtio;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
uint8_t version[32];
|
||||||
|
uint8_t pagesize_max;
|
||||||
|
|
||||||
|
uint8_t eprom_type;
|
||||||
|
uint8_t pagesize;
|
||||||
|
int reset_polarity;
|
||||||
|
|
||||||
|
uint8_t progmode;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct eprog_type
|
||||||
|
{
|
||||||
|
const char name[8];
|
||||||
|
uint8_t eprom_type;
|
||||||
|
uint8_t pagesize;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct eprog_type eprom_types[] =
|
||||||
|
{
|
||||||
|
{ "2716", EPROM_TYPE_2K, 0xFF },
|
||||||
|
{ "2732", EPROM_TYPE_4K, 0xFF },
|
||||||
|
{ "2764", EPROM_TYPE_8K, 0xFF },
|
||||||
|
{ "2864", EPROM_TYPE_8K, 0x40 },
|
||||||
|
{ "27128", EPROM_TYPE_16K, 0xFF },
|
||||||
|
{ "27256", EPROM_TYPE_32K, 0xFF },
|
||||||
|
{ "27512", EPROM_TYPE_64K, 0xFF },
|
||||||
|
{ "27010", EPROM_TYPE_128K, 0xFF },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct option eprog_optargs[] =
|
||||||
|
{
|
||||||
|
{ "device", 1, 0, 'd' }, /* [ -d <device> ] */
|
||||||
|
{ "reset", 1, 0, 'x' }, /* [ -x <reset polarity> ] */
|
||||||
|
{ "type", 1, 0, 't' }, /* [ -t <type> ] */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_optarg_cb
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_optarg_cb(int val, const char *arg, void *privdata)
|
||||||
|
{
|
||||||
|
struct eprog_privdata *p_prog = (struct eprog_privdata *)privdata;
|
||||||
|
|
||||||
|
switch (val)
|
||||||
|
{
|
||||||
|
case 'd': /* device */
|
||||||
|
if (p_prog->device != NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "invalid device: '%s'\n", arg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_prog->device = strdup(optarg);
|
||||||
|
if (p_prog->device == NULL)
|
||||||
|
{
|
||||||
|
perror("strdup()");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'x':
|
||||||
|
if (strcasecmp(arg, "high") == 0)
|
||||||
|
{
|
||||||
|
p_prog->reset_polarity = RESET_POLARITY_HIGH;
|
||||||
|
}
|
||||||
|
else if (strcasecmp(arg, "low") == 0)
|
||||||
|
{
|
||||||
|
p_prog->reset_polarity = RESET_POLARITY_LOW;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "invalid reset polarity: '%s'\n", arg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (p_prog->eprom_type != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "invalid EPROM type: '%s'\n", arg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(eprom_types); i++)
|
||||||
|
{
|
||||||
|
if (strcmp(arg, eprom_types[i].name) == 0)
|
||||||
|
{
|
||||||
|
p_prog->eprom_type = eprom_types[i].eprom_type;
|
||||||
|
p_prog->pagesize = eprom_types[i].pagesize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_prog->eprom_type == 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "invalid EPROM type: '%s'\n", arg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
case '?': /* error */
|
||||||
|
fprintf(stderr, "Usage: eprom_sim [options]\n"
|
||||||
|
" -d <device> - selects eprom_sim device\n"
|
||||||
|
" -x <reset polarity> - select 'high' or 'low' active reset\n"
|
||||||
|
" -t <type> - selects EPROM type (2716 - 27010)\n"
|
||||||
|
" -r eprom:<file> - reads EPROM to file (.bin | .hex | -)\n"
|
||||||
|
" -w eprom:<file> - write EPROM from file (.bin | .hex)\n"
|
||||||
|
" -p <0|1|2> - progress bar mode\n"
|
||||||
|
"\n"
|
||||||
|
"Example: eprom_sim -d /dev/ttyUSB0 -t 2764 -r high -w eprom:data.hex\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* eprog_optarg_cb */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_alloc
|
||||||
|
* ************************************************************************* */
|
||||||
|
static struct multiboot * eprog_alloc(void)
|
||||||
|
{
|
||||||
|
struct multiboot * mboot = malloc(sizeof(struct multiboot));
|
||||||
|
if (mboot == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(mboot, 0x00, sizeof(struct multiboot));
|
||||||
|
mboot->ops= &eprog_ops;
|
||||||
|
|
||||||
|
struct eprog_privdata *p_prog = malloc(sizeof(struct eprog_privdata));
|
||||||
|
if (p_prog == NULL)
|
||||||
|
{
|
||||||
|
free(mboot);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(p_prog, 0x00, sizeof(struct eprog_privdata));
|
||||||
|
p_prog->device = NULL;
|
||||||
|
|
||||||
|
optarg_register(eprog_optargs, ARRAY_SIZE(eprog_optargs),
|
||||||
|
eprog_optarg_cb, (void *)p_prog);
|
||||||
|
|
||||||
|
mboot->privdata = p_prog;
|
||||||
|
return mboot;
|
||||||
|
} /* eprog_alloc */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_free
|
||||||
|
* ************************************************************************* */
|
||||||
|
static void eprog_free(struct multiboot *mboot)
|
||||||
|
{
|
||||||
|
struct eprog_privdata *p_prog = (struct eprog_privdata *)mboot->privdata;
|
||||||
|
|
||||||
|
if (p_prog->device != NULL)
|
||||||
|
{
|
||||||
|
free(p_prog->device);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(p_prog);
|
||||||
|
free(mboot);
|
||||||
|
} /* eprog_free */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_get_memtype
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_get_memtype(struct multiboot *mboot,
|
||||||
|
const char *memname)
|
||||||
|
{
|
||||||
|
/* unused parameter */
|
||||||
|
(void)mboot;
|
||||||
|
|
||||||
|
if (strcmp(memname, "eprom") == 0)
|
||||||
|
{
|
||||||
|
return MEMTYPE_EPROM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
} /* eprog_get_memtype */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_get_memsize
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_get_memsize(struct multiboot *mboot,
|
||||||
|
int memtype)
|
||||||
|
{
|
||||||
|
struct eprog_privdata *p_prog = (struct eprog_privdata *)mboot->privdata;
|
||||||
|
|
||||||
|
if (memtype != MEMTYPE_EPROM)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p_prog->eprom_type * 1024;
|
||||||
|
} /* eprog_get_memsize */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_close_device
|
||||||
|
* ************************************************************************* */
|
||||||
|
static void eprog_close_device(struct eprog_privdata *p_prog)
|
||||||
|
{
|
||||||
|
/* delay close() / tcsetattr() */
|
||||||
|
usleep(100000);
|
||||||
|
|
||||||
|
tcsetattr(p_prog->fd, TCSANOW, &p_prog->oldtio);
|
||||||
|
close(p_prog->fd);
|
||||||
|
} /* eprog_close_device */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_open_device
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_open_device(struct eprog_privdata *p_prog)
|
||||||
|
{
|
||||||
|
p_prog->fd = open(p_prog->device, O_RDWR | O_NOCTTY | O_CLOEXEC);
|
||||||
|
if (p_prog->fd < 0)
|
||||||
|
{
|
||||||
|
perror("open()");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tcgetattr(p_prog->fd, &p_prog->oldtio) < 0)
|
||||||
|
{
|
||||||
|
perror("tcgetattr(oldtio)");
|
||||||
|
close(p_prog->fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct termios newtio;
|
||||||
|
memset(&newtio, 0, sizeof(newtio));
|
||||||
|
|
||||||
|
newtio.c_iflag |= IGNBRK;
|
||||||
|
newtio.c_cflag |= SERIAL_BAUDRATE | CS8 | CLOCAL | CREAD;
|
||||||
|
|
||||||
|
newtio.c_cc[VMIN] = 1;
|
||||||
|
newtio.c_cc[VTIME] = 0;
|
||||||
|
|
||||||
|
int err = tcsetattr(p_prog->fd, TCSANOW, &newtio);
|
||||||
|
if (err < 0)
|
||||||
|
{
|
||||||
|
perror("tcsetattr(newtio)");
|
||||||
|
close(p_prog->fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* eprog_open_device */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_serial_read
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_serial_read(int fd, void * data, int size, unsigned int timeout_ms)
|
||||||
|
{
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
fd_set fdset;
|
||||||
|
struct timeval timeout;
|
||||||
|
struct timeval * p_timeout = NULL;
|
||||||
|
|
||||||
|
FD_ZERO(&fdset);
|
||||||
|
FD_SET(fd, &fdset);
|
||||||
|
|
||||||
|
if (timeout_ms != 0)
|
||||||
|
{
|
||||||
|
p_timeout = &timeout;
|
||||||
|
|
||||||
|
timeout.tv_sec = timeout_ms / 1000;
|
||||||
|
timeout.tv_usec = (timeout_ms % 1000) * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = select(fd +1, &fdset, NULL, NULL, p_timeout);
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
perror("select");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (ret == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (FD_ISSET(fd, &fdset))
|
||||||
|
{
|
||||||
|
int len = read(fd, data + pos, size - pos);
|
||||||
|
if (len < 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos += len;
|
||||||
|
if (pos == size)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
} /* eprog_serial_read */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_recv
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_recv(int fd, uint8_t msgtype, uint8_t * data, uint8_t length)
|
||||||
|
{
|
||||||
|
uint8_t header[2];
|
||||||
|
uint8_t dummy[64];
|
||||||
|
|
||||||
|
int ret = eprog_serial_read(fd, header, sizeof(header), SERIAL_TIMEOUT);
|
||||||
|
if (ret < (int)sizeof(header))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "short read from device (header)\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t pos = 0;
|
||||||
|
uint8_t msgsize = header[1];
|
||||||
|
|
||||||
|
while (msgsize > 0)
|
||||||
|
{
|
||||||
|
if ((data != NULL) && (pos < length))
|
||||||
|
{
|
||||||
|
uint8_t readsize = MIN(msgsize, length - pos);
|
||||||
|
|
||||||
|
ret = eprog_serial_read(fd, &data[pos], readsize, SERIAL_TIMEOUT);
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "short read from device (payload)\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint8_t readsize = MIN(msgsize, sizeof(dummy));
|
||||||
|
|
||||||
|
ret = eprog_serial_read(fd, &dummy, readsize, SERIAL_TIMEOUT);
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "short read from device (dummy)\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msgsize -= ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header[0] != msgtype)
|
||||||
|
{
|
||||||
|
if ((header[0] == MSGTYPE_ERROR_RSP) && (header[1] == 1))
|
||||||
|
{
|
||||||
|
uint8_t error_code = (data != NULL) ? data[0] : dummy[0];
|
||||||
|
|
||||||
|
fprintf(stderr, "expected msgtype 0x%x received ERROR_RSP error_code 0x%x\n",
|
||||||
|
msgtype, error_code);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "wrong msgtype received (0x%x != 0x%x)\n",
|
||||||
|
header[0], msgtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
} /* eprog_recv */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_sync
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_sync(struct eprog_privdata *p_prog)
|
||||||
|
{
|
||||||
|
int sync_count = 255;
|
||||||
|
|
||||||
|
while (sync_count > 0)
|
||||||
|
{
|
||||||
|
/* send only MSGTYPE, no request length! */
|
||||||
|
uint8_t request[] = { MSGTYPE_SYNC };
|
||||||
|
uint8_t response[3];
|
||||||
|
|
||||||
|
int ret = write(p_prog->fd, request, sizeof(request));
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = eprog_serial_read(p_prog->fd, response, sizeof(response), SERIAL_TIMEOUT_SYNC);
|
||||||
|
if ((ret == sizeof(response)) &&
|
||||||
|
(response[0] == MSGTYPE_ERROR_RSP) &&
|
||||||
|
(response[1] == 1) &&
|
||||||
|
(response[2] == ERROR_UNKNOWN_COMMAND)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sync_count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
} /* eprog_sync */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_get_version
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_get_version(struct eprog_privdata *p_prog,
|
||||||
|
uint8_t *version, uint8_t length)
|
||||||
|
{
|
||||||
|
uint8_t request[] = { MSGTYPE_VERSION_REQ, 0 };
|
||||||
|
|
||||||
|
int ret = write(p_prog->fd, request, sizeof(request));
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = eprog_recv(p_prog->fd, MSGTYPE_VERSION_RSP, version, length);
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < length)
|
||||||
|
{
|
||||||
|
version[ret] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
version[length -1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* eprog_get_version */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_get_pagesize
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_get_pagesize(struct eprog_privdata *p_prog,
|
||||||
|
uint8_t *pagesize)
|
||||||
|
{
|
||||||
|
uint8_t request[] = { MSGTYPE_PAGESIZE_REQ, 0 };
|
||||||
|
uint8_t response[1];
|
||||||
|
|
||||||
|
int ret = write(p_prog->fd, request, sizeof(request));
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = eprog_recv(p_prog->fd, MSGTYPE_PAGESIZE_RSP, response, sizeof(response));
|
||||||
|
if (ret != sizeof(response))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pagesize = response[0];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* eprog_get_pagesize */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_set_config
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_set_config(struct eprog_privdata *p_prog,
|
||||||
|
uint8_t eprom_type,
|
||||||
|
uint8_t pagesize,
|
||||||
|
uint8_t reset_polarity)
|
||||||
|
{
|
||||||
|
uint8_t request[] = { MSGTYPE_CONFIG_REQ, 3, eprom_type, pagesize, reset_polarity };
|
||||||
|
|
||||||
|
int ret = write(p_prog->fd, request, sizeof(request));
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = eprog_recv(p_prog->fd, MSGTYPE_CONFIG_RSP, NULL, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* eprog_set_config */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_set_progmode
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_set_progmode(struct eprog_privdata *p_prog,
|
||||||
|
uint8_t progmode)
|
||||||
|
{
|
||||||
|
uint8_t request[] = { MSGTYPE_PROGMODE_REQ, 1, progmode };
|
||||||
|
|
||||||
|
int ret = write(p_prog->fd, request, sizeof(request));
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = eprog_recv(p_prog->fd, MSGTYPE_PROGMODE_RSP, NULL, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* eprog_set_progmode */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_set_address
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_set_address(struct eprog_privdata *p_prog,
|
||||||
|
uint32_t address)
|
||||||
|
{
|
||||||
|
uint8_t request[] = { MSGTYPE_SETADDRESS_REQ, 3,
|
||||||
|
(address >> 16) & 0xFF,
|
||||||
|
(address >> 8) & 0xFF,
|
||||||
|
(address >> 0) & 0xFF };
|
||||||
|
|
||||||
|
int ret = write(p_prog->fd, request, sizeof(request));
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = eprog_recv(p_prog->fd, MSGTYPE_SETADDRESS_RSP, NULL, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* eprog_set_address */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_read_data
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_read_data(struct eprog_privdata *p_prog,
|
||||||
|
uint8_t * data,
|
||||||
|
uint8_t length)
|
||||||
|
{
|
||||||
|
uint8_t request[] = { MSGTYPE_READ_REQ, 1, length };
|
||||||
|
|
||||||
|
int ret = write(p_prog->fd, request, sizeof(request));
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = eprog_recv(p_prog->fd, MSGTYPE_READ_RSP, data, length);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* eprog_read_data */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_write_data
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_write_data(struct eprog_privdata *p_prog,
|
||||||
|
const uint8_t * data,
|
||||||
|
uint8_t length)
|
||||||
|
{
|
||||||
|
uint8_t request[] = { MSGTYPE_WRITE_REQ, length };
|
||||||
|
|
||||||
|
int ret = write(p_prog->fd, request, sizeof(request));
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = write(p_prog->fd, data, length);
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = eprog_recv(p_prog->fd, MSGTYPE_WRITE_RSP, NULL, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* eprog_write_data */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_close
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_close(struct multiboot *mboot)
|
||||||
|
{
|
||||||
|
struct eprog_privdata *p_prog = (struct eprog_privdata *)mboot->privdata;
|
||||||
|
|
||||||
|
if (p_prog->progmode == PROGMODE_ENABLED)
|
||||||
|
{
|
||||||
|
eprog_set_progmode(p_prog, PROGMODE_DISABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
eprog_close_device(p_prog);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* eprog_close */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_open
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_open(struct multiboot *mboot)
|
||||||
|
{
|
||||||
|
struct eprog_privdata *p_prog = (struct eprog_privdata *)mboot->privdata;
|
||||||
|
|
||||||
|
if (p_prog->device == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "abort: no device given\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_prog->eprom_type == 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "abort: no EPROM type given\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eprog_open_device(p_prog) < 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eprog_sync(p_prog) < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "failed to sync\n");
|
||||||
|
eprog_close_device(p_prog);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eprog_get_version(p_prog, p_prog->version, sizeof(p_prog->version)) < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "failed to get version\n");
|
||||||
|
eprog_close_device(p_prog);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((eprog_get_pagesize(p_prog, &p_prog->pagesize_max) < 0) ||
|
||||||
|
(p_prog->pagesize_max == 0)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "failed to get pagesize\n");
|
||||||
|
eprog_close_device(p_prog);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_prog->pagesize = MIN(p_prog->pagesize, p_prog->pagesize_max);
|
||||||
|
if (eprog_set_config(p_prog, p_prog->eprom_type, p_prog->pagesize, p_prog->reset_polarity) < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "failed to set configuration\n");
|
||||||
|
eprog_close_device(p_prog);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eprog_set_progmode(p_prog, PROGMODE_ENABLED) < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "failed to enter progmode\n");
|
||||||
|
eprog_close_device(p_prog);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_prog->progmode = PROGMODE_ENABLED;
|
||||||
|
|
||||||
|
printf("device : %-16s\n",
|
||||||
|
p_prog->device);
|
||||||
|
|
||||||
|
printf("version : %-32s\n",
|
||||||
|
p_prog->version);
|
||||||
|
|
||||||
|
printf("reset polarity : %-4s\n",
|
||||||
|
p_prog->reset_polarity ? "high" : "low");
|
||||||
|
|
||||||
|
printf("EPROM size : 0x%05x (%d)\n",
|
||||||
|
p_prog->eprom_type * 1024,
|
||||||
|
p_prog->eprom_type * 1024);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* eprog_open */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_read
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_read(struct multiboot *mboot,
|
||||||
|
struct databuf *dbuf, int memtype)
|
||||||
|
{
|
||||||
|
struct eprog_privdata *p_prog = (struct eprog_privdata *)mboot->privdata;
|
||||||
|
char *progress_msg = "reading EPROM";
|
||||||
|
|
||||||
|
/* unused parameter */
|
||||||
|
(void)memtype;
|
||||||
|
|
||||||
|
uint32_t pos = 0;
|
||||||
|
uint32_t size = p_prog->eprom_type * 1024;
|
||||||
|
|
||||||
|
if (eprog_set_address(p_prog, pos) < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "failed to set address\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (pos < size)
|
||||||
|
{
|
||||||
|
mboot->progress_cb(progress_msg, pos, size);
|
||||||
|
|
||||||
|
uint8_t len = MIN(p_prog->pagesize_max, size - pos);
|
||||||
|
if (eprog_read_data(p_prog, dbuf->data + pos, len))
|
||||||
|
{
|
||||||
|
mboot->progress_cb(progress_msg, -1, -1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbuf->length = pos;
|
||||||
|
|
||||||
|
mboot->progress_cb(progress_msg, pos, size);
|
||||||
|
return 0;
|
||||||
|
} /* eprog_read */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_write
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_write(struct multiboot *mboot,
|
||||||
|
struct databuf *dbuf,
|
||||||
|
int memtype)
|
||||||
|
{
|
||||||
|
struct eprog_privdata *p_prog = (struct eprog_privdata *)mboot->privdata;
|
||||||
|
char *progress_msg = "writing EPROM";
|
||||||
|
|
||||||
|
/* unused parameter */
|
||||||
|
(void)memtype;
|
||||||
|
|
||||||
|
uint32_t pos = 0;
|
||||||
|
|
||||||
|
if (eprog_set_address(p_prog, pos) < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "failed to set address\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (pos < dbuf->length)
|
||||||
|
{
|
||||||
|
mboot->progress_cb(progress_msg, pos, dbuf->length);
|
||||||
|
|
||||||
|
uint8_t len = MIN(p_prog->pagesize, dbuf->length - pos);
|
||||||
|
if (eprog_write_data(p_prog, dbuf->data + pos, len))
|
||||||
|
{
|
||||||
|
mboot->progress_cb(progress_msg, -1, -1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
mboot->progress_cb(progress_msg, pos, dbuf->length);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* eprog_write */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************************************************
|
||||||
|
* eprog_verify
|
||||||
|
* ************************************************************************* */
|
||||||
|
static int eprog_verify(struct multiboot *mboot,
|
||||||
|
struct databuf *dbuf, int memtype)
|
||||||
|
{
|
||||||
|
struct eprog_privdata *p_prog = (struct eprog_privdata *)mboot->privdata;
|
||||||
|
char *progress_msg = "verifing EPROM";
|
||||||
|
|
||||||
|
/* unused parameter */
|
||||||
|
(void)memtype;
|
||||||
|
|
||||||
|
uint32_t pos = 0;
|
||||||
|
uint8_t comp[256];
|
||||||
|
|
||||||
|
if (eprog_set_address(p_prog, pos) < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "failed to set address\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (pos < dbuf->length)
|
||||||
|
{
|
||||||
|
mboot->progress_cb(progress_msg, pos, dbuf->length);
|
||||||
|
|
||||||
|
uint8_t len = MIN(p_prog->pagesize, dbuf->length - pos);
|
||||||
|
if (eprog_read_data(p_prog, comp, len))
|
||||||
|
{
|
||||||
|
mboot->progress_cb(progress_msg, -1, -1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(comp, dbuf->data + pos, len) != 0x00)
|
||||||
|
{
|
||||||
|
mboot->progress_cb(progress_msg, -1, -1);
|
||||||
|
fprintf(stderr, "verify failed at pos 0x%04x!!\n", pos);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbuf->length = pos;
|
||||||
|
|
||||||
|
mboot->progress_cb(progress_msg, pos, dbuf->length);
|
||||||
|
return 0;
|
||||||
|
} /* eprog_verify */
|
||||||
|
|
||||||
|
|
||||||
|
struct multiboot_ops eprog_ops =
|
||||||
|
{
|
||||||
|
.exec_name = "eprom_prog",
|
||||||
|
.alloc = eprog_alloc,
|
||||||
|
.free = eprog_free,
|
||||||
|
.get_memtype = eprog_get_memtype,
|
||||||
|
.get_memsize = eprog_get_memsize,
|
||||||
|
|
||||||
|
.open = eprog_open,
|
||||||
|
.close = eprog_close,
|
||||||
|
.read = eprog_read,
|
||||||
|
.write = eprog_write,
|
||||||
|
.verify = eprog_verify,
|
||||||
|
};
|
12
filedata.c
12
filedata.c
@ -64,7 +64,8 @@ void dbuf_free(struct databuf *dbuf)
|
|||||||
* ************************************************************************* */
|
* ************************************************************************* */
|
||||||
static void dbuf_dump(struct databuf *dbuf)
|
static void dbuf_dump(struct databuf *dbuf)
|
||||||
{
|
{
|
||||||
int pos = 0, oldskip = 0;
|
uint32_t pos = 0;
|
||||||
|
int oldskip = 0;
|
||||||
|
|
||||||
while (pos < dbuf->length)
|
while (pos < dbuf->length)
|
||||||
{
|
{
|
||||||
@ -372,6 +373,9 @@ static int hexfile_putrecord(FILE *stream, struct ihex_record *record)
|
|||||||
* ************************************************************************* */
|
* ************************************************************************* */
|
||||||
static int hexfile_getsize(const char *filename, uint32_t *size)
|
static int hexfile_getsize(const char *filename, uint32_t *size)
|
||||||
{
|
{
|
||||||
|
/* unused parameter */
|
||||||
|
(void)filename;
|
||||||
|
|
||||||
*size = 0x10000;
|
*size = 0x10000;
|
||||||
return 0;
|
return 0;
|
||||||
} /* hexfile_getsize */
|
} /* hexfile_getsize */
|
||||||
@ -432,9 +436,9 @@ static int hexfile_write(const char *filename, struct databuf *dbuf)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
uint32_t i;
|
||||||
int addr_min = dbuf->length;
|
uint32_t addr_min = dbuf->length;
|
||||||
int addr_max = 0;
|
uint32_t addr_max = 0;
|
||||||
for (i = 0; i < dbuf->length; i++)
|
for (i = 0; i < dbuf->length; i++)
|
||||||
{
|
{
|
||||||
if (dbuf->data[i] == 0xFF)
|
if (dbuf->data[i] == 0xFF)
|
||||||
|
18
funk.c
18
funk.c
@ -260,6 +260,9 @@ static void funk_free(struct multiboot *mboot)
|
|||||||
static int funk_get_memtype(struct multiboot *mboot,
|
static int funk_get_memtype(struct multiboot *mboot,
|
||||||
const char *memname)
|
const char *memname)
|
||||||
{
|
{
|
||||||
|
/* unused parameter */
|
||||||
|
(void)mboot;
|
||||||
|
|
||||||
if (strcmp(memname, "flash") == 0)
|
if (strcmp(memname, "flash") == 0)
|
||||||
{
|
{
|
||||||
return MEMTYPE_FLASH;
|
return MEMTYPE_FLASH;
|
||||||
@ -1066,14 +1069,14 @@ static int funk_read(struct multiboot *mboot,
|
|||||||
struct funk_privdata *funk = (struct funk_privdata *)mboot->privdata;
|
struct funk_privdata *funk = (struct funk_privdata *)mboot->privdata;
|
||||||
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "reading flash" : "reading eeprom";
|
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "reading flash" : "reading eeprom";
|
||||||
|
|
||||||
int pos = 0;
|
uint16_t pos = 0;
|
||||||
int size = (memtype == MEMTYPE_FLASH) ? funk->flashsize : funk->eepromsize;
|
uint16_t size = (memtype == MEMTYPE_FLASH) ? funk->flashsize : funk->eepromsize;
|
||||||
|
|
||||||
while (pos < size)
|
while (pos < size)
|
||||||
{
|
{
|
||||||
mboot->progress_cb(progress_msg, pos, size);
|
mboot->progress_cb(progress_msg, pos, size);
|
||||||
|
|
||||||
int len = MIN(READ_BLOCK_SIZE, size - pos);
|
uint16_t len = MIN(READ_BLOCK_SIZE, size - pos);
|
||||||
if (funk_read_memory(funk, dbuf->data + pos, len, memtype, pos))
|
if (funk_read_memory(funk, dbuf->data + pos, len, memtype, pos))
|
||||||
{
|
{
|
||||||
mboot->progress_cb(progress_msg, -1, -1);
|
mboot->progress_cb(progress_msg, -1, -1);
|
||||||
@ -1100,12 +1103,12 @@ static int funk_write(struct multiboot *mboot,
|
|||||||
struct funk_privdata *funk = (struct funk_privdata *)mboot->privdata;
|
struct funk_privdata *funk = (struct funk_privdata *)mboot->privdata;
|
||||||
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "writing flash" : "writing eeprom";
|
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "writing flash" : "writing eeprom";
|
||||||
|
|
||||||
int pos = 0;
|
uint16_t pos = 0;
|
||||||
while (pos < dbuf->length)
|
while (pos < dbuf->length)
|
||||||
{
|
{
|
||||||
mboot->progress_cb(progress_msg, pos, dbuf->length);
|
mboot->progress_cb(progress_msg, pos, dbuf->length);
|
||||||
|
|
||||||
int len = (memtype == MEMTYPE_FLASH) ? funk->flashpage : WRITE_BLOCK_SIZE;
|
uint16_t len = (memtype == MEMTYPE_FLASH) ? funk->flashpage : WRITE_BLOCK_SIZE;
|
||||||
|
|
||||||
len = MIN(len, dbuf->length - pos);
|
len = MIN(len, dbuf->length - pos);
|
||||||
|
|
||||||
@ -1133,14 +1136,14 @@ static int funk_verify(struct multiboot *mboot,
|
|||||||
struct funk_privdata *funk = (struct funk_privdata *)mboot->privdata;
|
struct funk_privdata *funk = (struct funk_privdata *)mboot->privdata;
|
||||||
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "verifing flash" : "verifing eeprom";
|
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "verifing flash" : "verifing eeprom";
|
||||||
|
|
||||||
int pos = 0;
|
uint16_t pos = 0;
|
||||||
uint8_t comp[READ_BLOCK_SIZE];
|
uint8_t comp[READ_BLOCK_SIZE];
|
||||||
|
|
||||||
while (pos < dbuf->length)
|
while (pos < dbuf->length)
|
||||||
{
|
{
|
||||||
mboot->progress_cb(progress_msg, pos, dbuf->length);
|
mboot->progress_cb(progress_msg, pos, dbuf->length);
|
||||||
|
|
||||||
int len = MIN(READ_BLOCK_SIZE, dbuf->length - pos);
|
uint16_t len = MIN(READ_BLOCK_SIZE, dbuf->length - pos);
|
||||||
if (funk_read_memory(funk, comp, len, memtype, pos))
|
if (funk_read_memory(funk, comp, len, memtype, pos))
|
||||||
{
|
{
|
||||||
mboot->progress_cb(progress_msg, -1, -1);
|
mboot->progress_cb(progress_msg, -1, -1);
|
||||||
@ -1166,6 +1169,7 @@ static int funk_verify(struct multiboot *mboot,
|
|||||||
|
|
||||||
struct multiboot_ops funk_ops =
|
struct multiboot_ops funk_ops =
|
||||||
{
|
{
|
||||||
|
.exec_name = "funkboot",
|
||||||
.alloc = funk_alloc,
|
.alloc = funk_alloc,
|
||||||
.free = funk_free,
|
.free = funk_free,
|
||||||
.get_memtype = funk_get_memtype,
|
.get_memtype = funk_get_memtype,
|
||||||
|
42
mpm.c
42
mpm.c
@ -46,11 +46,11 @@ struct mpm_privdata
|
|||||||
int fd;
|
int fd;
|
||||||
int connected;
|
int connected;
|
||||||
|
|
||||||
int address;
|
uint8_t address;
|
||||||
|
|
||||||
int flashsize;
|
uint16_t flashsize;
|
||||||
int flashpage;
|
uint8_t flashpage;
|
||||||
int eepromsize;
|
uint16_t eepromsize;
|
||||||
|
|
||||||
struct termios oldtio;
|
struct termios oldtio;
|
||||||
};
|
};
|
||||||
@ -178,6 +178,9 @@ static void mpm_free(struct multiboot *mboot)
|
|||||||
static int mpm_get_memtype(struct multiboot *mboot,
|
static int mpm_get_memtype(struct multiboot *mboot,
|
||||||
const char *memname)
|
const char *memname)
|
||||||
{
|
{
|
||||||
|
/* unused parameter */
|
||||||
|
(void)mboot;
|
||||||
|
|
||||||
if (strcmp(memname, "flash") == 0)
|
if (strcmp(memname, "flash") == 0)
|
||||||
{
|
{
|
||||||
return MEMTYPE_FLASH;
|
return MEMTYPE_FLASH;
|
||||||
@ -221,7 +224,7 @@ static int mpm_get_memsize(struct multiboot *mboot, int memtype)
|
|||||||
* mpm_send
|
* mpm_send
|
||||||
* ************************************************************************* */
|
* ************************************************************************* */
|
||||||
static int mpm_send(struct mpm_privdata *mpm, uint8_t command,
|
static int mpm_send(struct mpm_privdata *mpm, uint8_t command,
|
||||||
uint8_t *data, int length)
|
uint8_t *data, uint16_t length)
|
||||||
{
|
{
|
||||||
struct termios tio;
|
struct termios tio;
|
||||||
|
|
||||||
@ -283,9 +286,9 @@ static int mpm_send(struct mpm_privdata *mpm, uint8_t command,
|
|||||||
|
|
||||||
|
|
||||||
/* *************************************************************************
|
/* *************************************************************************
|
||||||
* myread
|
* mpm_serial_read
|
||||||
* ************************************************************************* */
|
* ************************************************************************* */
|
||||||
static int myread(int fd, void *data, int size)
|
static int mpm_serial_read(int fd, void *data, int size)
|
||||||
{
|
{
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
@ -327,7 +330,7 @@ static int myread(int fd, void *data, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return pos;
|
return pos;
|
||||||
} /* myread */
|
} /* mpm_serial_read */
|
||||||
|
|
||||||
|
|
||||||
/* *************************************************************************
|
/* *************************************************************************
|
||||||
@ -342,7 +345,7 @@ static int mpm_recv(struct mpm_privdata *mpm,
|
|||||||
int len;
|
int len;
|
||||||
uint8_t header[4];
|
uint8_t header[4];
|
||||||
|
|
||||||
len = myread(mpm->fd, header, sizeof(header));
|
len = mpm_serial_read(mpm->fd, header, sizeof(header));
|
||||||
if (len != sizeof(header))
|
if (len != sizeof(header))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "short read() from device (not addressed?)\n");
|
fprintf(stderr, "short read() from device (not addressed?)\n");
|
||||||
@ -367,10 +370,9 @@ static int mpm_recv(struct mpm_privdata *mpm,
|
|||||||
/* free space in output buffer? */
|
/* free space in output buffer? */
|
||||||
if ((bufferpos < buffersize) && (buffer != NULL))
|
if ((bufferpos < buffersize) && (buffer != NULL))
|
||||||
{
|
{
|
||||||
|
|
||||||
uint16_t size = MIN(buffersize - bufferpos, length);
|
uint16_t size = MIN(buffersize - bufferpos, length);
|
||||||
|
|
||||||
len = myread(mpm->fd, buffer + bufferpos, size);
|
len = mpm_serial_read(mpm->fd, buffer + bufferpos, size);
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "short read() from device (%d != %d)\n", len, size);
|
fprintf(stderr, "short read() from device (%d != %d)\n", len, size);
|
||||||
@ -379,7 +381,6 @@ static int mpm_recv(struct mpm_privdata *mpm,
|
|||||||
|
|
||||||
bufferpos += len;
|
bufferpos += len;
|
||||||
length -= len;
|
length -= len;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -388,7 +389,7 @@ static int mpm_recv(struct mpm_privdata *mpm,
|
|||||||
/* no space in output buffer, but device still sends data -> do dummy read */
|
/* no space in output buffer, but device still sends data -> do dummy read */
|
||||||
uint16_t size = MIN(sizeof(dummy), length);
|
uint16_t size = MIN(sizeof(dummy), length);
|
||||||
|
|
||||||
len = myread(mpm->fd, dummy, size);
|
len = mpm_serial_read(mpm->fd, dummy, size);
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "short read() from device (%d != %d)\n", len, size);
|
fprintf(stderr, "short read() from device (%d != %d)\n", len, size);
|
||||||
@ -728,14 +729,14 @@ static int mpm_read(struct multiboot *mboot,
|
|||||||
struct mpm_privdata *mpm = (struct mpm_privdata *)mboot->privdata;
|
struct mpm_privdata *mpm = (struct mpm_privdata *)mboot->privdata;
|
||||||
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "reading flash" : "reading eeprom";
|
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "reading flash" : "reading eeprom";
|
||||||
|
|
||||||
int pos = 0;
|
uint16_t pos = 0;
|
||||||
int size = (memtype == MEMTYPE_FLASH) ? mpm->flashsize : mpm->eepromsize;
|
uint16_t size = (memtype == MEMTYPE_FLASH) ? mpm->flashsize : mpm->eepromsize;
|
||||||
|
|
||||||
while (pos < size)
|
while (pos < size)
|
||||||
{
|
{
|
||||||
mboot->progress_cb(progress_msg, pos, size);
|
mboot->progress_cb(progress_msg, pos, size);
|
||||||
|
|
||||||
int len = MIN(READ_BLOCK_SIZE, size - pos);
|
uint16_t len = MIN(READ_BLOCK_SIZE, size - pos);
|
||||||
if (mpm_read_memory(mpm, dbuf->data + pos, len, memtype, pos))
|
if (mpm_read_memory(mpm, dbuf->data + pos, len, memtype, pos))
|
||||||
{
|
{
|
||||||
mboot->progress_cb(progress_msg, -1, -1);
|
mboot->progress_cb(progress_msg, -1, -1);
|
||||||
@ -761,12 +762,12 @@ static int mpm_write(struct multiboot *mboot,
|
|||||||
struct mpm_privdata *mpm = (struct mpm_privdata *)mboot->privdata;
|
struct mpm_privdata *mpm = (struct mpm_privdata *)mboot->privdata;
|
||||||
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "writing flash" : "writing eeprom";
|
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "writing flash" : "writing eeprom";
|
||||||
|
|
||||||
int pos = 0;
|
uint16_t pos = 0;
|
||||||
while (pos < dbuf->length)
|
while (pos < dbuf->length)
|
||||||
{
|
{
|
||||||
mboot->progress_cb(progress_msg, pos, dbuf->length);
|
mboot->progress_cb(progress_msg, pos, dbuf->length);
|
||||||
|
|
||||||
int len = (memtype == MEMTYPE_FLASH) ? mpm->flashpage : WRITE_BLOCK_SIZE;
|
uint16_t len = (memtype == MEMTYPE_FLASH) ? mpm->flashpage : WRITE_BLOCK_SIZE;
|
||||||
|
|
||||||
len = MIN(len, dbuf->length - pos);
|
len = MIN(len, dbuf->length - pos);
|
||||||
if (mpm_write_memory(mpm, dbuf->data + pos, len, memtype, pos))
|
if (mpm_write_memory(mpm, dbuf->data + pos, len, memtype, pos))
|
||||||
@ -792,14 +793,14 @@ static int mpm_verify(struct multiboot *mboot,
|
|||||||
struct mpm_privdata *mpm = (struct mpm_privdata *)mboot->privdata;
|
struct mpm_privdata *mpm = (struct mpm_privdata *)mboot->privdata;
|
||||||
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "verifing flash" : "verifing eeprom";
|
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "verifing flash" : "verifing eeprom";
|
||||||
|
|
||||||
int pos = 0;
|
uint16_t pos = 0;
|
||||||
uint8_t comp[READ_BLOCK_SIZE];
|
uint8_t comp[READ_BLOCK_SIZE];
|
||||||
|
|
||||||
while (pos < dbuf->length)
|
while (pos < dbuf->length)
|
||||||
{
|
{
|
||||||
mboot->progress_cb(progress_msg, pos, dbuf->length);
|
mboot->progress_cb(progress_msg, pos, dbuf->length);
|
||||||
|
|
||||||
int len = MIN(READ_BLOCK_SIZE, dbuf->length - pos);
|
uint16_t len = MIN(READ_BLOCK_SIZE, dbuf->length - pos);
|
||||||
if (mpm_read_memory(mpm, comp, len, memtype, pos))
|
if (mpm_read_memory(mpm, comp, len, memtype, pos))
|
||||||
{
|
{
|
||||||
mboot->progress_cb(progress_msg, -1, -1);
|
mboot->progress_cb(progress_msg, -1, -1);
|
||||||
@ -825,6 +826,7 @@ static int mpm_verify(struct multiboot *mboot,
|
|||||||
|
|
||||||
struct multiboot_ops mpm_ops =
|
struct multiboot_ops mpm_ops =
|
||||||
{
|
{
|
||||||
|
.exec_name = "mpmboot",
|
||||||
.alloc = mpm_alloc,
|
.alloc = mpm_alloc,
|
||||||
.free = mpm_free,
|
.free = mpm_free,
|
||||||
.get_memtype = mpm_get_memtype,
|
.get_memtype = mpm_get_memtype,
|
||||||
|
52
multiboot.c
52
multiboot.c
@ -33,16 +33,12 @@
|
|||||||
#define ACTION_READ 0x01
|
#define ACTION_READ 0x01
|
||||||
#define ACTION_WRITE 0x02
|
#define ACTION_WRITE 0x02
|
||||||
|
|
||||||
struct prog_mode {
|
static struct multiboot_ops * prog_ops[] =
|
||||||
char *progname;
|
|
||||||
struct multiboot_ops *ops;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct prog_mode prog_modes[] =
|
|
||||||
{
|
{
|
||||||
{ "twiboot", &twi_ops },
|
&twi_ops,
|
||||||
{ "mpmboot", &mpm_ops },
|
&mpm_ops,
|
||||||
{ "funkboot", &funk_ops },
|
&funk_ops,
|
||||||
|
&eprog_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mboot_action
|
struct mboot_action
|
||||||
@ -71,6 +67,11 @@ static struct option main_optargs[] =
|
|||||||
* ************************************************************************* */
|
* ************************************************************************* */
|
||||||
static void progress_mode0_cb(const char *msg, int pos, int size)
|
static void progress_mode0_cb(const char *msg, int pos, int size)
|
||||||
{
|
{
|
||||||
|
/* unused parameter */
|
||||||
|
(void)msg;
|
||||||
|
(void)pos;
|
||||||
|
(void)size;
|
||||||
|
|
||||||
/* no progress output */
|
/* no progress output */
|
||||||
} /* progress_mode0_cb */
|
} /* progress_mode0_cb */
|
||||||
|
|
||||||
@ -82,15 +83,16 @@ static void progress_mode1_cb(const char *msg, int pos, int size)
|
|||||||
{
|
{
|
||||||
if (pos != -1 && size != -1)
|
if (pos != -1 && size != -1)
|
||||||
{
|
{
|
||||||
char stars[50];
|
char stars[51];
|
||||||
int i;
|
int i;
|
||||||
int count = (pos * sizeof(stars) / size);
|
int count = (pos * 50 / size);
|
||||||
|
|
||||||
for (i = 0; i < sizeof(stars); i++)
|
for (i = 0; i < 50; i++)
|
||||||
{
|
{
|
||||||
stars[i] = (i < count) ? '*' : ' ';
|
stars[i] = (i < count) ? '*' : ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stars[50] = '\0';
|
||||||
printf("%-15s: [%s] (%d)\r", msg, stars, pos);
|
printf("%-15s: [%s] (%d)\r", msg, stars, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,14 +213,18 @@ static int main_optarg_cb(int val, const char *arg, void *privdata)
|
|||||||
switch (val)
|
switch (val)
|
||||||
{
|
{
|
||||||
case 'r': /* read */
|
case 'r': /* read */
|
||||||
if (add_action(mboot, ACTION_READ, arg) < 0)
|
if ((mboot->ops->read == NULL) ||
|
||||||
|
(add_action(mboot, ACTION_READ, arg) < 0)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'w': /* write */
|
case 'w': /* write */
|
||||||
if (add_action(mboot, ACTION_WRITE, arg) < 0)
|
if ((mboot->ops->write == NULL) ||
|
||||||
|
(add_action(mboot, ACTION_WRITE, arg) < 0)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -263,17 +269,19 @@ int main(int argc, char *argv[])
|
|||||||
char *progname = strrchr(argv[0], '/');
|
char *progname = strrchr(argv[0], '/');
|
||||||
progname = (progname != NULL) ? (progname +1) : argv[0];
|
progname = (progname != NULL) ? (progname +1) : argv[0];
|
||||||
|
|
||||||
int i;
|
unsigned int i;
|
||||||
for (i = 0; i < ARRAY_SIZE(prog_modes); i++)
|
for (i = 0; i < ARRAY_SIZE(prog_ops); i++)
|
||||||
{
|
{
|
||||||
struct prog_mode *mode = &prog_modes[i];
|
struct multiboot_ops * ops = prog_ops[i];
|
||||||
|
|
||||||
if (strcmp(progname, mode->progname) == 0)
|
if (strcmp(progname, ops->exec_name) == 0)
|
||||||
{
|
{
|
||||||
mboot = mode->ops->alloc();
|
mboot = ops->alloc();
|
||||||
if (mboot == NULL)
|
if (mboot == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "failed to allocate '%s'\n", progname);
|
fprintf(stderr, "failed to allocate '%s'\n",
|
||||||
|
progname);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -381,7 +389,9 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mboot->verify)
|
if (mboot->verify &&
|
||||||
|
(mboot->ops->verify != NULL)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
result = mboot->ops->verify(mboot, dbuf, action->memtype);
|
result = mboot->ops->verify(mboot, dbuf, action->memtype);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
|
@ -15,6 +15,8 @@ struct multiboot
|
|||||||
|
|
||||||
struct multiboot_ops
|
struct multiboot_ops
|
||||||
{
|
{
|
||||||
|
const char * exec_name;
|
||||||
|
|
||||||
struct multiboot * (* alloc)(void);
|
struct multiboot * (* alloc)(void);
|
||||||
void (* free)(struct multiboot *mboot);
|
void (* free)(struct multiboot *mboot);
|
||||||
|
|
||||||
@ -32,5 +34,6 @@ struct multiboot_ops
|
|||||||
extern struct multiboot_ops twi_ops;
|
extern struct multiboot_ops twi_ops;
|
||||||
extern struct multiboot_ops mpm_ops;
|
extern struct multiboot_ops mpm_ops;
|
||||||
extern struct multiboot_ops funk_ops;
|
extern struct multiboot_ops funk_ops;
|
||||||
|
extern struct multiboot_ops eprog_ops;
|
||||||
|
|
||||||
#endif /* _MULTIBOOT_H_ */
|
#endif /* _MULTIBOOT_H_ */
|
||||||
|
16
twi.c
16
twi.c
@ -360,14 +360,14 @@ static int twi_read(struct multiboot *mboot,
|
|||||||
struct twi_privdata *twi = (struct twi_privdata *)mboot->privdata;
|
struct twi_privdata *twi = (struct twi_privdata *)mboot->privdata;
|
||||||
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "reading flash" : "reading eeprom";
|
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "reading flash" : "reading eeprom";
|
||||||
|
|
||||||
int pos = 0;
|
uint16_t pos = 0;
|
||||||
int size = (memtype == MEMTYPE_FLASH) ? twi->flashsize : twi->eepromsize;
|
uint16_t size = (memtype == MEMTYPE_FLASH) ? twi->flashsize : twi->eepromsize;
|
||||||
|
|
||||||
while (pos < size)
|
while (pos < size)
|
||||||
{
|
{
|
||||||
mboot->progress_cb(progress_msg, pos, size);
|
mboot->progress_cb(progress_msg, pos, size);
|
||||||
|
|
||||||
int len = MIN(READ_BLOCK_SIZE, size - pos);
|
uint8_t len = MIN(READ_BLOCK_SIZE, size - pos);
|
||||||
|
|
||||||
if (twi_read_memory(twi, dbuf->data + pos, len, memtype, pos))
|
if (twi_read_memory(twi, dbuf->data + pos, len, memtype, pos))
|
||||||
{
|
{
|
||||||
@ -395,12 +395,12 @@ static int twi_write(struct multiboot *mboot,
|
|||||||
struct twi_privdata *twi = (struct twi_privdata *)mboot->privdata;
|
struct twi_privdata *twi = (struct twi_privdata *)mboot->privdata;
|
||||||
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "writing flash" : "writing eeprom";
|
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "writing flash" : "writing eeprom";
|
||||||
|
|
||||||
int pos = 0;
|
uint16_t pos = 0;
|
||||||
while (pos < dbuf->length)
|
while (pos < dbuf->length)
|
||||||
{
|
{
|
||||||
mboot->progress_cb(progress_msg, pos, dbuf->length);
|
mboot->progress_cb(progress_msg, pos, dbuf->length);
|
||||||
|
|
||||||
int len = (memtype == MEMTYPE_FLASH) ? twi->pagesize : WRITE_BLOCK_SIZE;
|
uint8_t len = (memtype == MEMTYPE_FLASH) ? twi->pagesize : WRITE_BLOCK_SIZE;
|
||||||
|
|
||||||
len = MIN(len, dbuf->length - pos);
|
len = MIN(len, dbuf->length - pos);
|
||||||
|
|
||||||
@ -426,7 +426,7 @@ static int twi_verify(struct multiboot *mboot, struct databuf *dbuf, int memtype
|
|||||||
struct twi_privdata *twi = (struct twi_privdata *)mboot->privdata;
|
struct twi_privdata *twi = (struct twi_privdata *)mboot->privdata;
|
||||||
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "verifing flash" : "verifing eeprom";
|
char *progress_msg = (memtype == MEMTYPE_FLASH) ? "verifing flash" : "verifing eeprom";
|
||||||
|
|
||||||
int pos = 0;
|
uint16_t pos = 0;
|
||||||
uint8_t comp[READ_BLOCK_SIZE];
|
uint8_t comp[READ_BLOCK_SIZE];
|
||||||
|
|
||||||
while (pos < dbuf->length)
|
while (pos < dbuf->length)
|
||||||
@ -571,6 +571,9 @@ static void twi_free(struct multiboot *mboot)
|
|||||||
static int twi_get_memtype(struct multiboot *mboot,
|
static int twi_get_memtype(struct multiboot *mboot,
|
||||||
const char *memname)
|
const char *memname)
|
||||||
{
|
{
|
||||||
|
/* unused parameter */
|
||||||
|
(void)mboot;
|
||||||
|
|
||||||
if (strcmp(memname, "flash") == 0)
|
if (strcmp(memname, "flash") == 0)
|
||||||
{
|
{
|
||||||
return MEMTYPE_FLASH;
|
return MEMTYPE_FLASH;
|
||||||
@ -613,6 +616,7 @@ static int twi_get_memsize(struct multiboot *mboot,
|
|||||||
|
|
||||||
struct multiboot_ops twi_ops =
|
struct multiboot_ops twi_ops =
|
||||||
{
|
{
|
||||||
|
.exec_name = "twiboot",
|
||||||
.alloc = twi_alloc,
|
.alloc = twi_alloc,
|
||||||
.free = twi_free,
|
.free = twi_free,
|
||||||
.get_memtype = twi_get_memtype,
|
.get_memtype = twi_get_memtype,
|
||||||
|
Loading…
Reference in New Issue
Block a user