Implement am7xxx_set_power_mode()
authorAntonio Ospite <ospite@studenti.unina.it>
Tue, 24 Jan 2012 15:43:23 +0000 (16:43 +0100)
committerAntonio Ospite <ospite@studenti.unina.it>
Wed, 25 Jan 2012 14:57:30 +0000 (15:57 +0100)
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
src/am7xxx.h
src/picoproj.c

index 483eaf7..7bd4a2c 100644 (file)
@@ -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;
+}
index 49510eb..6847796 100644 (file)
@@ -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
index 6e95fdb..7485f71 100644 (file)
@@ -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");