Example #1
0
static int check_version_string(fnusb_dev* dev) {
	freenect_context* ctx = dev->parent->parent;
	bootloader_command bootcmd;
	memset(&bootcmd, 0, sizeof(bootcmd));
	bootcmd.magic = fn_le32(0x06022009);
	bootcmd.tag   = fn_le32(dev->parent->audio_tag);
	bootcmd.bytes = fn_le32(0x60);
	bootcmd.cmd   = fn_le32(0);
	bootcmd.addr  = fn_le32(0x15);
	unsigned char buffer[512];
	int res;
	int transferred;

	FN_INFO("check_version_string(): About to send: ");
	dump_bl_cmd(ctx, bootcmd);

	// Send "get version string" command
	res = fnusb_bulk(dev, 1, (unsigned char*)&bootcmd, sizeof(bootcmd), &transferred);
	if(res != 0 || transferred != sizeof(bootcmd)) {
		FN_ERROR("Error: res: %d\ttransferred: %d (expected %d)\n",res, transferred, (int)sizeof(bootcmd));
		return -1;
	}

	// Read version string reply
	res = fnusb_bulk(dev, 0x81, buffer, 512, &transferred);
	if(res != 0 ) {
		FN_ERROR("Error reading version string: %d\ttransferred: %d (expected %d)\n", res, transferred, 0x60);
		return res;
	}
	FN_INFO("Read version string: ");
	int i;
	for(i = 0; i < transferred; ++i) {
		FN_INFO("%02X ", buffer[i]);
	}
	FN_INFO("\n");

	// Read status code reply
	res = get_reply(dev);
	dev->parent->audio_tag++;
	return res;
}
Example #2
0
FN_INTERNAL int upload_firmware(fnusb_dev* dev) {
	freenect_context* ctx = dev->parent->parent;
	bootloader_command bootcmd;
	memset(&bootcmd, 0, sizeof(bootcmd));
	bootcmd.magic = fn_le32(0x06022009);

	int res;
	int transferred;

	/* Search for firmware file (audios.bin) in the following places:
	 * $LIBFREENECT_FIRMWARE_PATH
	 * .
	 * ${HOME}/.libfreenect
	 * /usr/local/share/libfreenect
	 * /usr/share/libfreenect
	 */
	const char* fw_filename = "/audios.bin";
	int filenamelen = strlen(fw_filename);
	int i;
	int searchpathcount;
	FILE* fw = NULL;
	for(i = 0, searchpathcount = 5; !fw && i < searchpathcount; i++) {
		char* fwfile;
		int needs_free = 0;
		switch(i) {
			case 0: {
				char* envpath = getenv("LIBFREENECT_FIRMWARE_PATH");
				if (!envpath)
					continue;
				int pathlen = strlen(envpath);
				fwfile = malloc(pathlen + filenamelen + 1);
				strcpy(fwfile, envpath);
				strcat(fwfile, fw_filename);
				needs_free = 1;
				}
				break;
			case 1:
				fwfile = "./audios.bin";
				break;
			case 2: {
				// Construct $HOME/.libfreenect/
				char* home = getenv("HOME");
				if (!home)
					continue;
				int homelen = strlen(home);
				char* dotfolder = "/.libfreenect";
				int locallen = strlen(dotfolder);
				fwfile = (char*)malloc(homelen + locallen + filenamelen + 1);
				strcpy(fwfile, home);
				strcat(fwfile, dotfolder);
				strcat(fwfile, fw_filename);
				needs_free = 1;
				}
				break;
			case 3:
				fwfile = "/usr/local/share/libfreenect/audios.bin";
				break;
			case 4:
				fwfile = "/usr/share/libfreenect/audios.bin";
				break;
			default: break;
		}
		FN_INFO("Trying to open %s as firmware...\n", fwfile);
		fw = fopen(fwfile, "rb");
		if (needs_free) {
			free(fwfile);
		}
	}
	if (!fw) {
		FN_ERROR("upload_firmware: failed to find firmware file.\n");
		return -errno;
	}
	// Now we have an open firmware file handle.
	uint32_t addr = 0x00080000;
	int read;
	unsigned char page[0x4000];
	do {
		read = fread(page, 1, 0x4000, fw);
		if(read <= 0) {
			break;
		}
		bootcmd.tag = fn_le32(dev->parent->audio_tag);
		bootcmd.bytes = fn_le32(read);
		bootcmd.cmd = fn_le32(0x03);
		bootcmd.addr = fn_le32(addr);
		FN_INFO("About to send: ");
		dump_bl_cmd(ctx, bootcmd);
		// Send it off!
		res = fnusb_bulk(dev, 1, (unsigned char*)&bootcmd, sizeof(bootcmd), &transferred);
		if(res != 0 || transferred != sizeof(bootcmd)) {
			FN_ERROR("upload_firmware(): Error: res: %d\ttransferred: %d (expected %d)\n",res, transferred, (int)(sizeof(bootcmd)));
			fclose(fw);
			return -1;
		}
		int bytes_sent = 0;
		while(bytes_sent < read) {
			int to_send = (read - bytes_sent > 512 ? 512 : read - bytes_sent);
			res = fnusb_bulk(dev, 1, &page[bytes_sent], to_send, &transferred);
			if(res != 0 || transferred != to_send) {
				FN_ERROR("upload_firmware(): Error: res: %d\ttransferred: %d (expected %d)\n",res, transferred, to_send);
				fclose(fw);
				return -1;
			}
			bytes_sent += to_send;
		}
		res = get_reply(dev);
		addr += (uint32_t)read;
		dev->parent->audio_tag++;
	} while (read > 0);
	fclose(fw);
	fw = NULL;

	bootcmd.tag   = fn_le32(dev->parent->audio_tag);
	bootcmd.bytes = fn_le32(0);
	bootcmd.cmd   = fn_le32(0x04);
	bootcmd.addr  = fn_le32(0x00080030);
	dump_bl_cmd(ctx, bootcmd);
	res = fnusb_bulk(dev, 1, (unsigned char*)&bootcmd, sizeof(bootcmd), &transferred);
	if(res != 0 || transferred != sizeof(bootcmd)) {
		FN_ERROR("upload_firmware(): Error: res: %d\ttransferred: %d (expected %d)\n", res, transferred, (int)sizeof(bootcmd));
		return -1;
	}
	res = get_reply(dev);
	dev->parent->audio_tag++;
	FN_INFO("Firmware successfully uploaded and launched.  Device will disconnect and reenumerate.\n");
	return 0;
}
Example #3
0
FN_INTERNAL int upload_firmware(fnusb_dev* dev) {
	freenect_context* ctx = dev->parent->parent;
	bootloader_command bootcmd;
	memset(&bootcmd, 0, sizeof(bootcmd));
	bootcmd.magic = fn_le32(0x06022009);

	int res;
	int transferred;

	/* Search for firmware file (audios.bin) in the following places:
	 * $LIBFREENECT_FIRMWARE_PATH
	 * .
	 * ${HOME}/.libfreenect
	 * /usr/local/share/libfreenect
	 * /usr/share/libfreenect
	 */
	const char* fw_filename = "/audios.bin";
	int filenamelen = strlen(fw_filename);
	int i;
	int searchpathcount;
	FILE* fw = NULL;
	for(i = 0, searchpathcount = 5; !fw && i < searchpathcount; i++) {
		char* fwfile;
		int needs_free = 0;
		switch(i) {
			case 0: {
				char* envpath = getenv("LIBFREENECT_FIRMWARE_PATH");
				if (!envpath)
					continue;
				int pathlen = strlen(envpath);
				fwfile = malloc(pathlen + filenamelen + 1);
				strcpy(fwfile, envpath);
				strcat(fwfile, fw_filename);
				needs_free = 1;
				}
				break;
			case 1:
				fwfile = "./audios.bin";
				break;
			case 2: {
				// Construct $HOME/.libfreenect/
				char* home = getenv("HOME");
				if (!home)
					continue;
				int homelen = strlen(home);
				char* dotfolder = "/.libfreenect";
				int locallen = strlen(dotfolder);
				fwfile = (char*)malloc(homelen + locallen + filenamelen + 1);
				strcpy(fwfile, home);
				strcat(fwfile, dotfolder);
				strcat(fwfile, fw_filename);
				needs_free = 1;
				}
				break;
			case 3:
				fwfile = "/usr/local/share/libfreenect/audios.bin";
				break;
			case 4:
				fwfile = "/usr/share/libfreenect/audios.bin";
				break;
			default: break;
		}
		FN_INFO("Trying to open %s as firmware...\n", fwfile);
		fw = fopen(fwfile, "rb");
		if (needs_free) {
			free(fwfile);
		}
	}
	if (!fw) {
		FN_ERROR("upload_firmware: failed to find firmware file.\n");
		return -errno;
	}
	// Now we have an open firmware file handle.
	firmware_header fwheader;
	int read = 0;
	read = fread(&fwheader, 1, sizeof(firmware_header), fw);
	if (read != sizeof(firmware_header)) {
		FN_ERROR("upload_firmware: firmware image too small, has no header?\n");
		fclose(fw);
		return -errno;
	}
	// The file is serialized as little endian.
	fwheader.magic = fn_le32(fwheader.magic);
	fwheader.ver_major = fn_le16(fwheader.ver_major);
	fwheader.ver_minor = fn_le16(fwheader.ver_minor);
	fwheader.ver_release = fn_le16(fwheader.ver_release);
	fwheader.ver_patch = fn_le16(fwheader.ver_patch);
	fwheader.base_addr = fn_le32(fwheader.base_addr);
	fwheader.size = fn_le32(fwheader.size);
	fwheader.entry_addr = fn_le32(fwheader.entry_addr);
	FN_INFO("Found firmware image:\n");
	FN_INFO("\tmagic        %08X\n", fwheader.magic);
	FN_INFO("\tversion      %02d.%02d.%02d.%02d\n", fwheader.ver_major, fwheader.ver_minor, fwheader.ver_release, fwheader.ver_patch);
	FN_INFO("\tbase address 0x%08x\n", fwheader.base_addr);
	FN_INFO("\tsize         0x%08x\n", fwheader.size);
	FN_INFO("\tentry point  0x%08x\n", fwheader.entry_addr);

	rewind(fw);
	uint32_t addr = fwheader.base_addr;
	unsigned char page[0x4000];
	int total_bytes_sent = 0;
	do {
		size_t block_size = (0x4000 > fwheader.size - total_bytes_sent) ? fwheader.size - total_bytes_sent : 0x4000;
		read = fread(page, 1, block_size, fw);
		if(read <= 0) {
			break;
		}
		bootcmd.tag = fn_le32(dev->parent->audio_tag);
		bootcmd.bytes = fn_le32(read);
		bootcmd.cmd = fn_le32(0x03);
		bootcmd.addr = fn_le32(addr);
		FN_INFO("About to send: ");
		dump_bl_cmd(ctx, bootcmd);
		// Send it off!
		res = fnusb_bulk(dev, 1, (unsigned char*)&bootcmd, sizeof(bootcmd), &transferred);
		if(res != 0 || transferred != sizeof(bootcmd)) {
			FN_ERROR("upload_firmware(): Error: res: %d\ttransferred: %d (expected %d)\n",res, transferred, (int)(sizeof(bootcmd)));
			fclose(fw);
			return -1;
		}
		int bytes_sent = 0;
		while(bytes_sent < read) {
			int to_send = (read - bytes_sent > 512 ? 512 : read - bytes_sent);
			res = fnusb_bulk(dev, 1, &page[bytes_sent], to_send, &transferred);
			if(res != 0 || transferred != to_send) {
				FN_ERROR("upload_firmware(): Error: res: %d\ttransferred: %d (expected %d)\n",res, transferred, to_send);
				fclose(fw);
				return -1;
			}
			bytes_sent += to_send;
			total_bytes_sent += to_send;
		}
		res = get_reply(dev);
		addr += (uint32_t)read;
		dev->parent->audio_tag++;
	} while (read > 0);
	fclose(fw);
	fw = NULL;
	if (total_bytes_sent != fwheader.size) {
		FN_ERROR("upload_firmware: firmware image declared %d bytes, but file only contained %d bytes\n", fwheader.size, total_bytes_sent);
		return -1;
	}

	bootcmd.tag   = fn_le32(dev->parent->audio_tag);
	bootcmd.bytes = fn_le32(0);
	bootcmd.cmd   = fn_le32(0x04);
	bootcmd.addr  = fn_le32(fwheader.entry_addr);
	dump_bl_cmd(ctx, bootcmd);
	res = fnusb_bulk(dev, 1, (unsigned char*)&bootcmd, sizeof(bootcmd), &transferred);
	if(res != 0 || transferred != sizeof(bootcmd)) {
		FN_ERROR("upload_firmware(): Error: res: %d\ttransferred: %d (expected %d)\n", res, transferred, (int)sizeof(bootcmd));
		return -1;
	}
	res = get_reply(dev);
	dev->parent->audio_tag++;
	FN_INFO("Firmware successfully uploaded and launched.  Device will disconnect and reenumerate.\n");
	return 0;
}
Example #4
0
int upload_firmware(libusb_device_handle* dev) {
	bootloader_command bootcmd;
	memset(&bootcmd, 0, sizeof(bootcmd));
	bootcmd.magic = le32(0x06022009);
	bootcmd.tag   = le32(tag);
	bootcmd.bytes = le32(0x60);
	bootcmd.cmd   = le32(0);
	bootcmd.addr  = le32(0x15);

	int res;
	int transferred;

/*
    // First transfer happens to be a version query, and not necessary.
	LOG("About to send: ");
	dump_bl_cmd(bootcmd);

	res = libusb_bulk_transfer(dev, 1, (unsigned char*)&bootcmd, sizeof(bootcmd), &transferred, 0);
	if(res != 0 || transferred != sizeof(bootcmd)) {
		LOG("Error: res: %d\ttransferred: %d (expected %d)\n",res, transferred, sizeof(bootcmd));
		return -1;
	}
	res = get_first_reply(dev); // This first one doesn't have the usual magic bytes at the beginning, and is 96 bytes long - much longer than the usual 12-byte replies.
	res = get_reply(dev); // I'm not sure why we do this twice here, but maybe it'll make sense later.
	tag++;
*/
	const char* fw_filename = "audios.bin";
	FILE* fw = fopen(fw_filename, "r");
	if(fw == NULL) {
		fprintf(stderr, "Failed to open %s: error %d", fw_filename, errno);
		return -errno;
	}
	uint32_t addr = 0x00080000;
	int read;
	do {
		read = fread(page, 1, 0x4000, fw);
		if(read <= 0) {
			break;
		}
		bootcmd.tag = le32(tag);
		bootcmd.bytes = le32(read);
		bootcmd.cmd = le32(0x03);
		bootcmd.addr = le32(addr);
		LOG("About to send: ");
		dump_bl_cmd(bootcmd);
		// Send it off!
		res = libusb_bulk_transfer(dev, 1, (unsigned char*)&bootcmd, sizeof(bootcmd), &transferred, 0);
		if(res != 0 || transferred != sizeof(bootcmd)) {
			LOG("Error: res: %d\ttransferred: %d (expected %d)\n",res, transferred, (int)(sizeof(bootcmd)));
			return -1;
		}
		int bytes_sent = 0;
		while(bytes_sent < read) {
			int to_send = (read - bytes_sent > 512 ? 512 : read - bytes_sent);
			res = libusb_bulk_transfer(dev, 1, &page[bytes_sent], to_send, &transferred, 0);
			if(res != 0 || transferred != to_send) {
				LOG("Error: res: %d\ttransferred: %d (expected %d)\n",res, transferred, to_send);
				return -1;
			}
			bytes_sent += to_send;
		}
		res = get_reply(dev);
		addr += (uint32_t)read;
		tag++;
	} while (read > 0);
	fclose(fw);
	fw = NULL;

	bootcmd.tag   = le32(tag);
	bootcmd.bytes = le32(0);
	bootcmd.cmd   = le32(0x04);
	bootcmd.addr  = le32(0x00080030);
	dump_bl_cmd(bootcmd);
	res = libusb_bulk_transfer(dev, 1, (unsigned char*)&bootcmd, sizeof(bootcmd), &transferred, 0);
	if(res != 0 || transferred != sizeof(bootcmd)) {
		LOG("Error: res: %d\ttransferred: %d (expected %d)\n", res, transferred, (int)sizeof(bootcmd));
		return -1;
	}
	res = get_reply(dev);
	tag++;
	LOG("Firmware successfully uploaded and launched.  Device will disconnect and reenumerate.\n");
	return 0;
}