diff options
author | Jens Arnold <amiconn@rockbox.org> | 2008-04-02 22:16:14 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2008-04-02 22:16:14 +0000 |
commit | 5c87a98b97b9ab6bd9647bb0bb8d00f58d5f179b (patch) | |
tree | b61feaa66d26f63df09f03d0cb6921ac80edf560 | |
parent | cdae493f96150808007883a7fb0b582d46af4a1a (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.c | 1 | ||||
-rw-r--r-- | apps/plugin.h | 5 | ||||
-rw-r--r-- | apps/plugins/lib/grey.h | 11 | ||||
-rw-r--r-- | apps/plugins/lib/grey_core.c | 480 | ||||
-rw-r--r-- | apps/screen_access.h | 2 | ||||
-rw-r--r-- | firmware/backlight.c | 24 | ||||
-rw-r--r-- | firmware/drivers/button.c | 9 | ||||
-rw-r--r-- | firmware/export/backlight.h | 4 | ||||
-rw-r--r-- | uisimulator/sdl/button.c | 6 |
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; |