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