Blob Blame History Raw
From 488dad67eaa504d87151747c3bdcf71ca3d1efe8 Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Tue, 7 Oct 2014 00:12:34 +0200
Subject: [PATCH 3/3] Fix support for devices with irregular memory sizes

E.g. PIC12F675 has memory of 0x7fe size -- the last word is configuration word
that is handled separately.
---
 main.c    | 25 +++++++++++++++++--------
 minipro.c | 14 +++++++-------
 minipro.h |  4 ++--
 3 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/main.c b/main.c
index 3229a2c..34ec415 100644
--- a/main.c
+++ b/main.c
@@ -145,12 +145,12 @@ void read_page_ram(minipro_handle_t *handle, unsigned char *buf, unsigned int ty
 	sprintf(status_msg, "Reading %s... ", name);
 
 	device_t *device = handle->device;
+	int blocks_count = size / device->read_buffer_size;
 	if(size % device->read_buffer_size != 0) {
-		ERROR2("Wrong page size: %d bytes", size);
+		blocks_count++;
 	}
 
 	int i;
-	int blocks_count = size / device->read_buffer_size;
 	for(i = 0; i < blocks_count; i++) {
 		update_status(status_msg, "%2d%%", i * 100 / blocks_count);
 		// Translating address to protocol-specific
@@ -158,7 +158,11 @@ void read_page_ram(minipro_handle_t *handle, unsigned char *buf, unsigned int ty
 		if(device->opts4 & 0x2000) {
 			addr = addr >> 1;
 		}
-		minipro_read_block(handle, type, addr, buf + i * device->read_buffer_size);
+		int len = device->read_buffer_size;
+		// Last block
+		if ((i + 1) * len > size)
+			len = size % len;
+		minipro_read_block(handle, type, addr, buf + i * device->read_buffer_size, len);
 	}
 
 	update_status(status_msg, "OK\n");
@@ -169,12 +173,13 @@ void write_page_ram(minipro_handle_t *handle, unsigned char *buf, unsigned int t
 	sprintf(status_msg, "Writing %s... ", name);
 
 	device_t *device = handle->device;
-	if(size % device->write_buffer_size != 0) {
-		ERROR2("Wrong page size: %d bytes", size);
-	}
 	
-	int i;
 	int blocks_count = size / device->write_buffer_size;
+	if(size % device->read_buffer_size != 0) {
+		blocks_count++;
+	}
+
+	int i;
 	for(i = 0; i < blocks_count; i++) {
 		update_status(status_msg, "%2d%%", i * 100 / blocks_count);
 		// Translating address to protocol-specific
@@ -182,7 +187,11 @@ void write_page_ram(minipro_handle_t *handle, unsigned char *buf, unsigned int t
 		if(device->opts4 & 0x2000) {
 			addr = addr >> 1;
 		}
-		minipro_write_block(handle, type, addr, buf + i * device->write_buffer_size);
+		int len = device->write_buffer_size;
+		// Last block
+		if ((i + 1) * len > size)
+			len = size % len;
+		minipro_write_block(handle, type, addr, buf + i * device->write_buffer_size, len);
 	}
 	update_status(status_msg, "OK\n");
 }
diff --git a/minipro.c b/minipro.c
index 763ce56..3dbd117 100644
--- a/minipro.c
+++ b/minipro.c
@@ -115,20 +115,20 @@ int minipro_get_status(minipro_handle_t *handle) {
 	return(load_int(buf, 2, MP_LITTLE_ENDIAN));
 }
 
-void minipro_read_block(minipro_handle_t *handle, unsigned int type, unsigned int addr, unsigned char *buf) {
+void minipro_read_block(minipro_handle_t *handle, unsigned int type, unsigned int addr, unsigned char *buf, unsigned int len) {
 	msg_init(msg, type, handle->device);
-	format_int(&(msg[2]), handle->device->read_buffer_size, 2, MP_LITTLE_ENDIAN);
+	format_int(&(msg[2]), len, 2, MP_LITTLE_ENDIAN);
 	format_int(&(msg[4]), addr, 3, MP_LITTLE_ENDIAN);
 	msg_send(handle, msg, 18);
-	msg_recv(handle, buf, handle->device->read_buffer_size);
+	msg_recv(handle, buf, len);
 }
 
-void minipro_write_block(minipro_handle_t *handle, unsigned int type, unsigned int addr, unsigned char *buf) {
+void minipro_write_block(minipro_handle_t *handle, unsigned int type, unsigned int addr, unsigned char *buf, unsigned int len) {
 	msg_init(msg, type, handle->device);
-	format_int(&(msg[2]), handle->device->write_buffer_size, 2, MP_LITTLE_ENDIAN);
+	format_int(&(msg[2]), len, 2, MP_LITTLE_ENDIAN);
 	format_int(&(msg[4]), addr, 3, MP_LITTLE_ENDIAN);
-	memcpy(&(msg[7]), buf, handle->device->write_buffer_size);
-	msg_send(handle, msg, 7 + handle->device->write_buffer_size);
+	memcpy(&(msg[7]), buf, len);
+	msg_send(handle, msg, 7 + len);
 }
 
 /* Model-specific ID, e.g. AVR Device ID (not longer than 4 bytes) */
diff --git a/minipro.h b/minipro.h
index 3ff2a59..0d8578e 100644
--- a/minipro.h
+++ b/minipro.h
@@ -52,8 +52,8 @@ void minipro_end_transaction(minipro_handle_t *handle);
 void minipro_protect_off(minipro_handle_t *handle);
 void minipro_protect_on(minipro_handle_t *handle);
 int minipro_get_status(minipro_handle_t *handle);
-void minipro_read_block(minipro_handle_t *handle, unsigned int type, unsigned int addr, unsigned char *buf);
-void minipro_write_block(minipro_handle_t *handle, unsigned int type, unsigned int addr, unsigned char *buf);
+void minipro_read_block(minipro_handle_t *handle, unsigned int type, unsigned int addr, unsigned char *buf, unsigned int len);
+void minipro_write_block(minipro_handle_t *handle, unsigned int type, unsigned int addr, unsigned char *buf, unsigned int len);
 int minipro_get_chip_id(minipro_handle_t *handle);
 void minipro_read_fuses(minipro_handle_t *handle, unsigned int type, unsigned int length, unsigned char *buf);
 void minipro_write_fuses(minipro_handle_t *handle, unsigned int type, unsigned int length, unsigned char *buf);
-- 
2.1.0