void usart_dostuff() { if (flag_command_ready) handle_command(); if (flag_read_flash) { bool_t verified = false; while (!verified) { flash_read(flash_addr); verified = flash_verify(flash_addr); } while (!verified) { _delay_ms(25); flash_read(flash_addr); verified = flash_verify(flash_addr); } flash_addr++; flag_read_flash = false; } if (flag_xmodem_next_packet) { prepare_packet(); usart_send(); } }
int wacom_i2c_flash(struct wacom_i2c *wac_i2c) { unsigned long max_address = 0; unsigned long start_address = START_ADDR; int i; int eraseBlock[150], eraseBlockNum; bool bRet; int iBLVer, iMpuType; int iRet; unsigned long ulMaxRange; #ifdef CONFIG_EPEN_WACOM_G9PL int iChecksum; int iStatus; bool bBootFlash = false; bool bMarking; #endif if (fw_data == NULL) { printk(KERN_ERR"epen:Data is NULL. Exit.\n"); return -1; } wac_i2c->pdata->compulsory_flash_mode(true); /*Reset */ wac_i2c->pdata->reset_platform_hw(); msleep(200); printk(KERN_DEBUG "epen:start getting the boot loader version\n"); /*Obtain boot loader version */ iRet = GetBLVersion(wac_i2c, &iBLVer); if (iRet != EXIT_OK) { printk(KERN_DEBUG "epen:failed to get Boot Loader version\n"); goto fw_update_error; } printk(KERN_DEBUG"epen:BL version: %x \n", iBLVer); printk(KERN_DEBUG "epen:start getting the MPU version\n"); /*Obtain MPU type: this can be manually done in user space */ iRet = GetMpuType(wac_i2c, &iMpuType); if (iRet != EXIT_OK) { printk(KERN_DEBUG "epen:failed to get MPU type\n"); goto fw_update_error; } #ifdef CONFIG_EPEN_WACOM_G9PLL if (iMpuType != MPU_W9007) { printk(KERN_DEBUG"epen:MPU is not for W9007 : %x \n", iMpuType); return EXIT_FAIL_GET_MPU_TYPE; } #endif printk(KERN_DEBUG"epen:MPU type: %x \n", iMpuType); /*Set start and end address and block numbers*/ eraseBlockNum = 0; start_address = START_ADDR; max_address = MAX_ADDR; #ifdef CONFIG_EPEN_WACOM_G9PL eraseBlock[eraseBlockNum++] = 2; eraseBlock[eraseBlockNum++] = 1; eraseBlock[eraseBlockNum++] = 0; eraseBlock[eraseBlockNum++] = 3; #else for (i = BLOCK_NUM; i >= 8; i--) { eraseBlock[eraseBlockNum] = i; eraseBlockNum++; } #endif #ifdef CONFIG_EPEN_WACOM_G9PL /*If MPU is in Boot mode, do below */ if (bBootFlash) eraseBlock[eraseBlockNum++] = 4; printk(KERN_DEBUG "epen:obtaining the checksum\n"); /*Calculate checksum */ iChecksum = wacom_i2c_flash_chksum(wac_i2c, fw_data, &max_address); printk(KERN_DEBUG "epen:Checksum is :%d\n", iChecksum); printk(KERN_DEBUG "epen:setting the security unlock\n"); /*Unlock security */ iRet = SetSecurityUnlock(wac_i2c, &iStatus); if (iRet != EXIT_OK) { printk(KERN_DEBUG "epen:failed to set security unlock\n"); goto fw_update_error; } #endif bRet = true; /*Set adress range */ ulMaxRange = max_address; ulMaxRange -= start_address; ulMaxRange >>= 6; if (max_address > (ulMaxRange << 6)) ulMaxRange++; printk(KERN_DEBUG "epen:connecting to Wacom Digitizer\n"); printk(KERN_DEBUG "epen:erasing the current firmware\n"); /*Erase the old program */ bRet = flash_erase(wac_i2c, eraseBlock, eraseBlockNum); if (!bRet) { printk(KERN_DEBUG "epen:failed to erase the user program\n"); iRet = EXIT_FAIL_ERASE; goto fw_update_error; } printk(KERN_DEBUG "epen:erasing done\n"); #ifdef CONFIG_EPEN_WACOM_G9PL max_address = 0x11FC0; #endif printk(KERN_DEBUG "epen:writing new firmware\n"); /*Write the new program */ bRet = flash_write(wac_i2c, fw_data, DATA_SIZE, start_address, &max_address, iMpuType); if (!bRet) { printk(KERN_DEBUG "epen:failed to write firmware\n"); iRet = EXIT_FAIL_WRITE_FIRMWARE; goto fw_update_error; } #ifdef CONFIG_EPEN_WACOM_G9PL printk(KERN_DEBUG "epen:start marking\n"); /*Set mark in writing process */ bRet = flash_marking(wac_i2c, DATA_SIZE, true, iMpuType); if (!bRet) { printk(KERN_DEBUG "epen:failed to mark firmware\n"); iRet = EXIT_FAIL_WRITE_FIRMWARE; goto fw_update_error; } /*Set the address for verify */ start_address = 0x4000; max_address = 0x11FBF; printk(KERN_DEBUG "epen:start the verification\n"); /*Verify the written program */ bRet = flash_verify(wac_i2c, fw_data, DATA_SIZE, start_address, &max_address, iMpuType); if (!bRet) { printk(KERN_DEBUG "epen:failed to verify the firmware\n"); iRet = EXIT_FAIL_VERIFY_FIRMWARE; goto fw_update_error; } printk(KERN_DEBUG "epen:checking the mark\n"); /*Set mark */ bRet = is_flash_marking(wac_i2c, DATA_SIZE, &bMarking, iMpuType); if (!bRet) { printk(KERN_DEBUG "epen:marking firmwrae failed\n"); iRet = EXIT_FAIL_WRITING_MARK_NOT_SET; goto fw_update_error; } #endif /*Enable */ printk(KERN_DEBUG "epen:closing the boot mode\n"); bRet = flash_end(wac_i2c); if (!bRet) { printk(KERN_DEBUG "epen:closing boot mode failed\n"); iRet = EXIT_FAIL_WRITING_MARK_NOT_SET; goto fw_update_error; } iRet = EXIT_OK; printk(KERN_DEBUG "epen:write and verify completed\n"); fw_update_error: wac_i2c->pdata->compulsory_flash_mode(false); /*Reset */ wac_i2c->pdata->reset_platform_hw(); msleep(200); return iRet; }
int wacom_i2c_flash(struct wacom_i2c *wac_i2c) { unsigned long max_address = 0; unsigned long start_address = 0x4000; int eraseBlock[32], eraseBlockNum; bool bRet; int iChecksum; int iBLVer, iMpuType, iStatus; bool bBootFlash = false; bool bMarking; int iRet; unsigned long ulMaxRange; pr_info("wacom: %s\n", __func__); pr_info( "wacom: start getting the boot loader version\n"); /*Obtain boot loader version*/ iRet = GetBLVersion(wac_i2c, &iBLVer); if (iRet != EXIT_OK) { pr_err( "wacom: %s failed to get Boot Loader version\n", __func__); return EXIT_FAIL_GET_BOOT_LOADER_VERSION; } pr_info( "wacom: start getting the MPU version\n"); /*Obtain MPU type: this can be manually done in user space*/ iRet = GetMpuType(wac_i2c, &iMpuType); if (iRet != EXIT_OK) { pr_err( "wacom: %s failed to get MPU type\n", __func__); return EXIT_FAIL_GET_MPU_TYPE; } /*Set start and end address and block numbers*/ eraseBlockNum = 0; start_address = 0x4000; max_address = 0x12FFF; eraseBlock[eraseBlockNum++] = 2; eraseBlock[eraseBlockNum++] = 1; eraseBlock[eraseBlockNum++] = 0; eraseBlock[eraseBlockNum++] = 3; /*If MPU is in Boot mode, do below*/ if (bBootFlash) eraseBlock[eraseBlockNum++] = 4; pr_info( "wacom: obtaining the checksum\n"); /*Calculate checksum*/ iChecksum = wacom_i2c_flash_chksum(wac_i2c, wac_i2c->fw_bin, &max_address); pr_info( "wacom: Checksum is :%d\n", iChecksum); bRet = true; pr_info( "wacom: setting the security unlock\n"); /*Unlock security*/ iRet = SetSecurityUnlock(wac_i2c, &iStatus); if (iRet != EXIT_OK) { pr_err( "wacom: %s failed to set security unlock\n", __func__); return iRet; } /*Set adress range*/ ulMaxRange = max_address; ulMaxRange -= start_address; ulMaxRange >>= 6; if (max_address > (ulMaxRange<<6)) ulMaxRange++; pr_info( "wacom: connecting to Wacom Digitizer\n"); pr_info( "wacom: erasing the current firmware\n"); /*Erase the old program*/ bRet = flash_erase(wac_i2c, true, eraseBlock, eraseBlockNum); if (!bRet) { pr_err( "wacom: %s failed to erase the user program\n", __func__); return EXIT_FAIL_ERASE; } pr_info( "wacom: erasing done\n"); max_address = 0x11FC0; pr_info( "wacom: writing new firmware\n"); /*Write the new program*/ bRet = flash_write(wac_i2c, wac_i2c->fw_bin, start_address, &max_address, iMpuType); if (!bRet) { pr_err( "wacom: %s failed to write firmware\n", __func__); return EXIT_FAIL_WRITE_FIRMWARE; } pr_info( "wacom: start marking\n"); /*Set mark in writing process*/ bRet = flash_marking(wac_i2c, true, iMpuType); if (!bRet) { pr_err( "wacom: %s failed to mark firmware\n", __func__); return EXIT_FAIL_WRITE_FIRMWARE; } /*Set the address for verify*/ start_address = 0x4000; max_address = 0x11FBF; pr_info( "wacom: start the verification\n"); /*Verify the written program*/ bRet = flash_verify(wac_i2c, wac_i2c->fw_bin, start_address, &max_address, iMpuType); if (!bRet) { pr_err( "wacom: failed to verify the firmware\n"); return EXIT_FAIL_VERIFY_FIRMWARE; } pr_info( "wacom: checking the mark\n"); /*Set mark*/ bRet = is_flash_marking(wac_i2c, &bMarking, iMpuType); if (!bRet) { pr_err( "wacom: %s marking firmwrae failed\n", __func__); return EXIT_FAIL_WRITING_MARK_NOT_SET; } /*Enable */ pr_info( "wacom: closing the boot mode\n"); bRet = flash_end(wac_i2c); if (!bRet) { pr_err( "wacom: %s closing boot mode failed\n", __func__); return EXIT_FAIL_WRITING_MARK_NOT_SET; } pr_info( "wacom: write and verify completed\n"); return EXIT_OK; }
int FlashVerify(struct wacom_i2c *wac_i2c, char *filename) { unsigned long max_address = 0; unsigned long start_address = 0x4000; bool bRet; int iChecksum; int iBLVer, iMpuType; unsigned long ulMaxRange; bool bMarking; int iRet; iRet = GetBLVersion(wac_i2c, &iBLVer); if (iRet != EXIT_OK) { pr_err( "wacom: %s failed to get Boot Loader version\n", __func__); return iRet; } iRet = GetMpuType(wac_i2c, &iMpuType); if (iRet != EXIT_OK) { pr_err( "wacom: %s failed to get MPU type\n", __func__); return iRet; } start_address = 0x4000; max_address = 0x11FBF; iChecksum = wacom_i2c_flash_chksum(wac_i2c, wac_i2c->fw_bin, &max_address); pr_info( "wacom: %s check sum is: %d\n", __func__, iChecksum); ulMaxRange = max_address; ulMaxRange -= start_address; ulMaxRange >>= 6; if (max_address > (ulMaxRange << 6)) ulMaxRange++; bRet = flash_verify(wac_i2c, wac_i2c->fw_bin, start_address, &max_address, iMpuType); if (!bRet) { pr_err( "wacom: %s failed to verify the firmware\n", __func__); return EXIT_FAIL_VERIFY_FIRMWARE; } bRet = is_flash_marking(wac_i2c, &bMarking, iMpuType); if (!bRet) { pr_err( "wacom: %s there's no marking\n", __func__); return EXIT_FAIL_VERIFY_WRITING_MARK; } pr_info( "wacom: %s verifying completed\n", __func__); return EXIT_OK; }
int main(int argc, char *argv[]) { int in_fd = STDIN_FILENO, i=0, got, offset, extra; int buf[256]; int fw = 1, fv = 1, fr = 0, verbose = 0; char *name = NULL; int block = 0; if ( argc > 2 ) { if ( '-' == argv[1][0] && 'b' == argv[1][1] && 0 == argv[1][3] ) { char c = argv[1][2]; if ( '0' <= c && c <= '9') block = c - '0'; else if ( 'a' <= c && c <= 'f') block = c - 'a' + 10; else if ( 'A' <= c && c <= 'F') block = c - 'A' + 10; else argc = 1; /* get usage message below */ argv++, argc--; } } switch (argc) { case 1: in_fd = STDIN_FILENO; fv = 0; /* Cannot rewind stdin, so do not verify */ break; case 2: if ( '-' == argv[1][0] ) { if ( 'r' != argv[1][1] || 0 != argv[1][2]) goto usage; fr = 1; fw = fv = 0; break; } name = argv[1]; in_fd = open(argv[1], O_RDONLY); if (in_fd < 0) { fprintf(stderr, "Can't open %s", argv[1]); perror(": "); exit(1); } break; case 3: if ( '-' != argv[1][0] || 0 != argv[1][2]) goto usage; if ( 'v' == argv[1][1] ) fw = 0; else if ( 'V' == argv[1][1] ) fw = 0, verbose = 1; else if ( 'w' == argv[1][1] ) fv = 0; else goto usage; name = argv[2]; in_fd = open(argv[2], O_RDONLY); if (in_fd < 0) { fprintf(stderr, "Can't open %s", argv[2]); perror(": "); exit(1); } break; default: usage: fprintf(stderr, "Usage: sa_flash [filename]\n"); fprintf(stderr, "Block number: sa_flash -bN [filename]\n"); fprintf(stderr, "Write only: sa_flash [-bN] -w filename\n"); fprintf(stderr, "Verify only: sa_flash [-bN] -v|-V filename\n"); fprintf(stderr, "Read to stdout: sa_flash [-bN] -r\n"); exit(1); } driver_fd = open("/dev/safl", O_RDWR); if (driver_fd < 0) { perror("Can't open device: "); exit (1); } flash_base = mmap(NULL, FLASH_SZ, PROT_READ|PROT_WRITE, MAP_SHARED, driver_fd, 0); if (flash_base == NULL) { perror("mmap failed: "); close(driver_fd); return 0; } if (!flash_verify()) { fprintf(stderr, "Couldn't find flash.\n"); exit(1); } if ( fw ) { if ( ! flash_erase_block(block) ) { fprintf(stderr,"Erase error block %x\n", block); exit(1); } extra = 0; offset = block * FLASH_BLOCK_SZ; while ((got = read(in_fd, ((char *)buf) + extra, sizeof(buf) - extra)) > 0) { got += extra; extra = got & 3; got /= 4; for (i = 0; i < got; ++i, offset += 4) if ( ! flash_write_dword(offset, buf[i]) ) fprintf(stderr,"Write error offset %06x\n",offset); if (extra) buf[0] = buf[i]; printf("*"); fflush(stdout); } if (extra) if ( ! flash_write_dword(offset, buf[i]) ) fprintf(stderr,"Write error offset %06x\n",offset); printf("\n"); } flash_normal_mode(); if ( fv ) { int badwords = 0; int skipping = 0; close( in_fd ); in_fd = open(name, O_RDONLY); if (in_fd < 0) { fprintf(stderr, "Can't re-open %s", argv[2]); perror(": "); exit(1); } extra = 0; offset = block * FLASH_BLOCK_SZ; while ((got = read(in_fd, ((char *)buf) + extra, sizeof(buf) - extra)) > 0) { got += extra; extra = got & 3; got /= 4; for (i = 0; i < got; ++i, offset += 4) { int data = flash_read_dword(offset); if ( data != buf[i] ) { badwords++; if ( !skipping ) { fprintf(stderr, "Bad data at offset %06x: %08x read %08x wanted\n", offset, data, buf[i] ); if ( !verbose && badwords > 15 ) { skipping = 1; fprintf(stderr, "(Too many errors, skipping...)\n"); } } } } if (extra) buf[0] = buf[i]; printf("+"); fflush(stdout); } if (extra) { int data = flash_read_dword(offset); if ( data != buf[0] ) { fprintf(stderr, "End data at offset %06x: %08x read %08x wanted\n", offset, data, buf[0] ); } } printf("\n"); if ( badwords ) fprintf(stderr, "Bad data: %d bad words out of %d (end offset %06x)\n", badwords, offset/4, offset ); } flash_normal_mode(); if ( fr ) { for ( offset = block * FLASH_BLOCK_SZ; offset < (block+1) * FLASH_BLOCK_SZ; offset += 4 ) { for ( i = 0; i < (sizeof(buf)/sizeof(int)); ++i, offset += 4 ) { buf[i] = flash_read_dword(offset); } if ( sizeof(buf) != write( STDOUT_FILENO, buf, sizeof(buf) ) ) { perror("Stdout write failed: "); exit(1); } fprintf(stderr,"r"); fflush(stderr); } fprintf(stderr,"\n"); } munmap((void *)flash_base, FLASH_SZ); close(driver_fd); return 0; }