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; }
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; }
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; }
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; }