1 /* picoproj - communication with AM7xxx based USB pico projectors
3 * Copyright (C) 2011 Antonio Ospite <ospite@studenti.unina.it>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include <sys/types.h>
33 #define AM7x01_VENDOR_ID 0x1de1
34 #define AM7x01_PRODUCT_ID 0xc101
36 static libusb_device_handle *dev;
39 AM7x01_PACKET_TYPE_INIT = 0x01,
40 AM7x01_PACKET_TYPE_IMAGE = 0x02,
41 AM7x01_PACKET_TYPE_POWER = 0x04,
42 AM7x01_PACKET_TYPE_UNKNOWN = 0x05,
46 AM7x01_IMAGE_FORMAT_JPEG = 1,
47 } am7x01_image_format;
53 AM7x01_POWER_HIGH = 3,
70 * Examples of packet headers:
73 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
74 * +02|00|00|00|00|10|3e|10|01|00|00|00|20|03|00|00|e0|01|00|00|53|E8|00|00+
75 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
78 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
79 * +04|00|00|00|00|0c|ff|ff|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00+
80 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
83 static uint8_t reference_image_header[] = {
84 0x02, 0x00, 0x00, 0x00,
89 0x01, 0x00, 0x00, 0x00,
90 0x20, 0x03, 0x00, 0x00,
91 0xe0, 0x01, 0x00, 0x00,
92 0x53, 0xE8, 0x00, 0x00
102 struct image_header image;
103 struct power_header power;
108 static void dump_image_header(struct image_header *i)
113 printf("Image header:\n");
114 printf("format: 0x%08x (%u)\n", i->format, i->format);
115 printf("width: 0x%08x (%u)\n", i->width, i->width);
116 printf("height: 0x%08x (%u)\n", i->height, i->height);
117 printf("image size: 0x%08x (%u)\n", i->image_size, i->image_size);
120 static void dump_header(struct header *h)
125 printf("packet_type: 0x%08x (%u)\n", h->packet_type, h->packet_type);
126 printf("unknown0: 0x%02hhx (%hhu)\n", h->unknown0, h->unknown0);
127 printf("header_len: 0x%02hhx (%hhu)\n", h->header_len, h->header_len);
128 printf("unknown2: 0x%02hhx (%hhu)\n", h->unknown2, h->unknown2);
129 printf("unknown3: 0x%02hhx (%hhu)\n", h->unknown3, h->unknown3);
131 switch(h->packet_type) {
132 case AM7x01_PACKET_TYPE_IMAGE:
133 dump_image_header(&(h->header_data.image));
137 printf("Packet type not supported!\n");
144 static inline unsigned int in_80chars(unsigned int i)
146 return ((i+1) % (80/3));
149 static void dump_buffer(uint8_t *buffer, unsigned int len)
153 if (buffer == NULL || len == 0)
156 for (i = 0; i < len; i++) {
157 printf("%02hhX%c", buffer[i], (in_80chars(i) && (i < len - 1)) ? ' ' : '\n');
162 static int send_data(uint8_t *buffer, unsigned int len)
167 dump_buffer(buffer, len);
169 ret = libusb_bulk_transfer(dev, 1, buffer, len, &transferred, 0);
170 if (ret != 0 || (unsigned int)transferred != len) {
171 fprintf(stderr, "Error: ret: %d\ttransferred: %d (expected %u)\n",
172 ret, transferred, len);
179 static int send_header(struct header *h)
182 struct header header;
183 uint8_t buffer[sizeof (struct header)];
188 return send_data(data.buffer, sizeof (struct header));
191 static int send_image(am7x01_image_format format,
199 .packet_type = htole32(AM7x01_PACKET_TYPE_IMAGE),
201 .header_len = sizeof(struct image_header),
206 .format = htole32(format),
207 .width = htole32(width),
208 .height = htole32(height),
209 .image_size = htole32(size),
217 printf("Dump Buffers\n");
218 dump_buffer(reference_image_header, sizeof(struct header));
220 ret = send_header(&h);
224 if (image == NULL || size == 0)
227 return send_data(image, size);
230 static void usage(char *name)
232 printf("usage: %s [OPTIONS]\n\n", name);
233 printf("OPTIONS:\n");
234 printf("\t-f <filename>\t\tthe image file to upload\n");
235 printf("\t-F <format>\t\tthe image format to use (default is JPEG).\n");
236 printf("\t\t\t\tSUPPORTED FORMATS:\n");
237 printf("\t\t\t\t\t1 - JPEG\n");
238 printf("\t-W <image width>\tthe width of the image to upload\n");
239 printf("\t-H <image height>\tthe height of the image to upload\n");
240 printf("\t-h \t\t\tthis help message\n");
243 int main(int argc, char *argv[])
246 int exit_code = EXIT_SUCCESS;
249 char filename[FILENAME_MAX] = {0};
251 int format = AM7x01_IMAGE_FORMAT_JPEG;
254 uint8_t *image = NULL;
255 unsigned int size = 59475;
257 while ((opt = getopt(argc, argv, "f:F:W:H:h")) != -1) {
260 strncpy(filename, optarg, FILENAME_MAX);
263 format = atoi(optarg);
265 fprintf(stderr, "Unsupported format\n");
270 width = atoi(optarg);
272 fprintf(stderr, "Unsupported width\n");
277 height = atoi(optarg);
279 fprintf(stderr, "Unsupported height\n");
289 if (filename[0] != '\0') {
292 image_fd = open(filename, O_RDONLY);
295 exit_code = EXIT_FAILURE;
298 if (fstat(image_fd, &st) < 0) {
300 exit_code = EXIT_FAILURE;
301 goto out_close_image_fd;
305 image = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, image_fd, 0);
308 exit_code = EXIT_FAILURE;
309 goto out_close_image_fd;
314 libusb_set_debug(NULL, 3);
316 dev = libusb_open_device_with_vid_pid(NULL,
321 perror("libusb_open_device_with_vid_pid");
322 exit_code = EXIT_FAILURE;
323 goto out_libusb_exit;
326 libusb_set_configuration(dev, 1);
327 libusb_claim_interface(dev, 0);
329 ret = send_image(format, width, height, image, size);
331 perror("send_image");
332 exit_code = EXIT_FAILURE;
336 exit_code = EXIT_SUCCESS;
345 ret = munmap(image, size);
352 ret = close(image_fd);