Browse Source

fpgautils: load_bitstream_bytes support for Intel HEX format (.ihx) files

Luke Dashjr 12 years ago
parent
commit
de4b2e040d
2 changed files with 62 additions and 1 deletions
  1. 61 1
      fpgautils.c
  2. 1 0
      fpgautils.h

+ 61 - 1
fpgautils.c

@@ -1004,6 +1004,64 @@ FILE *open_xilinx_bitstream(const char *dname, const char *repr, const char *fwf
 	return f;
 	return f;
 }
 }
 
 
+bool load_bitstream_intelhex(bytes_t *rv, const char *dname, const char *fn)
+{
+	char buf[0x100];
+	size_t sz;
+	uint8_t xsz, xrt;
+	uint16_t xaddr;
+	FILE *F = open_bitstream(dname, fn);
+	if (!F)
+		return false;
+	while (!feof(F))
+	{
+		if (unlikely(ferror(F)))
+		{
+			applog(LOG_ERR, "Error reading '%s'", fn);
+			goto ihxerr;
+		}
+		fgets(buf, sizeof(buf), F);
+		if (unlikely(buf[0] != ':'))
+			goto ihxerr;
+		if (unlikely(!(
+			hex2bin(&xsz, &buf[1], 1)
+		 && hex2bin((unsigned char*)&xaddr, &buf[3], 2)
+		 && hex2bin(&xrt, &buf[7], 1)
+		)))
+		{
+			applog(LOG_ERR, "Error parsing in '%s'", fn);
+			goto ihxerr;
+		}
+		switch (xrt)
+		{
+			case 0:  // data
+				break;
+			case 1:  // EOF
+				fclose(F);
+				return true;
+			default:
+				applog(LOG_ERR, "Unsupported record type in '%s'", fn);
+				goto ihxerr;
+		}
+		xaddr = be16toh(xaddr);
+		sz = bytes_len(rv);
+		bytes_resize(rv, xaddr + xsz);
+		if (sz < xaddr)
+			memset(&bytes_buf(rv)[sz], 0xff, xaddr - sz);
+		if (unlikely(!(hex2bin(&bytes_buf(rv)[xaddr], &buf[9], xsz))))
+		{
+			applog(LOG_ERR, "Error parsing data in '%s'", fn);
+			goto ihxerr;
+		}
+		// TODO: checksum
+	}
+	
+ihxerr:
+	fclose(F);
+	bytes_reset(rv);
+	return false;
+}
+
 bool load_bitstream_bytes(bytes_t *rv, const char *dname, const char *fileprefix)
 bool load_bitstream_bytes(bytes_t *rv, const char *dname, const char *fileprefix)
 {
 {
 	FILE *F;
 	FILE *F;
@@ -1033,7 +1091,9 @@ bool load_bitstream_bytes(bytes_t *rv, const char *dname, const char *fileprefix
 			return true;
 			return true;
 	}
 	}
 	
 	
-	// TODO: Intel HEX
+	strcpy(&fnbuf[fplen], ".ihx");
+	if (load_bitstream_intelhex(rv, dname, fnbuf))
+		return true;
 	
 	
 	// TODO: Xilinx
 	// TODO: Xilinx
 	
 	

+ 1 - 0
fpgautils.h

@@ -47,6 +47,7 @@ extern ssize_t _serial_read(int fd, char *buf, size_t buflen, char *eol);
 #define serial_close(fd)  close(fd)
 #define serial_close(fd)  close(fd)
 
 
 extern FILE *open_xilinx_bitstream(const char *dname, const char *repr, const char *fwfile, unsigned long *out_len);
 extern FILE *open_xilinx_bitstream(const char *dname, const char *repr, const char *fwfile, unsigned long *out_len);
+extern bool load_bitstream_intelhex(bytes_t *out, const char *dname, const char *fn);
 extern bool load_bitstream_bytes(bytes_t *out, const char *dname, const char *fileprefix);
 extern bool load_bitstream_bytes(bytes_t *out, const char *dname, const char *fileprefix);
 
 
 extern int get_serial_cts(int fd);
 extern int get_serial_cts(int fd);