mirror of
				https://github.com/DigitalDevices/dddvb.git
				synced 2025-03-01 10:35:23 +00:00 
			
		
		
		
	support reboot and fast erase
This commit is contained in:
		| @@ -38,25 +38,6 @@ | ||||
| #include "flash.h" | ||||
| #include "flash.c" | ||||
|  | ||||
| static int reboot(uint32_t off) | ||||
| { | ||||
| 	FILE *f; | ||||
| 	uint32_t time; | ||||
|  | ||||
| 	if ((f = fopen ("/sys/class/rtc/rtc0/since_epoch", "r")) == NULL) | ||||
| 		return -1; | ||||
| 	fscanf(f, "%u", &time); | ||||
| 	fclose(f); | ||||
|  | ||||
| 	if ((f = fopen ("/sys/class/rtc/rtc0/wakealarm", "r+")) == NULL) | ||||
| 		return -1; | ||||
| 	fprintf(f, "%u", time + off); | ||||
| 	fclose(f); | ||||
| 	system("/sbin/poweroff"); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int update_flash(struct ddflash *ddf) | ||||
| { | ||||
| 	char *fname; | ||||
|   | ||||
| @@ -11,7 +11,6 @@ | ||||
| #include <sys/ioctl.h> | ||||
| #include <linux/types.h> | ||||
|  | ||||
|  | ||||
| #include "flash.h" | ||||
| #include "flash.c" | ||||
|  | ||||
| @@ -115,11 +114,11 @@ static int update_flash(struct ddflash *ddf) | ||||
| 		if (!fname) | ||||
| 			fname = default_fname; | ||||
| 		if (name) | ||||
| 			printf("Card:   %s\n", name); | ||||
| 			printf("Card:     %s\n", name); | ||||
| 		if (ddf->flash_name) | ||||
| 			printf("Flash:  %s\n", ddf->flash_name); | ||||
| 		printf("Version:%08x\n", ddf->id.hw); | ||||
| 		//printf("REGMAPa: %08x\n", ddf->id.regmap); | ||||
| 			printf("Flash:    %s\n", ddf->flash_name); | ||||
| 		printf("Version:  %08x\n", ddf->id.hw); | ||||
| 		printf("REGMAP :  %08x\n", ddf->id.regmap); | ||||
| 		if ((res = update_image(ddf, fname, 0x10000, 0x100000, 1, 0)) == 1) | ||||
| 			stat |= 1; | ||||
| 		return stat; | ||||
| @@ -142,7 +141,7 @@ static int update_link(struct ddflash *ddf) | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static int update_card(int ddbnum, char *fname) | ||||
| static int update_card(int ddbnum, char *fname, int force) | ||||
| { | ||||
| 	struct ddflash ddf; | ||||
| 	char ddbname[80]; | ||||
| @@ -156,6 +155,7 @@ static int update_card(int ddbnum, char *fname) | ||||
| 	ddf.fd = ddb; | ||||
| 	ddf.link = 0; | ||||
| 	ddf.fname = fname; | ||||
| 	ddf.force = force; | ||||
| 	links = 1; | ||||
|  | ||||
| 	for (link = 0; link < links; link++) { | ||||
| @@ -206,18 +206,20 @@ static int usage() | ||||
|  | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
| 	int ddbnum = -1, all = 0, i, force = 0; | ||||
| 	int ddbnum = -1, all = 0, i, force = 0, reboot_len = -1; | ||||
| 	char *fname = 0; | ||||
| 	int ret; | ||||
| 	 | ||||
|         while (1) { | ||||
|                 int option_index = 0; | ||||
| 		int c; | ||||
|                 static struct option long_options[] = { | ||||
| 			{"reboot", optional_argument , NULL, 'r'}, | ||||
| 			{"help", no_argument , NULL, 'h'}, | ||||
| 			{0, 0, 0, 0} | ||||
| 		}; | ||||
|                 c = getopt_long(argc, argv,  | ||||
| 				"n:havfb:", | ||||
| 				"n:havfb:r::", | ||||
| 				long_options, &option_index); | ||||
| 		if (c==-1) | ||||
| 			break; | ||||
| @@ -232,9 +234,20 @@ int main(int argc, char **argv) | ||||
| 		case 'a': | ||||
| 			all = 1; | ||||
| 			break; | ||||
| 		case 'f': | ||||
| 			force = 1; | ||||
| 			break; | ||||
| 		case 'v': | ||||
| 			verbose++; | ||||
| 			break; | ||||
| 		case 'r': | ||||
| 			if (optarg) | ||||
| 				reboot_len = strtol(optarg, NULL, 0); | ||||
| 			else  | ||||
| 				reboot_len = 40; | ||||
| 			if (!reboot_len) | ||||
| 				reboot(40); | ||||
| 			break; | ||||
| 		case 'h': | ||||
| 			usage(); | ||||
| 			break; | ||||
| @@ -253,17 +266,19 @@ int main(int argc, char **argv) | ||||
| 	} | ||||
| 		 | ||||
| 	if (!all) | ||||
| 		return update_card(ddbnum, fname); | ||||
|  | ||||
| 	for (i = 0; i < 100; i++) { | ||||
| 		int ret = update_card(i, 0); | ||||
| 		 | ||||
| 		if (ret == -3)     /* could not open, no more cards! */ | ||||
| 			break;  | ||||
| 		if (ret < 0) | ||||
| 			return i; /* fatal error */  | ||||
| 		if (verbose >= 1) | ||||
| 			printf("card %d up to date\n", i); | ||||
| 	} | ||||
| 		ret = update_card(ddbnum, fname, force); | ||||
| 	else | ||||
| 		for (i = 0; i < 100; i++) { | ||||
| 			ret = update_card(i, 0, 0); | ||||
| 			 | ||||
| 			if (ret == -3)     /* could not open, no more cards! */ | ||||
| 				break;  | ||||
| 			if (ret < 0) | ||||
| 				return i; /* fatal error */  | ||||
| 			if (verbose >= 1) | ||||
| 				printf("card %d up to date\n", i); | ||||
| 		} | ||||
| 	if (reboot_len > 0) | ||||
| 		reboot(reboot_len); | ||||
| 	return 0;  | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,28 @@ | ||||
| static int reboot(uint32_t off) | ||||
| { | ||||
| 	FILE *f; | ||||
| 	uint32_t time; | ||||
|  | ||||
| 	if ((f = fopen ("/sys/class/rtc/rtc0/since_epoch", "r")) == NULL) | ||||
| 		return -1; | ||||
| 	fscanf(f, "%u", &time); | ||||
| 	fclose(f); | ||||
|  | ||||
| 	if ((f = fopen ("/sys/class/rtc/rtc0/wakealarm", "r+")) == NULL) | ||||
| 		return -1; | ||||
| 	fprintf(f, "%u", time + off); | ||||
| 	fclose(f); | ||||
| 	system("/sbin/poweroff"); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| static uint32_t linknr = 0; | ||||
|  | ||||
| int flashio(int ddb, int link, | ||||
| 	    uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen) | ||||
| 	    uint8_t *wbuf, uint32_t wlen, | ||||
| 	    uint8_t *rbuf, uint32_t rlen) | ||||
| { | ||||
| 	struct ddb_flashio fio = { | ||||
| 		.write_buf=wbuf, | ||||
| @@ -118,7 +139,7 @@ int flashread(int ddb, int link, uint8_t *buf, uint32_t addr, uint32_t len) | ||||
| 	uint32_t l; | ||||
|  | ||||
| 	while (len) { | ||||
| 		cmd[0] = 3; | ||||
| 		cmd[0] = 0x03; | ||||
| 		cmd[1] = (addr >> 16) & 0xff; | ||||
| 		cmd[2] = (addr >> 8) & 0xff; | ||||
| 		cmd[3] = addr & 0xff; | ||||
| @@ -137,12 +158,12 @@ int flashread(int ddb, int link, uint8_t *buf, uint32_t addr, uint32_t len) | ||||
| 	return 0; | ||||
| } | ||||
| #else | ||||
| static int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len) | ||||
| static int flashread(int ddb, int link, uint8_t *buf, uint32_t addr, uint32_t len) | ||||
| { | ||||
| 	uint8_t cmd[4]= {0x03, (addr >> 16) & 0xff,  | ||||
| 			 (addr >> 8) & 0xff, addr & 0xff}; | ||||
| 	uint8_t cmd[5]= {0x0b, (addr >> 16) & 0xff,  | ||||
| 		(addr >> 8) & 0xff, addr & 0xff, 0x00}; | ||||
| 	 | ||||
| 	return flashio(ddb, linknr, cmd, 4, buf, len); | ||||
| 	return flashio(ddb, link, cmd, 5, buf, len); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| @@ -500,10 +521,10 @@ int FlashWritePageMode(int dev, uint32_t FlashOffset, | ||||
|     uint8_t Cmd[260]; | ||||
|     int i, j; | ||||
|      | ||||
|     if( (BufferSize % 4096) != 0 ) return -1;   // Must be multiple of sector size | ||||
|     if ((BufferSize % 4096)) | ||||
| 	    return -1;   // Must be multiple of sector size | ||||
|  | ||||
|     do | ||||
|     { | ||||
|     do { | ||||
|         Cmd[0] = 0x50;  // EWSR | ||||
|         err = flashio(dev,linknr, Cmd,1,NULL,0); | ||||
|         if( err < 0 ) break; | ||||
| @@ -513,8 +534,7 @@ int FlashWritePageMode(int dev, uint32_t FlashOffset, | ||||
|         err = flashio(dev,linknr, Cmd,2,NULL,0); | ||||
|         if( err < 0 ) break; | ||||
|  | ||||
|         for(i = 0; i < BufferSize; i += 4096 ) | ||||
|         { | ||||
|         for(i = 0; i < BufferSize; i += 4096 ) { | ||||
|             if( (i & 0xFFFF) == 0 ) | ||||
|             { | ||||
|                 printf(" Erase    %08x\n",FlashOffset + i); | ||||
| @@ -588,124 +608,117 @@ int FlashWritePageMode(int dev, uint32_t FlashOffset, | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| static int flash_wait(int fd, uint32_t link) | ||||
| { | ||||
| 	while (1) { | ||||
| 		uint8_t rcmd = 0x05;  // RDSR | ||||
| 		int err = flashio(fd, link, &rcmd, 1, &rcmd, 1); | ||||
| 		 | ||||
| 		if (err < 0) | ||||
| 			return err; | ||||
| 		if ((rcmd & 0x01) == 0) | ||||
| 			break; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| int flashwrite_pagemode(struct ddflash *ddf, int dev, uint32_t FlashOffset, | ||||
| 			uint8_t LockBits, uint32_t fw_off) | ||||
| 			uint8_t LockBits, uint32_t fw_off, int be) | ||||
| { | ||||
| 	int err = 0; | ||||
| 	uint8_t cmd[260]; | ||||
| 	int i, j; | ||||
| 	uint32_t flen, blen; | ||||
| 	int blockerase = be && ((FlashOffset & 0xFFFF) == 0 ) && (flen >= 0x10000); | ||||
| 	 | ||||
| 	blen = flen = lseek(dev, 0, SEEK_END) - fw_off; | ||||
| 	if (blen % 0xff) | ||||
| 		blen = (blen + 0xff) & 0xffffff00;  | ||||
| 	printf("blen = %u, flen = %u\n", blen, flen); | ||||
| 	     | ||||
| 	do { | ||||
| 		cmd[0] = 0x50;  // EWSR | ||||
| 		err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0); | ||||
| 		if (err < 0) | ||||
| 			break; | ||||
| 		 | ||||
| 		cmd[0] = 0x01;  // WRSR | ||||
| 		cmd[1] = 0x00;  // BPx = 0, Unlock all blocks | ||||
| 		err = flashio(ddf->fd, ddf->link, cmd, 2, NULL, 0); | ||||
| 		if (err < 0) | ||||
| 			break; | ||||
| 		 | ||||
| 		for (i = 0; i < flen; i += 4096) { | ||||
| 			if ((i & 0xFFFF) == 0) | ||||
| 				printf(" Erase    %08x\n", FlashOffset + i); | ||||
| 			 | ||||
| 			cmd[0] = 0x06;  // WREN | ||||
| 			err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0); | ||||
| 			if (err < 0) | ||||
| 				break; | ||||
| 			 | ||||
| 			cmd[0] = 0x20;  // Sector erase ( 4Kb) | ||||
| 			cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); | ||||
| 			cmd[2] = ( (( FlashOffset + i ) >>  8) & 0xFF ); | ||||
| 			cmd[3] = 0x00; | ||||
| 			err = flashio(ddf->fd, ddf->link, cmd, 4, NULL, 0); | ||||
| 			if (err < 0) | ||||
| 				break; | ||||
| 	//printf("blen = %u, flen = %u\n", blen, flen); | ||||
| 	setbuf(stdout, NULL); | ||||
|  | ||||
| 			while (1) { | ||||
| 				cmd[0] = 0x05;  // RDSR | ||||
| 				err = flashio(ddf->fd, ddf->link, cmd, 1, &cmd[0], 1); | ||||
| 				if (err < 0) | ||||
| 					break; | ||||
| 				if ((cmd[0] & 0x01) == 0) | ||||
| 					break; | ||||
| 			} | ||||
| 			if (err < 0) | ||||
| 				break; | ||||
| 			 | ||||
| 		} | ||||
| 		if (err < 0) | ||||
| 			break; | ||||
| 		 | ||||
| 		for (j = blen - 256; j >= 0; j -= 256 ) { | ||||
| 			uint32_t len = 256;  | ||||
| 			ssize_t rlen; | ||||
| 			 | ||||
| 			if (lseek(dev, j + fw_off, SEEK_SET) < 0) { | ||||
| 				printf("seek error\n"); | ||||
| 				return -1; | ||||
| 			} | ||||
| 			if (flen - j < 256) { | ||||
| 				len = flen - j; | ||||
| 				memset(ddf->buffer, 0xff, 256); | ||||
| 			} | ||||
| 			rlen = read(dev, ddf->buffer, len); | ||||
| 			if (rlen < 0 || rlen != len) { | ||||
| 				printf("file read error %d,%d at %u\n", rlen, errno, j); | ||||
| 				return -1; | ||||
| 			} | ||||
| 			//printf ("write %u bytes at %08x\n", len, j); | ||||
| 			 | ||||
| 			 | ||||
| 			if ((j & 0xFFFF) == 0) | ||||
| 				printf(" Program %08x\n", FlashOffset + j); | ||||
| 			 | ||||
| 			cmd[0] = 0x06;  // WREN | ||||
| 			err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0); | ||||
| 			if (err < 0) | ||||
| 				break; | ||||
| 			 | ||||
| 			cmd[0] = 0x02;  // PP | ||||
| 			cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF ); | ||||
| 			cmd[2] = ( (( FlashOffset + j ) >>  8) & 0xFF ); | ||||
| 			cmd[3] = 0x00; | ||||
| 			memcpy(&cmd[4], ddf->buffer, 256); | ||||
| 			err = flashio(ddf->fd, ddf->link, cmd, 260, NULL, 0); | ||||
| 			if (err < 0) | ||||
| 				break; | ||||
| 			 | ||||
| 			while(1) { | ||||
| 				cmd[0] = 0x05;  // RDRS | ||||
| 				err = flashio(ddf->fd, ddf->link, cmd,1, &cmd[0], 1); | ||||
| 				if (err < 0) | ||||
| 					break; | ||||
| 				if ((cmd[0] & 0x01) == 0) | ||||
| 					break; | ||||
| 			} | ||||
| 			if (err < 0) | ||||
| 				break; | ||||
| 			 | ||||
| 		} | ||||
| 		if (err < 0) | ||||
| 			break; | ||||
| 		 | ||||
| 		cmd[0] = 0x50;  // EWSR | ||||
| 	cmd[0] = 0x50;  // EWSR | ||||
| 	err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0); | ||||
| 	if (err < 0) | ||||
| 		return err; | ||||
| 	 | ||||
| 	cmd[0] = 0x01;  // WRSR | ||||
| 	cmd[1] = 0x00;  // BPx = 0, Unlock all blocks | ||||
| 	err = flashio(ddf->fd, ddf->link, cmd, 2, NULL, 0); | ||||
| 	if (err < 0) | ||||
| 		return err; | ||||
| 	 | ||||
| 	for (i = 0; i < flen; ) { | ||||
| 		printf(" Erase    %08x\r", FlashOffset + i); | ||||
| 		cmd[0] = 0x06;  // WREN | ||||
| 		err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0); | ||||
| 		if (err < 0) | ||||
| 			break; | ||||
| 			return err; | ||||
| 		cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); | ||||
| 		cmd[2] = ( (( FlashOffset + i ) >>  8) & 0xFF ); | ||||
| 		cmd[3] = 0x00; | ||||
| 		if (blockerase && ((flen - i) >= 0x10000) ) { | ||||
| 			cmd[0] = 0xd8; | ||||
| 			i += 0x10000; | ||||
| 		} else { | ||||
| 			cmd[0] = 0x20;  // Sector erase ( 4Kb) | ||||
| 			i += 0x1000; | ||||
| 		} | ||||
| 		err = flashio(ddf->fd, ddf->link, cmd, 4, NULL, 0); | ||||
| 		if (err < 0) | ||||
| 			return err; | ||||
| 		err = flash_wait(ddf->fd, ddf->link); | ||||
| 		if (err < 0) | ||||
| 			return err; | ||||
| 	} | ||||
| 	for (j = blen - 256; j >= 0; j -= 256 ) { | ||||
| 		uint32_t len = 256;  | ||||
| 		ssize_t rlen; | ||||
| 		 | ||||
| 		cmd[0] = 0x01;  // WRSR | ||||
| 		cmd[1] = LockBits;  // BPx = 0, Lock all blocks | ||||
| 		err = flashio(ddf->fd, ddf->link, cmd, 2, NULL, 0); | ||||
| 	} while(0); | ||||
| 		if (lseek(dev, j + fw_off, SEEK_SET) < 0) { | ||||
| 			printf("seek error\n"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		if (flen - j < 256) { | ||||
| 			len = flen - j; | ||||
| 			memset(ddf->buffer, 0xff, 256); | ||||
| 		} | ||||
| 		rlen = read(dev, ddf->buffer, len); | ||||
| 		if (rlen < 0 || rlen != len) { | ||||
| 			printf("file read error %d,%d at %u\n", rlen, errno, j); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		printf(" Program  %08x\r", FlashOffset + j); | ||||
| 		 | ||||
| 		cmd[0] = 0x06;  // WREN | ||||
| 		err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0); | ||||
| 		if (err < 0) | ||||
| 			goto out; | ||||
| 		 | ||||
| 		cmd[0] = 0x02;  // PP | ||||
| 		cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF ); | ||||
| 		cmd[2] = ( (( FlashOffset + j ) >>  8) & 0xFF ); | ||||
| 		cmd[3] = 0x00; | ||||
| 		memcpy(&cmd[4], ddf->buffer, 256); | ||||
| 		err = flashio(ddf->fd, ddf->link, cmd, 260, NULL, 0); | ||||
| 		if (err < 0) | ||||
| 			goto out; | ||||
| 		err = flash_wait(ddf->fd, ddf->link); | ||||
| 		if (err < 0) | ||||
| 			goto out; | ||||
| 	} | ||||
| 	printf("\n"); | ||||
| 	 | ||||
| 	cmd[0] = 0x50;  // EWSR | ||||
| 	err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0); | ||||
| 	if (err < 0) | ||||
| 		goto out; | ||||
| 	 | ||||
| 	cmd[0] = 0x01;  // WRSR | ||||
| 	cmd[1] = LockBits;  // BPx = 0, Lock all blocks | ||||
| 	err = flashio(ddf->fd, ddf->link, cmd, 2, NULL, 0); | ||||
| out: | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
| @@ -845,7 +858,7 @@ static int flashwrite(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxle | ||||
|         case SSTI_SST25VF032B:  | ||||
| 		return flashwrite_SSTI(ddf, fs, addr, maxlen, fw_off); | ||||
|         case SSTI_SST25VF064C: | ||||
| 		return flashwrite_pagemode(ddf, fs, addr, 0x3c, fw_off); | ||||
| 		return flashwrite_pagemode(ddf, fs, addr, 0x3c, fw_off, 0); | ||||
| 	case SPANSION_S25FL116K:  | ||||
| 	case SPANSION_S25FL132K:  | ||||
| 	case SPANSION_S25FL164K:  | ||||
| @@ -853,7 +866,8 @@ static int flashwrite(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxle | ||||
| 	case WINBOND_W25Q32JV: | ||||
| 	case WINBOND_W25Q64JV: | ||||
| 	case WINBOND_W25Q128JV: | ||||
| 		return flashwrite_pagemode(ddf, fs, addr, 0x1c, fw_off); | ||||
| 	default: | ||||
| 		return flashwrite_pagemode(ddf, fs, addr, 0x1c, fw_off, 1); | ||||
| 	} | ||||
| 	return -1; | ||||
| } | ||||
| @@ -892,97 +906,55 @@ static int get_id(struct ddflash *ddf) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| struct devids { | ||||
| 	uint16_t id; | ||||
| 	char *name; | ||||
| 	char *fname; | ||||
| }; | ||||
|  | ||||
| #define DEV(_id, _name, _fname) { .id = _id, .name = _name, .fname = _fname } | ||||
|  | ||||
| static const struct devids ids[] = { | ||||
| 	DEV(0x0002, "Octopus 35", "DVBBridgeV1A_DVBBridgeV1A.bit"), | ||||
| 	DEV(0x0003, "Octopus", "DVBBridgeV1B_DVBBridgeV1B.fpga"), | ||||
| 	DEV(0x0005, "Octopus Classic", "DVBBridgeV2A_DD01_0005_STD.fpga"), | ||||
| 	DEV(0x0006, "CineS2 V7", "DVBBridgeV2A_DD01_0006_STD.fpga"), | ||||
| 	DEV(0x0007, "Octopus 4/8", "DVBBridgeV2A_DD01_0007_MXL.fpga"), | ||||
| 	DEV(0x0008, "Octopus 4/8", "DVBBridgeV2A_DD01_0008_CXD.fpga"), | ||||
| 	DEV(0x0009, "Octopus MAXSX8", "DVBBridgeV2A_DD01_0009_SX8.fpga"), | ||||
| 	DEV(0x000b, "Octopus MAXSX8 Basic", "DVBBridgeV2A_DD01_000B_SX8.fpga"), | ||||
| 	DEV(0x000a, "Octopus MAXM4", "DVBBridgeV2A_DD01_000A_M4.fpga"), | ||||
| 	DEV(0x0011, "Octopus CI", "DVBBridgeV2B_DD01_0011.fpga"), | ||||
| 	DEV(0x0012, "Octopus CI", "DVBBridgeV2B_DD01_0012_STD.fpga"), | ||||
| 	DEV(0x0013, "Octopus PRO", "DVBBridgeV2B_DD01_0013_PRO.fpga"), | ||||
| 	DEV(0x0020, "Octopus GT Mini", "DVBBridgeV2C_DD01_0020.fpga"), | ||||
| 	DEV(0x0201, "Modulator", "DVBModulatorV1B_DVBModulatorV1B.bit"), | ||||
| 	DEV(0x0203, "Modulator Test", "DVBModulatorV1B_DD01_0203.fpga"), | ||||
| 	DEV(0x0210, "Modulator V2", "DVBModulatorV2A_DD01_0210.fpga"), | ||||
| 	DEV(0x0220, "SDRModulator ATV", "SDRModulatorV1A_DD01_0220.fpga"), | ||||
| 	DEV(0x0221, "SDRModulator IQ", "SDRModulatorV1A_DD01_0221_IQ.fpga"),  | ||||
| 	DEV(0x0222, "SDRModulator DVBT", "SDRModulatorV1A_DD01_0222_DVBT.fpga"), | ||||
| 	DEV(0x0223, "SDRModulator IQ2", "SDRModulatorV1A_DD01_0223_IQ2.fpga"), | ||||
| 	DEV(0x0000, "UNKNOWN", 0), | ||||
| }; | ||||
|  | ||||
| static char *devid2fname(uint16_t devid, char **name) | ||||
| { | ||||
| 	int i; | ||||
| 	char *fname = 0; | ||||
|  | ||||
| 	switch (devid) { | ||||
| 	case 0x0002: | ||||
| 		fname="DVBBridgeV1A_DVBBridgeV1A.bit"; | ||||
| 		*name = "Octopus 35"; | ||||
| 		break; | ||||
| 	case 0x0003: | ||||
| 		fname="DVBBridgeV1B_DVBBridgeV1B.fpga"; | ||||
| 		*name = "Octopus"; | ||||
| 		break; | ||||
| 	case 0x0005: | ||||
| 		fname="DVBBridgeV2A_DD01_0005_STD.fpga"; | ||||
| 		*name = "Octopus Classic"; | ||||
| 		break; | ||||
| 	case 0x0006: | ||||
| 		fname="DVBBridgeV2A_DD01_0006_STD.fpga"; | ||||
| 		*name = "CineS2 V7"; | ||||
| 		break; | ||||
| 	case 0x0007: | ||||
| 		fname="DVBBridgeV2A_DD01_0007_MXL.fpga"; | ||||
| 		*name = "Octopus 4/8"; | ||||
| 		break; | ||||
| 	case 0x0008: | ||||
| 		fname="DVBBridgeV2A_DD01_0008_CXD.fpga"; | ||||
| 		*name = "Octopus 4/8"; | ||||
| 		break; | ||||
| 	case 0x0009: | ||||
| 		fname="DVBBridgeV2A_DD01_0009_SX8.fpga"; | ||||
| 		*name = "Octopus MAXSX8"; | ||||
| 		break; | ||||
| 	case 0x000b: | ||||
| 		fname="DVBBridgeV2A_DD01_000B_SX8.fpga"; | ||||
| 		*name = "Octopus MAXSX8 Basic"; | ||||
| 		break; | ||||
| 	case 0x000a: | ||||
| 		fname="DVBBridgeV2A_DD01_000A_M4.fpga"; | ||||
| 		*name = "Octopus MAXM4"; | ||||
| 		break; | ||||
| 	case 0x0011: | ||||
| 		fname="DVBBridgeV2B_DD01_0011.fpga"; | ||||
| 		*name = "Octopus CI"; | ||||
| 		break; | ||||
| 	case 0x0012: | ||||
| 		fname="DVBBridgeV2B_DD01_0012_STD.fpga"; | ||||
| 		*name = "Octopus CI"; | ||||
| 		break; | ||||
| 	case 0x0013: | ||||
| 		fname="DVBBridgeV2B_DD01_0013_PRO.fpga"; | ||||
| 		*name = "Octopus PRO"; | ||||
| 		break; | ||||
| 	case 0x0020: | ||||
| 		fname="DVBBridgeV2C_DD01_0020.fpga"; | ||||
| 		*name = "Octopus GT Mini"; | ||||
| 		break; | ||||
| 	case 0x0201: | ||||
| 		fname="DVBModulatorV1B_DVBModulatorV1B.bit"; | ||||
| 		*name = "Modulator"; | ||||
| 		break; | ||||
| 	case 0x0203: | ||||
| 		fname="DVBModulatorV1B_DD01_0203.fpga"; | ||||
| 		*name = "Modulator Test"; | ||||
| 		break; | ||||
| 	case 0x0210: | ||||
| 		fname="DVBModulatorV2A_DD01_0210.fpga"; | ||||
| 		*name = "Modulator V2"; | ||||
| 		break; | ||||
| 	case 0x0220: | ||||
| 		fname="SDRModulatorV1A_DD01_0220.fpga"; | ||||
| 		*name = "SDRModulator ATV"; | ||||
| 		break; | ||||
| 	case 0x0221: | ||||
| 		fname="SDRModulatorV1A_DD01_0221_IQ.fpga"; | ||||
| 		*name = "SDRModulator IQ"; | ||||
| 		break; | ||||
| 	case 0x0222: | ||||
| 		fname="SDRModulatorV1A_DD01_0222_DVBT.fpga"; | ||||
| 		*name = "SDRModulator DVBT"; | ||||
| 		break; | ||||
| 	default: | ||||
| 		*name = "UNKNOWN"; | ||||
| 		break; | ||||
| 	for (i = 0; ; i++) { | ||||
| 		const struct devids *id = &ids[i]; | ||||
|  | ||||
| 		if (devid == id->id || !id->id) { | ||||
| 			*name = id->name; | ||||
| 			fname = id->fname; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	return fname; | ||||
| } | ||||
|  | ||||
| 	 | ||||
|  | ||||
| static int flashcmp(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off) | ||||
| { | ||||
| 	off_t off; | ||||
| @@ -1015,9 +987,9 @@ static int flashcmp(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, | ||||
| 			 | ||||
| 		if (memcmp(buf, buf2, bl)) { | ||||
| 			printf("flash differs at %08x (offset %u)\n", addr, j); | ||||
| 			dump(buf, bl); | ||||
| 			printf("\n"); | ||||
| 			dump(buf2, bl); | ||||
| 			//dump(buf, bl); | ||||
| 			//printf("\n"); | ||||
| 			//dump(buf2, bl); | ||||
| 			return addr; | ||||
| 		} | ||||
| 	} | ||||
| @@ -1080,7 +1052,7 @@ static int check_fw(struct ddflash *ddf, char *fn, uint32_t *fw_off) | ||||
| 	unsigned int devid, version, length; | ||||
| 	unsigned int cid[8]; | ||||
| 	int cids = 0; | ||||
| 	uint32_t maxlen = 2 * 1024 * 1024, crc; | ||||
| 	uint32_t maxlen = 2 * 1024 * 1024, crc, fcrc; | ||||
| 	 | ||||
| 	fd = open(fn, O_RDONLY); | ||||
| 	if (fd < 0) { | ||||
| @@ -1148,11 +1120,17 @@ static int check_fw(struct ddflash *ddf, char *fn, uint32_t *fw_off) | ||||
| 	} | ||||
| 	p++; | ||||
| 	*fw_off = p; | ||||
| 	printf("        CRC     = %08x\n", crc); | ||||
| 	printf("        devid   = %04x\n", devid); | ||||
| 	printf("        version = %08x    (current image = %08x)\n", version, ddf->id.hw); | ||||
| 	fcrc = crc32(buf + p, length, 0xffffffff); | ||||
| 	printf("          CRC file  = %08x\n", fcrc); | ||||
| 	printf("          CRC flash = %08x\n", crc); | ||||
| 	printf("          devid     = %04x\n", devid); | ||||
| 	printf("          version   = %08x    (current image = %08x)\n", version, ddf->id.hw); | ||||
| 	//printf("        length = %u\n", length); | ||||
| 	//printf("fsize = %u, p = %u, f-p = %u\n", fsize, p, fsize - p); | ||||
| 	if (fcrc != crc) { | ||||
| 		printf("CRC error in file %s!\n", fn); | ||||
| 		return -4; | ||||
| 	} | ||||
| 	if (devid == ddf->id.device) { | ||||
| 		if (version <= (ddf->id.hw & 0xffffff)) { | ||||
| 			printf("%s is older or same version as flash\n", fn); | ||||
| @@ -1175,7 +1153,7 @@ static int update_image(struct ddflash *ddf, char *fn, | ||||
| 	int fs, res = 0; | ||||
| 	uint32_t fw_off = 0; | ||||
|  | ||||
| 	printf("File:   %s\n", fn); | ||||
| 	printf("File:     %s\n", fn); | ||||
| 	if (has_header) { | ||||
| 		int ck; | ||||
| 		ck = check_fw(ddf, fn, &fw_off); | ||||
| @@ -1192,6 +1170,10 @@ static int update_image(struct ddflash *ddf, char *fn, | ||||
| 	res = flashcmp(ddf, fs, adr, len, fw_off); | ||||
| 	if (res == -2) { | ||||
| 		printf("Flash already identical to %s\n", fn); | ||||
| 		if (ddf->force) { | ||||
| 			printf("but force enabled!\n"); | ||||
| 			res = 0; | ||||
| 		} | ||||
| 	} | ||||
| 	if (res < 0)  | ||||
| 		goto out; | ||||
| @@ -1200,6 +1182,9 @@ static int update_image(struct ddflash *ddf, char *fn, | ||||
| 		res = flashcmp(ddf, fs, adr, len, fw_off); | ||||
| 		if (res == -2) { | ||||
| 			res = 1; | ||||
| 			printf("Flash verify OK!\n"); | ||||
| 		} else { | ||||
| 			printf("Flash verify ERROR!\n"); | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
|   | ||||
| @@ -89,6 +89,7 @@ struct ddflash { | ||||
| 	int fd; | ||||
| 	uint32_t link; | ||||
| 	char *fname; | ||||
| 	int force; | ||||
| 	 | ||||
| 	struct ddb_id id; | ||||
| 	uint32_t version; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user