From: Antonio Ospite Date: Fri, 6 Jan 2012 17:16:37 +0000 (+0100) Subject: Initial import X-Git-Tag: v0.1.0~44 X-Git-Url: https://git.ao2.it/libam7xxx.git/commitdiff_plain/b11a9f3e0fbaf1d0c9465f7d0e0f97abef4f6de7?ds=inline Initial import --- b11a9f3e0fbaf1d0c9465f7d0e0f97abef4f6de7 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1062ce4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*~ +*.swp +*.o +picoproj diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b8515ad --- /dev/null +++ b/Makefile @@ -0,0 +1,53 @@ +CFLAGS ?= -std=c99 -pedantic -Wall -Wextra -O2 + +# Don't make pedantic checks errors, +# as vanilla libusb-1.0.8 can't live with that +#CFLAGS += -pedantic-errors + +# GCC >= 4.6 +#CFLAGS += -Wunused-but-set-variable + +CFLAGS += -fno-common \ + -Wall \ + -Wextra \ + -Wformat=2 \ + -Winit-self \ + -Winline \ + -Wpacked \ + -Wp,-D_FORTIFY_SOURCE=2 \ + -Wpointer-arith \ + -Wlarger-than-65500 \ + -Wmissing-declarations \ + -Wmissing-format-attribute \ + -Wmissing-noreturn \ + -Wmissing-prototypes \ + -Wnested-externs \ + -Wold-style-definition \ + -Wredundant-decls \ + -Wsign-compare \ + -Wstrict-aliasing=2 \ + -Wstrict-prototypes \ + -Wswitch-enum \ + -Wundef \ + -Wunreachable-code \ + -Wunsafe-loop-optimizations \ + -Wwrite-strings + +CFLAGS += $(shell pkg-config --cflags libusb-1.0) +LDLIBS += $(shell pkg-config --libs libusb-1.0) + +PREFIX ?= /usr/local +bindir := $(PREFIX)/sbin + +all: picoproj + +CFLAGS += -D_BSD_SOURCE +picoproj: picoproj.o + + +install: picoproj + install -d $(DESTDIR)$(bindir) + install -m 755 picoproj $(DESTDIR)$(bindir) + +clean: + rm -rf *~ *.o picoproj diff --git a/picoproj.c b/picoproj.c new file mode 100644 index 0000000..f1c6a3b --- /dev/null +++ b/picoproj.c @@ -0,0 +1,257 @@ +/* picoproj - communication with AM7xxx based USB pico projectors + * + * Copyright (C) 2011 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 3 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 +#include +#include +#include + +/* + * Examples of a packet headers: + * + * Image widget: + * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * +02|00|00|00|00|10|3e|10|01|00|00|00|20|03|00|00|e0|01|00|00|53|E8|00|00+ + * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * Brightness widget: + * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * +04|00|00|00|00|0c|ff|ff|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00|00+ + * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + */ + +#define AM7x01_PACKET_TYPE_INIT 0x01 +#define AM7x01_PACKET_TYPE_IMAGE 0x02 +#define AM7x01_PACKET_TYPE_POWER 0x04 +#define AM7x01_PACKET_TYPE_UNKNOWN 0x05 + +struct buffer { + unsigned int len; + uint8_t *data; +}; + +struct header{ + uint32_t packet_type; + uint32_t unknown1; + uint32_t unknown2; + uint32_t width; + uint32_t height; + uint32_t payload_size; +}; + +struct packet { + struct header header; + uint8_t payload[]; +}; + +static struct buffer *packet_allocate_buffer(struct packet *p) +{ + struct buffer *buffer; + + if (p == NULL) { + perror("packet NULL"); + return NULL; + } + + buffer = malloc(sizeof(*buffer)); + if (buffer == NULL) { + perror("malloc buffer"); + return NULL; + } + + buffer->len = sizeof(p->header); /* + p->header.payload_size; */ + + buffer->data = malloc(buffer->len); + if (buffer->data == NULL) { + perror("malloc buffer->data"); + free(buffer); + return NULL; + } + return buffer; +} + +static void packet_free_buffer(struct buffer *buffer) +{ + free(buffer->data); + free(buffer); + buffer = NULL; +} + +static int packet_pack(struct packet *p, struct buffer *buffer) +{ + unsigned int offset; + uint32_t tmp; + + if (p == NULL || buffer == NULL) + return -EINVAL; + + /* TODO: check for packet payload being NULL? */ + if (buffer->data == NULL || buffer->len < sizeof(*p)) + return -EINVAL; + + offset = 0; + + tmp = htole32(p->header.packet_type); + memcpy(buffer->data + offset, &tmp, sizeof(p->header.packet_type)); + offset += sizeof(p->header.packet_type); + + tmp = htole32(p->header.unknown1); + memcpy(buffer->data + offset, &tmp, sizeof(p->header.unknown1)); + offset += sizeof(p->header.unknown1); + + tmp = htole32(p->header.unknown2); + memcpy(buffer->data + offset, &tmp, sizeof(p->header.unknown2)); + offset += sizeof(p->header.unknown2); + + tmp = htole32(p->header.width); + memcpy(buffer->data + offset, &tmp, sizeof(p->header.width)); + offset += sizeof(p->header.width); + + tmp = htole32(p->header.height); + memcpy(buffer->data + offset, &tmp, sizeof(p->header.height)); + offset += sizeof(p->header.height); + + tmp = htole32(p->header.payload_size); + memcpy(buffer->data + offset, &tmp, sizeof(p->header.payload_size)); + offset += sizeof(p->header.payload_size); + + /* TODO memcpy payload of size */ + + return 0; +} + +static int packet_unpack(struct buffer *buffer, struct packet *p) +{ + unsigned int offset; + uint32_t tmp; + + if (p == NULL || buffer == NULL) + return -EINVAL; + + /* TODO: check for packet payload being NULL? */ + if (buffer->data == NULL || buffer->len < sizeof(*p)) + return -EINVAL; + + offset = 0; + + memcpy(&tmp, buffer->data + offset, sizeof(p->header.packet_type)); + p->header.packet_type = le32toh(tmp); + offset += sizeof(p->header.packet_type); + + memcpy(&tmp, buffer->data + offset, sizeof(p->header.unknown1)); + p->header.unknown1 = le32toh(tmp); + offset += sizeof(p->header.unknown1); + + memcpy(&tmp, buffer->data + offset, sizeof(p->header.unknown2)); + p->header.unknown2 = le32toh(tmp); + offset += sizeof(p->header.unknown2); + + memcpy(&tmp, buffer->data + offset, sizeof(p->header.width)); + p->header.width = le32toh(tmp); + offset += sizeof(p->header.width); + + memcpy(&tmp, buffer->data + offset, sizeof(p->header.height)); + p->header.height = le32toh(tmp); + offset += sizeof(p->header.height); + + memcpy(&tmp, buffer->data + offset, sizeof(p->header.payload_size)); + p->header.payload_size = le32toh(tmp); + offset += sizeof(p->header.payload_size); + + /* malloc & memcpy payload of size p->header.payload_size */ + + return 0; +} + +static void packet_dump_header(struct packet *p) +{ + if (p == NULL) + return; + + printf("packet_type: 0x%08x (%u)\n", p->header.packet_type, p->header.packet_type); + printf("unknown1: 0x%08x (%u)\n", p->header.unknown1, p->header.unknown1); + printf("unknown2: 0x%08x (%u)\n", p->header.unknown2, p->header.unknown2); + printf("width: 0x%08x (%u)\n", p->header.width, p->header.width); + printf("height: 0x%08x (%u)\n", p->header.height, p->header.height); + printf("size: 0x%08x (%u)\n", p->header.payload_size, p->header.payload_size); + fflush(stdout); +} + +static void packet_dump_buffer(struct buffer *buffer) +{ + unsigned int i; + + if (buffer == NULL) + return; + + if (buffer->data == NULL) + return; + + for (i = 0; i < buffer->len; i++) { + printf("%02hhX%c", buffer->data[i], (i < buffer->len - 1) ? ' ' : '\n'); + } + fflush(stdout); +} + +int main(void) +{ + struct packet p1 = { + .header = { + .packet_type = AM7x01_PACKET_TYPE_IMAGE, + .unknown1 = le32toh(0x103e1000), + .unknown2 = le32toh(0x00000001), + .width = 800, + .height = 480, + .payload_size = 59475, + }, + /* TODO initialize payload */ + }; + struct buffer *buffer = NULL; + struct packet p2; + int ret; + + packet_dump_header(&p1); + + buffer = packet_allocate_buffer(&p1); + if (buffer == NULL) { + fprintf(stderr, "Cannot allocate the buffer.\n"); + exit(EXIT_FAILURE); + } + + ret = packet_pack(&p1, buffer); + if (ret < 0) { + fprintf(stderr, "Cannot pack the packet.\n"); + exit(EXIT_FAILURE); + } + + packet_dump_buffer(buffer); + + ret = packet_unpack(buffer, &p2); + if (ret < 0) { + fprintf(stderr, "Cannot unpack the packet.\n"); + exit(EXIT_FAILURE); + } + + packet_dump_header(&p2); + + packet_free_buffer(buffer); + + exit(EXIT_SUCCESS); +}