From: Antonio Ospite Date: Wed, 7 May 2014 19:40:44 +0000 (+0200) Subject: Merge branch 'zoom-tele-picopix' X-Git-Tag: v0.1.5~10 X-Git-Url: https://git.ao2.it/libam7xxx.git/commitdiff_plain/8fb663458b08cc5cb79ec824348919ee239b4da3?hp=2d1f8c13ccce07e38c0dd08e28323f2dcbd14bc8 Merge branch 'zoom-tele-picopix' --- diff --git a/doc/man/am7xxx-play.1.txt b/doc/man/am7xxx-play.1.txt index 4dcf296..a5c41c9 100644 --- a/doc/man/am7xxx-play.1.txt +++ b/doc/man/am7xxx-play.1.txt @@ -63,7 +63,7 @@ EXAMPLE: the slave connector to be plugged in. *-z* '':: - the display zoom mode, between 0 (original) and 3 (test) + the display zoom mode, between 0 (original) and 4 (tele) *-h*:: show the help message diff --git a/doc/man/picoproj.1.txt b/doc/man/picoproj.1.txt index 1b0e471..69ec437 100644 --- a/doc/man/picoproj.1.txt +++ b/doc/man/picoproj.1.txt @@ -46,7 +46,7 @@ OPTIONS the slave connector to be plugged in. *-z* '':: - the display zoom mode, between 0 (original) and 3 (test) + the display zoom mode, between 0 (original) and 4 (tele) *-W* '':: the width of the image to upload diff --git a/examples/am7xxx-play.c b/examples/am7xxx-play.c index 1b28406..9251701 100644 --- a/examples/am7xxx-play.c +++ b/examples/am7xxx-play.c @@ -610,8 +610,8 @@ static void usage(char *name) AM7XXX_POWER_OFF, AM7XXX_POWER_TURBO); printf("\t\t\t\tWARNING: Level 2 and greater require the master AND\n"); printf("\t\t\t\t the slave connector to be plugged in.\n"); - printf("\t-z \t\tthe display zoom mode, between %d (original) and %d (test)\n", - AM7XXX_ZOOM_ORIGINAL, AM7XXX_ZOOM_TEST); + printf("\t-z \t\tthe display zoom mode, between %d (original) and %d (tele)\n", + AM7XXX_ZOOM_ORIGINAL, AM7XXX_ZOOM_TELE); printf("\t-h \t\t\tthis help message\n"); printf("\n\nEXAMPLES OF USE:\n"); printf("\t%s -f x11grab -i :0.0 -o video_size=800x480\n", name); @@ -757,11 +757,12 @@ int main(int argc, char *argv[]) case AM7XXX_ZOOM_H: case AM7XXX_ZOOM_H_V: case AM7XXX_ZOOM_TEST: + case AM7XXX_ZOOM_TELE: fprintf(stdout, "Zoom: %d\n", zoom); break; default: fprintf(stderr, "Invalid zoom mode value, must be between %d and %d\n", - AM7XXX_ZOOM_ORIGINAL, AM7XXX_ZOOM_TEST); + AM7XXX_ZOOM_ORIGINAL, AM7XXX_ZOOM_TELE); ret = -EINVAL; goto out; } diff --git a/examples/picoproj.c b/examples/picoproj.c index 9128538..cb30de0 100644 --- a/examples/picoproj.c +++ b/examples/picoproj.c @@ -47,8 +47,8 @@ static void usage(char *name) AM7XXX_POWER_OFF, AM7XXX_POWER_TURBO); printf("\t\t\t\tWARNING: Level 2 and greater require the master AND\n"); printf("\t\t\t\t the slave connector to be plugged in.\n"); - printf("\t-z \t\tthe display zoom mode, between %d (original) and %d (test)\n", - AM7XXX_ZOOM_ORIGINAL, AM7XXX_ZOOM_TEST); + printf("\t-z \t\tthe display zoom mode, between %d (original) and %d (tele)\n", + AM7XXX_ZOOM_ORIGINAL, AM7XXX_ZOOM_TELE); printf("\t-W \tthe width of the image to upload\n"); printf("\t-H \tthe height of the image to upload\n"); printf("\t-h \t\t\tthis help message\n"); @@ -138,11 +138,12 @@ int main(int argc, char *argv[]) case AM7XXX_ZOOM_H: case AM7XXX_ZOOM_H_V: case AM7XXX_ZOOM_TEST: + case AM7XXX_ZOOM_TELE: fprintf(stdout, "Zoom: %d\n", zoom); break; default: fprintf(stderr, "Invalid zoom mode value, must be between %d and %d\n", - AM7XXX_ZOOM_ORIGINAL, AM7XXX_ZOOM_TEST); + AM7XXX_ZOOM_ORIGINAL, AM7XXX_ZOOM_TELE); ret = -EINVAL; goto out; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0817374..f743b1a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,10 +1,11 @@ add_definitions("-D_BSD_SOURCE") # for htole32() +add_definitions("-D_POSIX_C_SOURCE=199309L") # for nanosleep() # Find packages needed to build library find_package(libusb-1.0 REQUIRED) include_directories(${LIBUSB_1_INCLUDE_DIRS}) -set(SRC am7xxx.c serialize.c) +set(SRC am7xxx.c serialize.c tools.c) # Build the library add_library(am7xxx SHARED ${SRC}) diff --git a/src/am7xxx.c b/src/am7xxx.c index 4ac2461..ffdd59c 100644 --- a/src/am7xxx.c +++ b/src/am7xxx.c @@ -26,6 +26,7 @@ #include "am7xxx.h" #include "serialize.h" +#include "tools.h" #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -81,6 +82,7 @@ struct am7xxx_usb_device_descriptor { static int default_set_power_mode(am7xxx_device *dev, am7xxx_power_mode power); static int picopix_set_power_mode(am7xxx_device *dev, am7xxx_power_mode power); static int default_set_zoom_mode(am7xxx_device *dev, am7xxx_zoom_mode zoom); +static int picopix_set_zoom_mode(am7xxx_device *dev, am7xxx_zoom_mode zoom); #define DEFAULT_OPS { \ .set_power_mode = default_set_power_mode, \ @@ -128,6 +130,7 @@ static const struct am7xxx_usb_device_descriptor supported_devices[] = { .interface_number = 0, .ops = { .set_power_mode = picopix_set_power_mode, + .set_zoom_mode = picopix_set_zoom_mode, }, }, { @@ -170,6 +173,8 @@ typedef enum { AM7XXX_PACKET_TYPE_PICOPIX_POWER_LOW = 0x15, AM7XXX_PACKET_TYPE_PICOPIX_POWER_MEDIUM = 0x16, AM7XXX_PACKET_TYPE_PICOPIX_POWER_HIGH = 0x17, + AM7XXX_PACKET_TYPE_PICOPIX_ENABLE_TI = 0x18, + AM7XXX_PACKET_TYPE_PICOPIX_DISABLE_TI = 0x19, } am7xxx_packet_type; struct am7xxx_generic_header { @@ -949,6 +954,7 @@ static int default_set_zoom_mode(am7xxx_device *dev, am7xxx_zoom_mode zoom) h.header_data.zoom.bit0 = 1; break; + case AM7XXX_ZOOM_TELE: default: error(dev->ctx, "Unsupported zoom mode.\n"); return -EINVAL; @@ -961,6 +967,41 @@ static int default_set_zoom_mode(am7xxx_device *dev, am7xxx_zoom_mode zoom) return 0; } +static int picopix_set_zoom_mode(am7xxx_device *dev, am7xxx_zoom_mode zoom) +{ + int ret; + am7xxx_packet_type packet_type; + + switch(zoom) { + case AM7XXX_ZOOM_ORIGINAL: + packet_type = AM7XXX_PACKET_TYPE_PICOPIX_DISABLE_TI; + break; + + case AM7XXX_ZOOM_TELE: + packet_type = AM7XXX_PACKET_TYPE_PICOPIX_ENABLE_TI; + break; + + case AM7XXX_ZOOM_H: + case AM7XXX_ZOOM_H_V: + case AM7XXX_ZOOM_TEST: + default: + error(dev->ctx, "Unsupported zoom mode.\n"); + return -EINVAL; + }; + + ret = send_command(dev, packet_type); + if (ret < 0) + return ret; + + /* The Windows drivers wait for 100ms and send the same command again, + * probably to overcome a firmware deficiency */ + ret = msleep(100); + if (ret < 0) + return ret; + + return send_command(dev, packet_type); +} + /* Public API */ AM7XXX_PUBLIC int am7xxx_init(am7xxx_context **ctx) diff --git a/src/am7xxx.h b/src/am7xxx.h index ec9869d..77c2030 100644 --- a/src/am7xxx.h +++ b/src/am7xxx.h @@ -114,12 +114,17 @@ typedef enum { * * @note On the zoom test screen the version of the firmware running on the * device is shown as well (e.g SPI_V21.0.0_2011.03.18). + * + * @note The Tele mode is available only on some PicoPix models, when using it + * the image is distorted like if a different lens was used, but the global + * aspect ratio of the image does not change. */ typedef enum { AM7XXX_ZOOM_ORIGINAL = 0, /**< Original Size, as retrieved via #am7xxx_device_info. */ AM7XXX_ZOOM_H = 1, /**< Zoom 1: H Scale (changes aspect ratio). */ AM7XXX_ZOOM_H_V = 2, /**< Zoom 2: H/V Scale (changes aspect ratio). */ AM7XXX_ZOOM_TEST = 3, /**< Zoom test screen, the firmware version is shown as well. */ + AM7XXX_ZOOM_TELE = 4, /**< Zoom Tele: available on some PicoPix models. */ } am7xxx_zoom_mode; /** diff --git a/src/tools.c b/src/tools.c new file mode 100644 index 0000000..be63ac6 --- /dev/null +++ b/src/tools.c @@ -0,0 +1,48 @@ +/* am7xxx - communication with AM7xxx based USB Pico Projectors and DPFs + * + * Copyright (C) 2014 Antonio Ospite + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "tools.h" + +/** + * Sleep for a period expressed in milliseconds + * + * @param[in] msecs Time to sleep in milliseconds + * + * @return 0 on success, -1 on error + */ +int msleep(unsigned long msecs) +{ + struct timespec delay; + int ret; + + delay.tv_sec = msecs / 1000; + delay.tv_nsec = (msecs % 1000) * 1000000; + while (1) { + ret = nanosleep(&delay, &delay); + if (ret == -1 && errno == EINTR) + continue; + break; + } + if (ret == -1) + return ret; + + return 0; +} diff --git a/src/tools.h b/src/tools.h new file mode 100644 index 0000000..d3140c8 --- /dev/null +++ b/src/tools.h @@ -0,0 +1,24 @@ +/* am7xxx - communication with AM7xxx based USB Pico Projectors and DPFs + * + * Copyright (C) 2014 Antonio Ospite + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TOOLS_H +#define __TOOLS_H + +int msleep(unsigned long msecs); + +#endif /* __TOOLS_H */