summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2008-04-02 22:16:14 +0000
committerJens Arnold <amiconn@rockbox.org>2008-04-02 22:16:14 +0000
commit5c87a98b97b9ab6bd9647bb0bb8d00f58d5f179b (patch)
treeb61feaa66d26f63df09f03d0cb6921ac80edf560
parentcdae493f96150808007883a7fb0b582d46af4a1a (diff)
Greyscale library: * Implement linearisation curve flipping for 1st/2nd Gen iPods (LCD is inverted when backlight is on, so the curve is also inverted). This needs a slight extension of is_backlight_on() functionality in the core. * Thorough recalibration of all reachable greyscale targets, and #ifdef cleanup. * Reduce on-target gamma a bit, because the displayable contrast range of a monochrome/greyscale isn't that high.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16936 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugin.c1
-rw-r--r--apps/plugin.h5
-rw-r--r--apps/plugins/lib/grey.h11
-rw-r--r--apps/plugins/lib/grey_core.c480
-rw-r--r--apps/screen_access.h2
-rw-r--r--firmware/backlight.c24
-rw-r--r--firmware/drivers/button.c9
-rw-r--r--firmware/export/backlight.h4
-rw-r--r--uisimulator/sdl/button.c6
9 files changed, 313 insertions, 229 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index b7037139b5..7c3fab1079 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -576,6 +576,7 @@ static const struct plugin_api rockbox_api = {
/* new stuff at the end, sort into place next time
the API gets incompatible */
+ is_backlight_on,
};
int plugin_load(const char* plugin, void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index 1753272952..cfbd3e72af 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -120,7 +120,7 @@
#define PLUGIN_MAGIC 0x526F634B /* RocK */
/* increase this every time the api struct changes */
-#define PLUGIN_API_VERSION 105
+#define PLUGIN_API_VERSION 106
/* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any
@@ -721,7 +721,8 @@ struct plugin_api {
/* new stuff at the end, sort into place next time
the API gets incompatible */
-
+
+ bool (*is_backlight_on)(bool ignore_always_off);
};
/* plugin header */
diff --git a/apps/plugins/lib/grey.h b/apps/plugins/lib/grey.h
index 4298ae3ada..3d5e6d16c4 100644
--- a/apps/plugins/lib/grey.h
+++ b/apps/plugins/lib/grey.h
@@ -120,9 +120,16 @@ void grey_ub_scroll_down(int count);
/*** Internal stuff ***/
+/* standard gamma (s23p8) */
+#ifdef SIMULATOR /* Standard PC gamma */
+#define _GREY_GAMMA ((200<<8)/100)
+#else /* Target LCDs have a smaller contrast range */
+#define _GREY_GAMMA ((180<<8)/100)
+#endif
+
/* flag definitions */
-#define _GREY_RUNNING 0x0001 /* greyscale overlay is running */
-#define _GREY_DEFERRED_UPDATE 0x0002 /* lcd_update() requested */
+#define _GREY_RUNNING 0x8000 /* greyscale overlay is running */
+#define _GREY_DEFERRED_UPDATE 0x4000 /* lcd_update() requested */
/* fast unsigned multiplication (16x16bit->32bit or 32x32bit->32bit,
* whichever is faster for the architecture) */
diff --git a/apps/plugins/lib/grey_core.c b/apps/plugins/lib/grey_core.c
index 8a30faa5f8..6b196e1aaf 100644
--- a/apps/plugins/lib/grey_core.c
+++ b/apps/plugins/lib/grey_core.c
@@ -33,189 +33,200 @@
#ifndef SIMULATOR
-#if CONFIG_LCD == LCD_SSD1815 || CONFIG_LCD == LCD_IFP7XX \
- || CONFIG_LCD == LCD_MROBE100
-/* measured and interpolated curve */
-/* TODO: check for iFP & m:robe 100 */
+#if defined ARCHOS_RECORDER /* verified */ \
+ || defined ARCHOS_FMRECORDER /* should be identical */ \
+ || defined ARCHOS_RECORDERV2 /* should be identical */ \
+ || defined ARCHOS_ONDIOFM /* verified */ \
+ || defined ARCHOS_ONDIOSP /* verified */
+/* Average measurements of a Recorder v1, an Ondio FM, a backlight-modded
+ * Ondio FM, and an Ondio SP. */
static const unsigned char lcdlinear[256] = {
- 0, 3, 5, 8, 11, 13, 16, 18,
- 21, 23, 26, 28, 31, 33, 36, 38,
- 40, 42, 45, 47, 49, 51, 53, 55,
- 57, 59, 60, 62, 64, 66, 67, 69,
- 70, 72, 73, 74, 76, 77, 78, 79,
- 81, 82, 83, 84, 85, 86, 87, 88,
- 88, 89, 90, 91, 92, 92, 93, 94,
- 95, 95, 96, 97, 97, 98, 99, 99,
- 100, 101, 102, 102, 103, 104, 104, 105,
- 106, 106, 107, 107, 108, 109, 109, 110,
- 111, 111, 112, 113, 113, 114, 114, 115,
- 116, 116, 117, 117, 118, 119, 119, 120,
- 120, 121, 121, 122, 122, 123, 123, 124,
- 124, 125, 125, 126, 126, 127, 127, 128,
- 128, 128, 129, 129, 130, 130, 131, 131,
- 132, 132, 133, 133, 133, 134, 134, 135,
- 135, 136, 136, 137, 137, 138, 138, 138,
- 139, 139, 140, 140, 141, 141, 142, 142,
- 143, 143, 144, 144, 145, 145, 146, 146,
- 147, 147, 148, 148, 148, 149, 149, 150,
- 150, 151, 151, 152, 152, 153, 153, 153,
- 154, 154, 155, 155, 156, 156, 157, 157,
- 158, 158, 158, 159, 159, 160, 160, 161,
- 161, 162, 162, 163, 163, 164, 164, 165,
- 165, 166, 167, 167, 168, 168, 169, 169,
- 170, 171, 171, 172, 173, 173, 174, 175,
- 176, 176, 177, 178, 179, 180, 181, 181,
- 182, 183, 184, 185, 186, 188, 189, 190,
- 191, 192, 194, 195, 196, 198, 199, 201,
- 202, 204, 205, 207, 209, 211, 213, 215,
- 217, 219, 222, 224, 226, 229, 231, 234,
- 236, 239, 242, 244, 247, 250, 252, 255
+ 5, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 29, 31, 33, 35,
+ 37, 39, 40, 42, 43, 45, 46, 48, 49, 50, 51, 53, 54, 55, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 71, 72,
+ 73, 74, 74, 75, 76, 77, 77, 78, 79, 79, 80, 80, 81, 81, 82, 82,
+ 83, 84, 84, 85, 86, 86, 87, 87, 88, 88, 89, 89, 90, 90, 91, 91,
+ 92, 92, 93, 93, 94, 94, 95, 95, 96, 96, 97, 98, 98, 99, 100, 100,
+101, 101, 102, 103, 103, 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109,
+110, 110, 111, 112, 112, 113, 114, 114, 115, 115, 116, 117, 117, 118, 119, 119,
+120, 120, 121, 122, 123, 123, 124, 125, 126, 126, 127, 128, 129, 129, 130, 131,
+132, 132, 133, 134, 135, 135, 136, 137, 138, 138, 139, 140, 140, 141, 141, 142,
+143, 144, 145, 146, 147, 147, 148, 149, 150, 151, 152, 153, 154, 154, 155, 156,
+157, 158, 159, 160, 161, 161, 162, 163, 164, 165, 166, 167, 168, 168, 169, 170,
+171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 184, 185, 186, 187,
+188, 189, 191, 192, 194, 195, 197, 198, 199, 200, 202, 203, 204, 205, 207, 208,
+209, 210, 212, 213, 215, 216, 218, 219, 220, 221, 222, 223, 225, 226, 227, 228,
+229, 230, 232, 233, 234, 235, 237, 238, 239, 240, 242, 243, 244, 246, 247, 248
};
-#elif CONFIG_LCD == LCD_S1D15E06
-/* measured and interpolated curve */
+/* The actual LCD scanrate varies a lot with temperature on these targets */
+#define LCD_SCANRATE 67 /* Hz */
+
+#elif defined IAUDIO_M3 /* verified */
+/* Average measurements of 2 iAudio remotes connected to an M3. */
+static const unsigned char lcdlinear[256] = {
+ 5, 9, 13, 17, 21, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62, 66,
+ 70, 73, 76, 78, 80, 82, 84, 86, 88, 90, 91, 92, 94, 95, 96, 97,
+ 98, 99, 99, 100, 101, 102, 102, 103, 104, 104, 105, 105, 106, 107, 107, 108,
+109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116,
+117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 121, 122, 122, 123, 123, 123,
+124, 124, 124, 125, 125, 126, 126, 126, 127, 127, 127, 128, 128, 129, 129, 129,
+130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 134, 135, 135, 136, 136, 136,
+137, 137, 137, 138, 138, 139, 139, 139, 140, 140, 141, 141, 142, 142, 143, 143,
+144, 144, 145, 145, 146, 147, 147, 148, 149, 149, 150, 150, 151, 151, 152, 152,
+153, 153, 154, 154, 155, 155, 156, 156, 157, 157, 158, 158, 159, 160, 160, 161,
+162, 162, 163, 164, 164, 165, 166, 167, 168, 168, 169, 169, 170, 171, 171, 172,
+173, 173, 174, 175, 176, 176, 177, 178, 179, 179, 180, 181, 182, 182, 183, 184,
+185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 198, 199, 200, 201,
+202, 203, 204, 205, 207, 208, 209, 210, 211, 212, 213, 214, 216, 217, 218, 219,
+220, 221, 222, 223, 225, 226, 227, 228, 229, 230, 231, 232, 234, 235, 236, 237,
+238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 249, 250, 251, 252
+};
+/* The actual LCD scanrate is twice as high, but we cannot transfer fast enough
+ * for 150Hz. Even at 75Hz, greyscale display is very smooth. Average from
+ * 2 iAudio remotes. */
+#define LCD_SCANRATE 75 /* Hz */
+
+#elif defined IAUDIO_M5 /* verified */
+/* Measurement of one iAudio M5L */
+static const unsigned char lcdlinear[256] = {
+ 4, 6, 8, 10, 11, 13, 15, 17, 19, 21, 22, 24, 25, 27, 28, 30,
+ 32, 33, 35, 36, 37, 39, 40, 42, 43, 44, 45, 46, 48, 49, 50, 51,
+ 52, 52, 53, 54, 55, 55, 56, 57, 58, 58, 59, 60, 61, 61, 62, 63,
+ 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 70, 70, 71, 72, 72,
+ 73, 73, 74, 75, 75, 76, 77, 77, 78, 78, 79, 79, 80, 80, 81, 81,
+ 82, 82, 83, 84, 84, 85, 86, 86, 87, 87, 88, 89, 89, 90, 91, 91,
+ 92, 92, 93, 93, 94, 94, 95, 95, 96, 96, 97, 98, 98, 99, 100, 100,
+101, 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108,
+109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116,
+117, 117, 118, 119, 119, 120, 121, 121, 122, 122, 123, 124, 124, 125, 126, 126,
+127, 127, 128, 129, 130, 130, 131, 132, 133, 133, 134, 135, 135, 136, 137, 137,
+138, 139, 140, 141, 142, 142, 143, 144, 145, 146, 147, 148, 149, 149, 150, 151,
+152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 163, 164, 165, 167, 168, 169,
+170, 172, 173, 175, 177, 179, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198,
+200, 202, 204, 205, 207, 209, 210, 212, 214, 216, 218, 219, 221, 223, 224, 226,
+228, 230, 231, 233, 235, 236, 237, 239, 241, 243, 244, 246, 248, 249, 250, 252
+};
+#define LCD_SCANRATE 73 /* Hz */
+
+#elif defined IPOD_1G2G /* verified */
+/* Average measurements of an iPod 1st Gen (0x00010001) and an iPod 2nd Gen
+ * (0x00020000), measured with both backlight off & backlight on (flipped
+ * curves) and medium load (white background when measuring with backlight on),
+ * as the curve is load dependent (the controller's step-up converter doesn't
+ * provide enough juice). Table is for backlight_off state. */
+static const unsigned char lcdlinear[256] = {
+ 4, 6, 8, 9, 11, 13, 14, 16, 17, 18, 20, 21, 23, 24, 26, 27,
+ 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 41, 42, 43, 44,
+ 45, 45, 46, 47, 47, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53,
+ 54, 54, 54, 55, 55, 56, 56, 56, 57, 57, 57, 58, 58, 59, 59, 59,
+ 60, 60, 60, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 65, 65, 65,
+ 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 73, 73,
+ 74, 74, 74, 75, 75, 76, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80,
+ 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, 88, 88,
+ 89, 89, 90, 91, 92, 92, 93, 94, 95, 95, 96, 97, 97, 98, 99, 99,
+100, 100, 101, 102, 102, 103, 104, 104, 105, 105, 106, 107, 107, 108, 109, 109,
+110, 110, 111, 112, 113, 113, 114, 115, 116, 116, 117, 118, 119, 119, 120, 121,
+122, 122, 123, 124, 125, 125, 126, 127, 128, 129, 130, 131, 131, 132, 133, 134,
+135, 137, 138, 139, 141, 142, 144, 145, 146, 147, 149, 150, 151, 152, 154, 155,
+156, 158, 159, 161, 162, 164, 165, 167, 169, 171, 172, 174, 175, 177, 178, 180,
+182, 184, 186, 188, 189, 191, 193, 195, 197, 199, 201, 203, 206, 208, 210, 212,
+214, 217, 219, 221, 224, 226, 229, 231, 233, 236, 238, 240, 243, 245, 247, 250
+};
+/* Average from an iPod 1st Gen and an iPod 2nd Gen */
+#define LCD_SCANRATE 96 /* Hz */
+
+#elif defined IPOD_MINI2G /* verified */ \
+ || defined IPOD_MINI /* should be identical */ \
+ || defined IPOD_3G /* TODO: verify */ \
+ || defined IPOD_4G /* TODO: verify */
+/* Measurement of one iPod Mini G2 */
static const unsigned char lcdlinear[256] = {
- 0, 5, 11, 16, 21, 27, 32, 37,
- 42, 47, 51, 56, 60, 64, 68, 72,
- 75, 78, 81, 84, 87, 89, 91, 93,
- 95, 96, 98, 99, 101, 102, 103, 104,
- 105, 106, 107, 108, 109, 110, 111, 111,
- 112, 113, 113, 114, 115, 115, 116, 117,
- 117, 118, 118, 119, 119, 120, 120, 121,
- 121, 122, 122, 123, 123, 124, 124, 125,
- 125, 126, 126, 127, 127, 127, 128, 128,
- 129, 129, 130, 130, 131, 131, 132, 132,
- 133, 133, 134, 134, 135, 135, 136, 136,
- 137, 137, 138, 138, 138, 139, 139, 140,
- 140, 141, 141, 141, 142, 142, 143, 143,
- 143, 144, 144, 145, 145, 145, 146, 146,
- 146, 147, 147, 147, 148, 148, 149, 149,
- 149, 150, 150, 150, 151, 151, 151, 152,
- 152, 153, 153, 153, 154, 154, 155, 155,
- 155, 156, 156, 157, 157, 157, 158, 158,
- 159, 159, 159, 160, 160, 161, 161, 162,
- 162, 162, 163, 163, 164, 164, 164, 165,
- 165, 166, 166, 167, 167, 167, 168, 168,
- 169, 169, 170, 170, 170, 171, 171, 172,
- 172, 173, 173, 174, 174, 175, 175, 176,
- 176, 177, 177, 178, 178, 179, 179, 180,
- 180, 181, 182, 182, 183, 184, 184, 185,
- 186, 186, 187, 188, 188, 189, 190, 191,
- 191, 192, 193, 194, 195, 196, 196, 197,
- 198, 199, 200, 201, 202, 203, 204, 205,
- 206, 207, 208, 209, 210, 211, 213, 214,
- 215, 216, 218, 219, 220, 222, 223, 225,
- 227, 228, 230, 232, 233, 235, 237, 239,
- 241, 243, 245, 247, 249, 251, 253, 255
+ 2, 5, 7, 10, 12, 15, 17, 20, 22, 24, 26, 28, 30, 32, 34, 36,
+ 38, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 50, 51, 52, 52, 53,
+ 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 58, 59, 59, 60, 60, 60,
+ 61, 61, 61, 62, 62, 63, 63, 63, 64, 64, 64, 64, 65, 65, 65, 65,
+ 66, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 69, 69, 69, 69,
+ 70, 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, 73, 73, 74, 74, 74,
+ 75, 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 78, 78, 79, 79, 79,
+ 80, 80, 80, 81, 81, 82, 82, 82, 83, 83, 83, 84, 84, 85, 85, 85,
+ 86, 86, 86, 87, 87, 88, 88, 88, 89, 89, 90, 90, 91, 91, 92, 92,
+ 93, 93, 94, 94, 95, 95, 96, 96, 97, 97, 98, 99, 99, 100, 101, 101,
+102, 102, 103, 104, 104, 105, 106, 106, 107, 108, 109, 110, 110, 111, 112, 113,
+114, 115, 115, 116, 117, 118, 118, 119, 120, 121, 121, 122, 123, 124, 124, 125,
+126, 127, 128, 129, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
+141, 142, 143, 144, 146, 147, 148, 149, 150, 151, 153, 154, 155, 156, 158, 159,
+160, 162, 163, 165, 166, 168, 169, 171, 172, 175, 177, 180, 182, 185, 187, 190,
+192, 196, 199, 203, 206, 210, 213, 217, 220, 223, 227, 230, 234, 238, 242, 246
};
-#elif (CONFIG_LCD == LCD_IPOD2BPP) || (CONFIG_LCD == LCD_IPODMINI)
-/* measured and interpolated curve for mini LCD */
-/* TODO: verify this curve on the fullsize greyscale LCD */
+/* Average of an iPod Mini G2 and 2 3rd Gen iPods. */
+#define LCD_SCANRATE 87 /* Hz */
+
+#elif defined IRIVER_H100_SERIES /* verified */
+/* Measurement of one Iriver H140 */
static const unsigned char lcdlinear[256] = {
- 0, 3, 6, 8, 11, 14, 17, 19,
- 22, 24, 27, 29, 32, 34, 36, 38,
- 40, 42, 44, 45, 47, 48, 50, 51,
- 52, 54, 55, 56, 57, 58, 58, 59,
- 60, 61, 62, 62, 63, 64, 64, 65,
- 66, 66, 67, 67, 68, 68, 69, 69,
- 70, 70, 70, 71, 71, 71, 72, 72,
- 73, 73, 73, 74, 74, 74, 74, 75,
- 75, 75, 76, 76, 76, 77, 77, 77,
- 78, 78, 78, 79, 79, 79, 80, 80,
- 80, 80, 81, 81, 81, 82, 82, 82,
- 83, 83, 83, 84, 84, 84, 85, 85,
- 85, 85, 86, 86, 86, 87, 87, 87,
- 87, 88, 88, 88, 89, 89, 89, 89,
- 90, 90, 90, 91, 91, 91, 92, 92,
- 92, 93, 93, 93, 94, 94, 94, 95,
- 95, 96, 96, 96, 97, 97, 98, 98,
- 99, 99, 99, 100, 100, 101, 101, 102,
- 102, 103, 103, 104, 104, 105, 105, 106,
- 106, 107, 107, 108, 108, 109, 109, 110,
- 110, 111, 111, 112, 113, 113, 114, 114,
- 115, 115, 116, 117, 117, 118, 118, 119,
- 120, 120, 121, 122, 122, 123, 124, 124,
- 125, 126, 126, 127, 128, 128, 129, 130,
- 131, 131, 132, 133, 134, 134, 135, 136,
- 137, 138, 139, 140, 141, 142, 143, 144,
- 145, 146, 147, 148, 149, 150, 152, 153,
- 154, 156, 157, 159, 160, 162, 163, 165,
- 167, 168, 170, 172, 174, 176, 178, 180,
- 182, 184, 187, 189, 192, 194, 197, 200,
- 203, 206, 209, 212, 215, 219, 222, 226,
- 229, 233, 236, 240, 244, 248, 251, 255
+ 5, 8, 12, 15, 18, 22, 25, 28, 31, 34, 36, 39, 42, 44, 47, 50,
+ 53, 55, 57, 59, 62, 64, 66, 68, 70, 71, 72, 73, 75, 76, 77, 78,
+ 79, 80, 80, 81, 82, 83, 83, 84, 85, 85, 86, 86, 87, 87, 88, 88,
+ 89, 89, 90, 90, 91, 91, 92, 92, 93, 93, 93, 94, 94, 95, 95, 95,
+ 96, 96, 96, 97, 97, 98, 98, 98, 99, 99, 99, 100, 100, 101, 101, 101,
+102, 102, 102, 103, 103, 104, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108,
+109, 109, 109, 110, 110, 111, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115,
+116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123,
+124, 124, 125, 125, 126, 127, 127, 128, 129, 129, 130, 130, 131, 131, 132, 132,
+133, 133, 134, 135, 135, 136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141,
+142, 142, 143, 143, 144, 145, 145, 146, 147, 147, 148, 148, 149, 150, 150, 151,
+152, 152, 153, 153, 154, 155, 155, 156, 157, 157, 158, 159, 160, 160, 161, 162,
+163, 164, 165, 166, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177,
+178, 179, 181, 182, 183, 184, 186, 187, 188, 189, 191, 192, 193, 194, 196, 197,
+198, 200, 202, 203, 205, 207, 208, 210, 212, 214, 215, 217, 218, 220, 221, 223,
+224, 226, 228, 229, 231, 233, 235, 236, 238, 240, 241, 242, 244, 245, 246, 248
};
-#elif CONFIG_LCD == LCD_TL0350A
-/* measured and interpolated curve for iaudio remote */
+#define LCD_SCANRATE 70 /* Hz */
+
+#else /* not yet calibrated targets - generic linear mapping */
+/* TODO: calibrate iFP7xx
+ * TODO: Olympus m:robe 100 */
static const unsigned char lcdlinear[256] = {
- 5, 9, 13, 17, 21, 25, 29, 33,
- 36, 39, 42, 45, 48, 51, 54, 57,
- 60, 62, 65, 67, 70, 72, 75, 77,
- 80, 82, 84, 86, 87, 89, 91, 93,
- 94, 95, 96, 97, 97, 98, 99, 99,
- 100, 100, 101, 102, 103, 103, 104, 105,
- 106, 106, 107, 108, 108, 109, 110, 111,
- 112, 112, 113, 113, 114, 114, 115, 115,
- 116, 116, 117, 117, 118, 118, 119, 119,
- 120, 120, 121, 121, 122, 122, 123, 123,
- 124, 124, 124, 125, 125, 126, 126, 126,
- 127, 127, 127, 128, 128, 129, 129, 129,
- 130, 130, 131, 131, 132, 132, 133, 133,
- 134, 134, 135, 135, 136, 136, 137, 137,
- 138, 138, 139, 139, 140, 140, 141, 141,
- 142, 142, 143, 143, 144, 144, 145, 145,
- 146, 146, 147, 147, 148, 149, 149, 150,
- 151, 151, 152, 152, 153, 154, 154, 155,
- 156, 156, 157, 157, 158, 159, 159, 160,
- 161, 161, 162, 163, 164, 164, 165, 166,
- 167, 167, 168, 169, 170, 170, 171, 172,
- 173, 173, 174, 175, 176, 176, 177, 178,
- 179, 179, 180, 181, 182, 182, 183, 184,
- 185, 186, 187, 188, 188, 189, 191, 191,
- 192, 193, 194, 195, 195, 196, 197, 198,
- 199, 200, 201, 202, 203, 204, 205, 206,
- 207, 208, 209, 210, 211, 212, 213, 214,
- 215, 216, 217, 218, 219, 220, 222, 223,
- 224, 225, 226, 227, 228, 229, 230, 231,
- 232, 233, 234, 235, 236, 237, 238, 239,
- 240, 240, 241, 242, 243, 243, 244, 245,
- 246, 246, 247, 248, 249, 250, 251, 252
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
+192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
+208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
+224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
+240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
};
+/* generic default */
+#define LCD_SCANRATE 70 /* Hz */
+
#endif
#else /* SIMULATOR */
/* undo a (generic) PC display gamma of 2.0 to simulate target behaviour */
static const unsigned char lcdlinear[256] = {
- 0, 16, 23, 28, 32, 36, 39, 42,
- 45, 48, 50, 53, 55, 58, 60, 62,
- 64, 66, 68, 70, 71, 73, 75, 77,
- 78, 80, 81, 83, 84, 86, 87, 89,
- 90, 92, 93, 94, 96, 97, 98, 100,
- 101, 102, 103, 105, 106, 107, 108, 109,
- 111, 112, 113, 114, 115, 116, 117, 118,
- 119, 121, 122, 123, 124, 125, 126, 127,
- 128, 129, 130, 131, 132, 133, 134, 135,
- 135, 136, 137, 138, 139, 140, 141, 142,
- 143, 144, 145, 145, 146, 147, 148, 149,
- 150, 151, 151, 152, 153, 154, 155, 156,
- 156, 157, 158, 159, 160, 160, 161, 162,
- 163, 164, 164, 165, 166, 167, 167, 168,
- 169, 170, 170, 171, 172, 173, 173, 174,
- 175, 176, 176, 177, 178, 179, 179, 180,
- 181, 181, 182, 183, 183, 184, 185, 186,
- 186, 187, 188, 188, 189, 190, 190, 191,
- 192, 192, 193, 194, 194, 195, 196, 196,
- 197, 198, 198, 199, 199, 200, 201, 201,
- 202, 203, 203, 204, 204, 205, 206, 206,
- 207, 208, 208, 209, 209, 210, 211, 211,
- 212, 212, 213, 214, 214, 215, 215, 216,
- 217, 217, 218, 218, 219, 220, 220, 221,
- 221, 222, 222, 223, 224, 224, 225, 225,
- 226, 226, 227, 228, 228, 229, 229, 230,
- 230, 231, 231, 232, 233, 233, 234, 234,
- 235, 235, 236, 236, 237, 237, 238, 238,
- 239, 240, 240, 241, 241, 242, 242, 243,
- 243, 244, 244, 245, 245, 246, 246, 247,
- 247, 248, 248, 249, 249, 250, 250, 251,
- 251, 252, 252, 253, 253, 254, 254, 255
+ 0, 16, 23, 28, 32, 36, 39, 42, 45, 48, 50, 53, 55, 58, 60, 62,
+ 64, 66, 68, 70, 71, 73, 75, 77, 78, 80, 81, 83, 84, 86, 87, 89,
+ 90, 92, 93, 94, 96, 97, 98, 100, 101, 102, 103, 105, 106, 107, 108, 109,
+111, 112, 113, 114, 115, 116, 117, 118, 119, 121, 122, 123, 124, 125, 126, 127,
+128, 129, 130, 131, 132, 133, 134, 135, 135, 136, 137, 138, 139, 140, 141, 142,
+143, 144, 145, 145, 146, 147, 148, 149, 150, 151, 151, 152, 153, 154, 155, 156,
+156, 157, 158, 159, 160, 160, 161, 162, 163, 164, 164, 165, 166, 167, 167, 168,
+169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 179, 179, 180,
+181, 181, 182, 183, 183, 184, 185, 186, 186, 187, 188, 188, 189, 190, 190, 191,
+192, 192, 193, 194, 194, 195, 196, 196, 197, 198, 198, 199, 199, 200, 201, 201,
+202, 203, 203, 204, 204, 205, 206, 206, 207, 208, 208, 209, 209, 210, 211, 211,
+212, 212, 213, 214, 214, 215, 215, 216, 217, 217, 218, 218, 219, 220, 220, 221,
+221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, 228, 228, 229, 229, 230,
+230, 231, 231, 232, 233, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238,
+239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247,
+247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255
};
#endif /* SIMULATOR */
@@ -224,12 +235,64 @@ static inline void _deferred_update(void) __attribute__ ((always_inline));
static int exp_s16p16(int x);
static int log_s16p16(int x);
static void grey_screendump_hook(int fd);
+static void fill_gvalues(void);
#ifdef SIMULATOR
static unsigned long _grey_get_pixel(int x, int y);
#else
static void _timer_isr(void);
#endif
+#if defined(HAVE_BACKLIGHT_INVERSION) && !defined(SIMULATOR)
+static bool backlight_state;
+
+
+static void invert_gvalues(void)
+{
+ unsigned char *val, *end;
+ unsigned char rev_tab[256];
+ unsigned i;
+ unsigned last_i = 0;
+ unsigned x = 0;
+ unsigned last_x;
+
+ if (_grey_info.flags & GREY_BUFFERED)
+ {
+ fill_gvalues();
+ grey_update();
+ }
+ else /* Unbuffered - need crude reconstruction */
+ {
+ /* Step 1: Calculate a transposed table for undoing the old mapping */
+ for (i = 0; i < 256; i++)
+ {
+ last_x = x;
+ x = _grey_info.gvalue[i];
+ if (x > last_x)
+ {
+ rev_tab[last_x++] = (last_i + i) / 2;
+ while (x > last_x)
+ rev_tab[last_x++] = i;
+ last_i = i;
+ }
+ }
+ rev_tab[last_x++] = (last_i + 255) / 2;
+ while (256 > last_x)
+ rev_tab[last_x++] = 255;
+
+ /* Step 2: Calculate new mapping */
+ fill_gvalues();
+
+ /* Step 3: Transpose all pixel values */
+ val = _grey_info.values;
+ end = val + _GREY_MULUQ(_grey_info.width, _grey_info.height);
+
+ do
+ *val = _grey_info.gvalue[rev_tab[*val]];
+ while (++val < end);
+ }
+}
+#endif
+
/* Update LCD areas not covered by the greyscale overlay */
static inline void _deferred_update(void)
{
@@ -275,6 +338,16 @@ static unsigned long _grey_get_pixel(int x, int y)
/* Timer interrupt handler: display next frame */
static void _timer_isr(void)
{
+#if defined(HAVE_BACKLIGHT_INVERSION) && !defined(SIMULATOR)
+ bool bls = _grey_info.rb->is_backlight_on(true);
+
+ if ((backlight_state != bls) && !(_grey_info.flags & GREY_RAWMAPPED))
+ {
+ backlight_state = bls;
+ invert_gvalues();
+ return; /* don't overload this timer slot */
+ }
+#endif
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
_grey_info.rb->lcd_blit_grey_phase(_grey_info.values, _grey_info.phases,
_grey_info.bx, _grey_info.y,
@@ -343,6 +416,26 @@ static int log_s16p16(int x)
return y;
}
+static void fill_gvalues(void)
+{
+ int i;
+ unsigned data;
+
+#if defined(HAVE_BACKLIGHT_INVERSION) && !defined(SIMULATOR)
+ unsigned imask = backlight_state ? 0xff : 0;
+#else
+ const unsigned imask = 0;
+#endif
+ for (i = 0; i < 256; i++)
+ {
+ data = exp_s16p16((_GREY_GAMMA * log_s16p16(i * 257 + 1)) >> 8) + 128;
+ data = (data - (data >> 8)) >> 8; /* approx. data /= 257 */
+ data = ((lcdlinear[data ^ imask] ^ imask) << 7) + 127;
+ _grey_info.gvalue[i] = (data + (data >> 8)) >> 8;
+ /* approx. data / 255 */
+ }
+}
+
/* Initialise the framework and prepare the greyscale display buffer
arguments:
@@ -449,7 +542,7 @@ bool grey_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
_grey_info.by = 0;
_grey_info.bheight = bdim;
#endif
- _grey_info.flags = 0;
+ _grey_info.flags = features & 0xff;
_grey_info.fg_brightness = 0;
_grey_info.bg_brightness = 255;
_grey_info.drawmode = DRMODE_SOLID;
@@ -458,21 +551,21 @@ bool grey_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
/* precalculate the value -> pattern index conversion table, taking
linearisation and gamma correction into account */
if (features & GREY_RAWMAPPED)
+ {
for (i = 0; i < 256; i++)
{
data = i << 7;
_grey_info.gvalue[i] = (data + (data >> 8)) >> 8;
}
+ }
else
- for (i = 0; i < 256; i++)
- {
- data = exp_s16p16(((2<<8) * log_s16p16(i * 257 + 1)) >> 8) + 128;
- data = (data - (data >> 8)) >> 8; /* approx. data /= 257 */
- data = (lcdlinear[data] << 7) + 127;
- _grey_info.gvalue[i] = (data + (data >> 8)) >> 8;
- /* approx. data / 255 */
- }
-
+ {
+#if defined(HAVE_BACKLIGHT_INVERSION) && !defined(SIMULATOR)
+ backlight_state = _grey_info.rb->is_backlight_on(true);
+#endif
+ fill_gvalues();
+ }
+
if (buf_taken) /* caller requested info about space taken */
*buf_taken = buftaken;
@@ -509,29 +602,8 @@ void grey_show(bool enable)
#ifdef NEED_BOOST
_grey_info.rb->cpu_boost(true);
#endif
-#if CONFIG_LCD == LCD_SSD1815
- _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 67, 1, _timer_isr);
-#elif CONFIG_LCD == LCD_S1D15E06
- _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 70, 1, _timer_isr);
-#elif CONFIG_LCD == LCD_IPOD2BPP
-#ifdef IPOD_1G2G
- _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 96, 1, _timer_isr); /* verified */
-#elif defined IPOD_3G
- _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 87, 1, _timer_isr); /* verified */
-#else
- /* FIXME: verify value */
- _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 80, 1, _timer_isr);
-#endif
-#elif CONFIG_LCD == LCD_IPODMINI
- _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 88, 1, _timer_isr);
-#elif CONFIG_LCD == LCD_IFP7XX
- _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 83, 1, _timer_isr);
-#elif CONFIG_LCD == LCD_MROBE100
- _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 83, 1, _timer_isr); /* not calibrated/tested */
-#elif CONFIG_LCD == LCD_TL0350A
- _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 75, 1, _timer_isr); /* verified */
- /* This is half of the actual frame frequency, but 150Hz is too much */
-#endif /* CONFIG_LCD */
+ _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / LCD_SCANRATE, 1,
+ _timer_isr);
#endif /* !SIMULATOR */
_grey_info.rb->screen_dump_set_hook(grey_screendump_hook);
}
diff --git a/apps/screen_access.h b/apps/screen_access.h
index 7efa48c423..883e1528dd 100644
--- a/apps/screen_access.h
+++ b/apps/screen_access.h
@@ -151,7 +151,7 @@ struct screen
void (*update_viewport)(void);
void (*backlight_on)(void);
void (*backlight_off)(void);
- bool (*is_backlight_on)(void);
+ bool (*is_backlight_on)(bool ignore_always_off);
void (*backlight_set_timeout)(int index);
};
diff --git a/firmware/backlight.c b/firmware/backlight.c
index 0f66fbf574..19e6933fca 100644
--- a/firmware/backlight.c
+++ b/firmware/backlight.c
@@ -631,13 +631,13 @@ void backlight_off(void)
queue_post(&backlight_queue, BACKLIGHT_OFF, 0);
}
-/* returns true when the backlight is on OR when it's set to always off */
-bool is_backlight_on(void)
+/* returns true when the backlight is on,
+ * and optionally when it's set to always off. */
+bool is_backlight_on(bool ignore_always_off)
{
- if (backlight_timer || backlight_timeout <= 0)
- return true;
- else
- return false;
+ return (backlight_timer > 0) /* countdown */
+ || (backlight_timeout == 0) /* always on */
+ || ((backlight_timeout < 0) && !ignore_always_off);
}
/* return value in ticks; 0 means always on, <0 means always off */
@@ -752,13 +752,13 @@ int remote_backlight_get_current_timeout(void)
return remote_backlight_timeout;
}
-/* returns true when the backlight is on OR when it's set to always off */
-bool is_remote_backlight_on(void)
+/* returns true when the backlight is on, and
+ * optionally when it's set to always off */
+bool is_remote_backlight_on(bool ignore_always_off)
{
- if (remote_backlight_timer != 0 || remote_backlight_timeout <= 0)
- return true;
- else
- return false;
+ return (remote_backlight_timer > 0) /* countdown */
+ || (remote_backlight_timeout == 0) /* always on */
+ || ((remote_backlight_timeout < 0) && !ignore_always_off);
}
#endif /* HAVE_REMOTE_LCD */
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c
index d38306b3ca..90ff800c88 100644
--- a/firmware/drivers/button.c
+++ b/firmware/drivers/button.c
@@ -247,9 +247,10 @@ static void button_tick(void)
#ifdef HAVE_BACKLIGHT
#ifdef HAVE_REMOTE_LCD
if (btn & BUTTON_REMOTE) {
- if (!remote_filter_first_keypress || is_remote_backlight_on()
+ if (!remote_filter_first_keypress
+ || is_remote_backlight_on(false)
#if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
- || (remote_type()==REMOTETYPE_H300_NONLCD)
+ || (remote_type()==REMOTETYPE_H300_NONLCD)
#endif
)
queue_post(&button_queue, btn, data);
@@ -258,9 +259,9 @@ static void button_tick(void)
}
else
#endif
- if (!filter_first_keypress || is_backlight_on()
+ if (!filter_first_keypress || is_backlight_on(false)
#if BUTTON_REMOTE
- || (btn&BUTTON_REMOTE)
+ || (btn & BUTTON_REMOTE)
#endif
)
queue_post(&button_queue, btn, data);
diff --git a/firmware/export/backlight.h b/firmware/export/backlight.h
index 3ee46c1485..35c0f86178 100644
--- a/firmware/export/backlight.h
+++ b/firmware/export/backlight.h
@@ -21,7 +21,7 @@
#include "config.h"
-bool is_backlight_on(void);
+bool is_backlight_on(bool ignore_always_off);
void backlight_on(void);
void backlight_off(void);
void backlight_set_timeout(int value);
@@ -57,7 +57,7 @@ void remote_backlight_on(void);
void remote_backlight_off(void);
void remote_backlight_set_timeout(int value);
void remote_backlight_set_timeout_plugged(int value);
-bool is_remote_backlight_on(void);
+bool is_remote_backlight_on(bool ignore_always_off);
#ifdef HAS_REMOTE_BUTTON_HOLD
void remote_backlight_hold_changed(bool rc_hold_button);
diff --git a/uisimulator/sdl/button.c b/uisimulator/sdl/button.c
index 03f7dc1e96..15764da900 100644
--- a/uisimulator/sdl/button.c
+++ b/uisimulator/sdl/button.c
@@ -883,14 +883,16 @@ void button_event(int key, bool pressed)
#ifdef HAVE_BACKLIGHT
#ifdef HAVE_REMOTE_LCD
if (btn & BUTTON_REMOTE) {
- if (!remote_filter_first_keypress || is_remote_backlight_on())
+ if (!remote_filter_first_keypress
+ || is_remote_backlight_on(false))
queue_post(&button_queue, btn, data);
else
skip_remote_release = true;
}
else
#endif
- if (!filter_first_keypress || is_backlight_on())
+ if (!filter_first_keypress
+ || is_backlight_on(false))
queue_post(&button_queue, btn, data);
else
skip_release = true;