Hello,

I have done more test and find a functionnal calibration method.

Strangely, the calibration return returns Mean_H and not the expected status. I need to read the "FP Status" register for the calibration to work in the next step.

Also, i added 0x04f3:0x01cA to the test list.

Hans, can you help us to find a recent list of ids?

All work now for me:

$ sudo ./elanfp
Device with vid 4f3 pid 903 found.
Config number is 1
CMD RESET sent
CMD Fuse Load sent
CMD VERSION sent
FP Bridge FW Version 1.53
CMD Get Image Size sent
width x height = 96x96
CMD Get Calibration Mean sent
calibration mean value: 33792 (0x8400)
CMD CALIBRATION sent
Calibration Status: 0x84
CMD STATUS sent
Status: 0x1
CMD Get Calibration Mean sent
calibration mean value: 256 (0x100)
CMD Wait For Finger sent
Received 0x55
CMD Get Image sent
Received 18432


If others confirm maybe Igor can modify the driver?

On 2018-01-17 12:12, Igor Filatov wrote:
Looks like o1ca as well https://github.com/iafilatov/libfprint/pull/4
I wonder if we can get a list of ids if devices like these.

2018-01-17 12:50 GMT+02:00 Sébastien Béchet <sebastien.bec...@osinix.com>:
Hello,

In attachment what I understood from the documentation.

must work for

0x04f3,0x0903
0x04f3,0x0907
0x04f3,0x0C03
0x04f3,0x0C16

Please try it.

CC	= gcc
LD	= gcc
OPT 	= -O1 -s 
CFLAGS 	= $(OPT) -c -I/usr/include/libusb-1.0
LDFLAGS	= -DPTW32_STATIC_LIB $(OPT)
LIBS	= -lrt -lusb-1.0

all:
	$(CC) $(CFLAGS) elanfp.c -o elanfp.o
	$(LD) $(LDFLAGS) elanfp.o $(LIBS) -o elanfp

clean: 
	rm -f *.o elanfp
	
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <libusb.h>

#define BULK_EP1_OUT    0x01
#define BULK_EP2_IN     0x82
#define BULK_EP3_IN     0x83

#define IMAGE_PACKET_SIZE (96 * 96 * 2)
char img_buf[IMAGE_PACKET_SIZE];


char set_cmd_reset[2] = { 0x40, 0x11 };
char get_cmd_status[2] = { 0x40, 0x13 };
char set_cmd_fuse_load[2] = { 0x40, 0x14 };
char get_cmd_image_size[2] = { 0x00, 0x0C };
char get_cmd_version[2] = { 0x40, 0x19 };
char get_cmd_calibration[2] = { 0x40, 0x23 };
char get_cmd_calibration_mean[2] = { 0x40, 0x24 };
char get_cmd_waitforfinger[2] = { 0x40, 0x3f };
char get_cmd_image[2] = { 0x00, 0x09 };


char set_cmd_stop_prescan[2] = { 0x00, 0x0b };
char get_cmd_cal_mean[2] = { 0x40, 0x24 };


int write_to_file(char* buf, int size) {
    FILE *fp;
    fp = fopen("./out.fp","w");
    if (fp < 0) return 1;
    fwrite(buf, 1, size, fp);
    fclose(fp);
    return 0;
}

