From ad32c9df36e8ec1c5b336bdad10ae771298b4d39 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Tue, 24 Jan 2012 16:43:23 +0100 Subject: [PATCH 1/1] Implement am7xxx_set_power_mode() The AM7XXX_PACKET_TYPE_POWER expects the power mode to be specified in the header_data section of the header like a value between 0 and 4, but with one bit per field, each field being a little-endian 32 bit integer. --- src/am7xxx.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/am7xxx.h | 23 ++++++++++++++------ src/picoproj.c | 7 ++++++ 3 files changed, 91 insertions(+), 7 deletions(-) diff --git a/src/am7xxx.c b/src/am7xxx.c index 483eaf7..7bd4a2c 100644 --- a/src/am7xxx.c +++ b/src/am7xxx.c @@ -38,6 +38,17 @@ static void dump_image_header(struct am7xxx_image_header *i) printf("\timage size: 0x%08x (%u)\n", i->image_size, i->image_size); } +static void dump_power_header(struct am7xxx_power_header *p) +{ + if (p == NULL) + return; + + printf("Power header:\n"); + printf("\tbit2: 0x%08x (%u)\n", p->bit2, p->bit2); + printf("\tbit1: 0x%08x (%u)\n", p->bit1, p->bit1); + printf("\tbit0: 0x%08x (%u)\n", p->bit0, p->bit0); +} + static void dump_header(struct am7xxx_header *h) { if (h == NULL) @@ -54,6 +65,10 @@ static void dump_header(struct am7xxx_header *h) dump_image_header(&(h->header_data.image)); break; + case AM7XXX_PACKET_TYPE_POWER: + dump_power_header(&(h->header_data.power)); + break; + default: printf("Packet type not supported!\n"); break; @@ -209,3 +224,56 @@ int am7xxx_send_image(am7xxx_device dev, return send_data(dev, image, size); } + +int am7xxx_set_power_mode(am7xxx_device dev, am7xxx_power_mode mode) +{ + int ret; + struct am7xxx_header h = { + .packet_type = AM7XXX_PACKET_TYPE_POWER, + .unknown0 = 0x00, + .header_data_len = sizeof(struct am7xxx_power_header), + .unknown2 = 0x3e, + .unknown3 = 0x10, + }; + + switch(mode) { + case AM7XXX_POWER_OFF: + h.header_data.power.bit2 = 0; + h.header_data.power.bit1 = 0; + h.header_data.power.bit0 = 0; + break; + + case AM7XXX_POWER_LOW: + h.header_data.power.bit2 = 0; + h.header_data.power.bit1 = 0; + h.header_data.power.bit0 = 1; + + case AM7XXX_POWER_MIDDLE: + h.header_data.power.bit2 = 0; + h.header_data.power.bit1 = 1; + h.header_data.power.bit0 = 0; + break; + + case AM7XXX_POWER_HIGH: + h.header_data.power.bit2 = 0; + h.header_data.power.bit1 = 1; + h.header_data.power.bit0 = 1; + break; + + case AM7XXX_POWER_TURBO: + h.header_data.power.bit2 = 1; + h.header_data.power.bit1 = 0; + h.header_data.power.bit0 = 0; + break; + + default: + fprintf(stderr, "Unsupported power mode.\n"); + return -EINVAL; + }; + + ret = send_header(dev, &h); + if (ret < 0) + return ret; + + return 0; +} diff --git a/src/am7xxx.h b/src/am7xxx.h index 49510eb..6847796 100644 --- a/src/am7xxx.h +++ b/src/am7xxx.h @@ -41,10 +41,11 @@ typedef enum { } am7xxx_image_format; typedef enum { - AM7XXX_POWER_OFF = 0, - AM7XXX_POWER_LOW = 1, - AM7XXX_POWER_MID = 2, - AM7XXX_POWER_HIGH = 3, + AM7XXX_POWER_OFF = 0, + AM7XXX_POWER_LOW = 1, + AM7XXX_POWER_MIDDLE = 2, + AM7XXX_POWER_HIGH = 3, + AM7XXX_POWER_TURBO = 4, } am7xxx_power_mode; struct am7xxx_generic_header { @@ -62,9 +63,9 @@ struct am7xxx_image_header { }; struct am7xxx_power_header { - uint32_t power_low; - uint32_t power_mid; - uint32_t power_high; + uint32_t bit2; + uint32_t bit1; + uint32_t bit0; }; /* @@ -107,6 +108,14 @@ int am7xxx_send_image(am7xxx_device dev, uint8_t *image, unsigned int size); +/* + * NOTE: if we set the mode to AM7XXX_POWER_OFF we can't turn the + * display on again by using only am7xxx_set_power_mode(). + * + * Remember to mention that when writing the API doc. + */ +int am7xxx_set_power_mode(am7xxx_device dev, am7xxx_power_mode mode); + #ifdef __cplusplus } #endif diff --git a/src/picoproj.c b/src/picoproj.c index 6e95fdb..7485f71 100644 --- a/src/picoproj.c +++ b/src/picoproj.c @@ -130,6 +130,13 @@ int main(int argc, char *argv[]) goto out_munmap; } + ret = am7xxx_set_power_mode(dev, AM7XXX_POWER_LOW); + if (ret < 0) { + perror("am7xxx_set_power_mode"); + exit_code = EXIT_FAILURE; + goto cleanup; + } + ret = am7xxx_send_image(dev, format, width, height, image, size); if (ret < 0) { perror("am7xxx_send_image"); -- 2.1.4