Esempio n. 1
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}