int main(int argc, char* argv[]) {
    int r0, i, devs_count = 0, libusb_config = 0, transferred = 0;
    int id = 0;

    struct libusb_device **devs;
    struct libusb_device *dev;
    struct libusb_device_descriptor desc;
    struct libusb_device_handle *handle = NULL;

    if (argc ==2) {
      id = atoi((const char*)argv[1]);
    }

    r0 = libusb_init(NULL);
    if (r0 < 0) return 1;

    devs_count = libusb_get_device_list(NULL, &devs);
    if (devs_count < 0) {
        libusb_exit(NULL);
        printf("Error %d\n", r0);
        return 2;
    }

    while (1) {
        dev = devs[i];
        if (dev != NULL) {
            r0 = libusb_get_device_descriptor(dev, &desc);
            if (r0 < 0) continue;

            if ((desc.idVendor == 0x04f3) && (desc.idProduct == 0x01cA) ||
                (desc.idVendor == 0x04f3) && (desc.idProduct == 0x0903) ||
                (desc.idVendor == 0x04f3) && (desc.idProduct == 0x0907) ||
                (desc.idVendor == 0x04f3) && (desc.idProduct == 0x0c03) ||
                (desc.idVendor == 0x04f3) && (desc.idProduct == 0x0c16) ) {
                r0 = 0;
                printf("Device with vid %x pid %x found.\n", desc.idVendor, desc.idProduct);
                break;
            }
        } else {
            r0 = 3;
            break;
        }

        i++;
        if (i > devs_count) {
            r0 = 99;
            goto app_exit;
        }
    }

    if (r0 != 0) goto app_exit;

    /*****************************************************/

    r0 = libusb_open(dev, &handle);
    if (r0 < 0) {
        r0 = 5;
        goto app_exit;
    }

    r0 = libusb_get_configuration(handle, &libusb_config);
    if (r0 != 0) {
        r0 = 98;
        goto app_exit_2;
    }

    printf("Config number is %d\n", libusb_config);

    if (libusb_config > 1) {
        r0 = libusb_set_configuration(handle, 1);
        if (r0 != 0) {
            r0 = 97;
            goto app_exit_2;
        }
        printf("Config set to 1\n");
    }

    if (libusb_kernel_driver_active(handle, 0) == 1) {
        if(libusb_detach_kernel_driver(handle, 0) != 0) {
            r0 = 96;
            goto app_exit_2;
        }
    }

    r0 = libusb_claim_interface(handle, 0);
    if (r0 != 0) {
        r0 = 95;
        goto app_exit_2;
    }

    /* reset */

    r0 = libusb_bulk_transfer(handle, BULK_EP1_OUT, set_cmd_reset, 2, &transferred, 0);
    if((r0 == 0) && (transferred == 2)) {
        printf("CMD RESET sent\n");
    }
    usleep(5000);
    r0 = libusb_bulk_transfer(handle, BULK_EP1_OUT, set_cmd_fuse_load, 2, &transferred, 0);
    if((r0 == 0) && (transferred == 2)) {
        printf("CMD Fuse Load sent\n");
    }

    /* version */

    r0 = libusb_bulk_transfer(handle, BULK_EP1_OUT, get_cmd_version, 2, &transferred, 0);
    if((r0 == 0) && (transferred == 2)) {
        printf("CMD VERSION sent\n");
    }
    r0 = libusb_bulk_transfer(handle, BULK_EP3_IN, img_buf, 2, &transferred, 0);
    printf("FP Bridge FW Version %d.%d\n", img_buf[0], img_buf[1]);

    /* image size */

    r0 = libusb_bulk_transfer(handle, BULK_EP1_OUT, get_cmd_image_size, 2, &transferred, 0);
    if((r0 == 0) && (transferred == 2)) {
        printf("CMD Get Image Size sent\n");
    }
    r0 = libusb_bulk_transfer(handle, BULK_EP3_IN, img_buf, 4, &transferred, 0);
    printf("Width x height = %dx%d\n", img_buf[0], img_buf[2]);

    /* calibration */

    do {
      /* calibration image mean value */
      r0 = libusb_bulk_transfer(handle, BULK_EP1_OUT, get_cmd_calibration_mean, 2, &transferred, 0);
      if((r0 == 0) && (transferred == 2)) {
          printf("CMD Get Calibration Mean sent\n");
      }
      r0 = libusb_bulk_transfer(handle, BULK_EP3_IN, img_buf, 2, &transferred, 0);
      i = ((unsigned char)img_buf[0]<<8 | (unsigned char)img_buf[1])&0x0FFFF;
      printf("calibration mean value: %d (0x%x)\n", i, i);

      if (i > 500) {
        unsigned char result = 0;

        /* calibration */
        r0 = libusb_bulk_transfer(handle, BULK_EP1_OUT, get_cmd_calibration, 2, &transferred, 0);
        if((r0 == 0) && (transferred == 2)) {
            printf("CMD CALIBRATION sent\n");
        }
        r0 = libusb_bulk_transfer(handle, BULK_EP3_IN, &result, 1, &transferred, 0);
        printf("Calibration Status: 0x%x\n", result);

        r0 = libusb_bulk_transfer(handle, BULK_EP1_OUT, get_cmd_status, 2, &transferred, 0);
        if((r0 == 0) && (transferred == 2)) {
            printf("CMD STATUS sent\n");
        }
        r0 = libusb_bulk_transfer(handle, BULK_EP3_IN, &result, 1, &transferred, 0);
        printf("Status: 0x%x\n", result);

        if (result == 0x03) break; /* Never happend, always 0x01! */

        usleep(5000);
      }
    } while (i > 500);

    /* wait for image */

    r0 = libusb_bulk_transfer(handle, BULK_EP1_OUT, get_cmd_waitforfinger, 2, &transferred, 0);
    if((r0 == 0) && (transferred == 2)) {
        printf("CMD Wait For Finger sent\n");
    }
    r0 = libusb_bulk_transfer(handle, BULK_EP3_IN, img_buf, 1, &transferred, 0);
    printf("Received 0x%x\n", img_buf[0]);

    /* get image */

    r0 = libusb_bulk_transfer(handle, BULK_EP1_OUT, get_cmd_image, 2, &transferred, 0);
    if((r0 == 0) && (transferred == 2)) {
        printf("CMD Get Image sent\n");
    }
    r0 = libusb_bulk_transfer(handle, BULK_EP2_IN, img_buf, IMAGE_PACKET_SIZE, &transferred, 0);
    printf("Received %d\n", transferred);

    write_to_file(img_buf, IMAGE_PACKET_SIZE);

    system("convert -depth 16 -size 96x96+0 gray:out.fp ./out.png");
    system("rm ./out.fp");

app_exit_2:
    libusb_close(handle);

    /*****************************************************/

app_exit:
    libusb_free_device_list(devs, 1);
    libusb_exit(NULL);

    if (r0 != 0) {
        printf("Error %d\n", r0);
    }

    return r0;
}
_______________________________________________
fprint mailing list
fprint@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/fprint

Reply via email to