summaryrefslogtreecommitdiff
path: root/utils/nwztools
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2016-11-06 00:12:04 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2016-11-06 00:12:04 +0100
commit5017babb307122d8567ca78a5721e96c4d7ff8f2 (patch)
tree26ca7ac1d8a3608e364d59a203c32b81b16f92e3 /utils/nwztools
parentd492f25c54b4134fd6632156efee07670ab4004f (diff)
downloadrockbox-5017babb307122d8567ca78a5721e96c4d7ff8f2.tar.gz
rockbox-5017babb307122d8567ca78a5721e96c4d7ff8f2.zip
nwztools/plattools: fix black screen issue in dualboot, rework dualboot
Sony added extensions to the frambuffer interface. It is important to take them into account since the OF uses them and might leave the framebuffer in an unusual state which would make the dualboot not display anything. Also rework the dualboot code so that it can boot rockbox (not doing anything at the moment), display all tools or boot the OF. Change-Id: Ia0f589c9ec8558f375270841503c0964aff07f0b
Diffstat (limited to 'utils/nwztools')
-rw-r--r--utils/nwztools/plattools/Makefile2
-rw-r--r--utils/nwztools/plattools/all_tools.c5
-rw-r--r--utils/nwztools/plattools/dualboot.c114
-rw-r--r--utils/nwztools/plattools/nwz_fb.h87
-rw-r--r--utils/nwztools/plattools/nwz_lib.c21
-rw-r--r--utils/nwztools/plattools/nwz_lib.h3
-rw-r--r--utils/nwztools/plattools/test_display.c24
7 files changed, 180 insertions, 76 deletions
diff --git a/utils/nwztools/plattools/Makefile b/utils/nwztools/plattools/Makefile
index f4e88cd778..067b4a7033 100644
--- a/utils/nwztools/plattools/Makefile
+++ b/utils/nwztools/plattools/Makefile
@@ -6,7 +6,7 @@ INCLUDES=-I.
6 6
7LIB_FILES=nwz_lib.c nwz_lib_devlist.c 7LIB_FILES=nwz_lib.c nwz_lib_devlist.c
8TOOL_FILES=dest_tool.c test_adc.c test_adc.c test_bl.c test_display.c \ 8TOOL_FILES=dest_tool.c test_adc.c test_adc.c test_bl.c test_display.c \
9 test_keys.c test_power.c test_ts.c 9 test_keys.c test_power.c test_ts.c test_fb.c
10ALL_ELF=$(patsubst %.c,%.elf,$(TOOL_FILES)) all_tools.elf dualboot.elf 10ALL_ELF=$(patsubst %.c,%.elf,$(TOOL_FILES)) all_tools.elf dualboot.elf
11 11
12all: $(ALL_ELF) 12all: $(ALL_ELF)
diff --git a/utils/nwztools/plattools/all_tools.c b/utils/nwztools/plattools/all_tools.c
index f3ecb51c05..c93e26b36e 100644
--- a/utils/nwztools/plattools/all_tools.c
+++ b/utils/nwztools/plattools/all_tools.c
@@ -31,7 +31,8 @@
31 TOOL(test_display) \ 31 TOOL(test_display) \
32 TOOL(test_keys) \ 32 TOOL(test_keys) \
33 TOOL(test_power) \ 33 TOOL(test_power) \
34 TOOL(test_ts) 34 TOOL(test_ts) \
35 TOOL(test_fb) \
35 36
36typedef int (*nwz_tool_main_t)(int argc, char **argv); 37typedef int (*nwz_tool_main_t)(int argc, char **argv);
37 38
@@ -60,7 +61,7 @@ static void hello(void)
60{ 61{
61 /* clear screen and display welcome message */ 62 /* clear screen and display welcome message */
62 nwz_lcdmsg(true, 0, 0, "all_tools"); 63 nwz_lcdmsg(true, 0, 0, "all_tools");
63 nwz_lcdmsg(false, 0, 2, "BACK: quit"); 64 nwz_lcdmsg(false, 0, 1, "BACK: quit");
64 nwz_lcdmsg(false, 0, 2, "LEFT/RIGHT: change tool"); 65 nwz_lcdmsg(false, 0, 2, "LEFT/RIGHT: change tool");
65 nwz_lcdmsg(false, 0, 3, "PLAY: run tool"); 66 nwz_lcdmsg(false, 0, 3, "PLAY: run tool");
66} 67}
diff --git a/utils/nwztools/plattools/dualboot.c b/utils/nwztools/plattools/dualboot.c
index 965fabed72..a5d04fa4ed 100644
--- a/utils/nwztools/plattools/dualboot.c
+++ b/utils/nwztools/plattools/dualboot.c
@@ -29,7 +29,14 @@
29 * error, the OF is run. This seems like the safest option since the OF is 29 * error, the OF is run. This seems like the safest option since the OF is
30 * always there and might do magic things. */ 30 * always there and might do magic things. */
31 31
32bool boot_rockbox(void) 32enum boot_mode
33{
34 BOOT_ROCKBOX,
35 BOOT_TOOLS,
36 BOOT_OF
37};
38
39enum boot_mode get_boot_mode(void)
33{ 40{
34 /* get time */ 41 /* get time */
35 struct timeval deadline; 42 struct timeval deadline;
@@ -37,7 +44,7 @@ bool boot_rockbox(void)
37 { 44 {
38 nwz_lcdmsg(false, 0, 2, "Cannot get time"); 45 nwz_lcdmsg(false, 0, 2, "Cannot get time");
39 sleep(2); 46 sleep(2);
40 return false; 47 return BOOT_OF;
41 } 48 }
42 /* open input device */ 49 /* open input device */
43 int input_fd = nwz_key_open(); 50 int input_fd = nwz_key_open();
@@ -45,11 +52,11 @@ bool boot_rockbox(void)
45 { 52 {
46 nwz_lcdmsg(false, 0, 2, "Cannot open input device"); 53 nwz_lcdmsg(false, 0, 2, "Cannot open input device");
47 sleep(2); 54 sleep(2);
48 return false; 55 return BOOT_OF;
49 } 56 }
50 deadline.tv_sec += 5; 57 deadline.tv_sec += 5;
51 /* wait for user action */ 58 /* wait for user action */
52 bool boot_rb = false; 59 enum boot_mode mode = BOOT_OF;
53 while(true) 60 while(true)
54 { 61 {
55 /* get time */ 62 /* get time */
@@ -69,7 +76,8 @@ bool boot_rockbox(void)
69 int sec_left = deadline.tv_sec - cur_time.tv_sec; 76 int sec_left = deadline.tv_sec - cur_time.tv_sec;
70 sec_left += (deadline.tv_usec - cur_time.tv_usec + 999999) / 1000000; /* round up */ 77 sec_left += (deadline.tv_usec - cur_time.tv_usec + 999999) / 1000000; /* round up */
71 nwz_lcdmsgf(false, 0, 2, "Booting OF in %d seconds ", sec_left); 78 nwz_lcdmsgf(false, 0, 2, "Booting OF in %d seconds ", sec_left);
72 nwz_lcdmsg(false, 0, 3, "Press BACK to boot RB"); 79 nwz_lcdmsg(false, 0, 3, "Press BACK to run tools");
80 nwz_lcdmsg(false, 0, 3, "Press PLAY to boot RB");
73 /* wait for a key (1s) */ 81 /* wait for a key (1s) */
74 int ret = nwz_key_wait_event(input_fd, 1000000); 82 int ret = nwz_key_wait_event(input_fd, 1000000);
75 if(ret != 1) 83 if(ret != 1)
@@ -77,14 +85,21 @@ bool boot_rockbox(void)
77 struct input_event evt; 85 struct input_event evt;
78 if(nwz_key_read_event(input_fd, &evt) != 1) 86 if(nwz_key_read_event(input_fd, &evt) != 1)
79 continue; 87 continue;
80 if(nwz_key_event_get_keycode(&evt) == NWZ_KEY_BACK && !nwz_key_event_is_press(&evt)) 88 if(nwz_key_event_is_press(&evt))
89 continue;
90 if(nwz_key_event_get_keycode(&evt) == NWZ_KEY_PLAY)
81 { 91 {
82 boot_rb = true; 92 mode = BOOT_ROCKBOX;
93 break;
94 }
95 else if(nwz_key_event_get_keycode(&evt) == NWZ_KEY_BACK)
96 {
97 mode = BOOT_TOOLS;
83 break; 98 break;
84 } 99 }
85 } 100 }
86 nwz_key_close(input_fd); 101 nwz_key_close(input_fd);
87 return boot_rb; 102 return mode;
88} 103}
89 104
90static char *boot_rb_argv[] = 105static char *boot_rb_argv[] =
@@ -97,41 +112,40 @@ static char *boot_rb_argv[] =
97 NULL 112 NULL
98}; 113};
99 114
100static void wait_key(void)
101{
102 int input_fd = nwz_key_open();
103 /* display input state in a loop */
104 while(1)
105 {
106 /* wait for event (10ms) */
107 int ret = nwz_key_wait_event(input_fd, 10000);
108 if(ret != 1)
109 continue;
110 struct input_event evt;
111 if(nwz_key_read_event(input_fd, &evt) != 1)
112 continue;
113 if(nwz_key_event_get_keycode(&evt) == NWZ_KEY_BACK && !nwz_key_event_is_press(&evt))
114 break;
115 }
116 /* finish nicely */
117 nwz_key_close(input_fd);
118}
119
120int NWZ_TOOL_MAIN(all_tools)(int argc, char **argv); 115int NWZ_TOOL_MAIN(all_tools)(int argc, char **argv);
121 116
122int main(int argc, char **argv) 117int main(int argc, char **argv)
123{ 118{
124#if 0 119 /* make sure backlight is on and we are running the standard lcd mode */
120 int fb_fd = nwz_fb_open(true);
121 if(fb_fd >= 0)
122 {
123 struct nwz_fb_brightness bl;
124 nwz_fb_get_brightness(fb_fd, &bl);
125 bl.level = NWZ_FB_BL_MAX_LEVEL;
126 nwz_fb_set_brightness(fb_fd, &bl);
127 nwz_fb_set_standard_mode(fb_fd);
128 nwz_fb_close(fb_fd);
129 }
125 nwz_lcdmsg(true, 0, 0, "dualboot"); 130 nwz_lcdmsg(true, 0, 0, "dualboot");
126 if(boot_rockbox()) 131 /* run all tools menu */
132 enum boot_mode mode = get_boot_mode();
133 if(mode == BOOT_TOOLS)
134 {
135 /* run tools and then run OF */
136 NWZ_TOOL_MAIN(all_tools)(argc, argv);
137 }
138 else if(mode == BOOT_ROCKBOX)
127 { 139 {
128 /* boot rockox */ 140 /* boot rockox */
129 nwz_lcdmsg(true, 0, 3, "Booting rockbox..."); 141 nwz_lcdmsg(true, 0, 3, "Booting rockbox...");
142 /* in the future, we will run rockbox here, for now we just print a
143 * message */
130 execvp("/usr/local/bin/lcdmsg", boot_rb_argv); 144 execvp("/usr/local/bin/lcdmsg", boot_rb_argv);
145 /* fallback to OF in case of failure */
131 nwz_lcdmsg(false, 0, 4, "failed."); 146 nwz_lcdmsg(false, 0, 4, "failed.");
132 sleep(5); 147 sleep(5);
133 } 148 }
134 /* if for some reason, running rockbox failed, then try to run the OF */
135 /* boot OF */ 149 /* boot OF */
136 nwz_lcdmsg(true, 0, 3, "Booting OF..."); 150 nwz_lcdmsg(true, 0, 3, "Booting OF...");
137 execvp("/usr/local/bin/SpiderApp.of", argv); 151 execvp("/usr/local/bin/SpiderApp.of", argv);
@@ -140,42 +154,4 @@ int main(int argc, char **argv)
140 /* if we reach this point, everything failed, so return an error so that 154 /* if we reach this point, everything failed, so return an error so that
141 * sysmgrd knows something is wrong */ 155 * sysmgrd knows something is wrong */
142 return 1; 156 return 1;
143#elif 0
144 const char *args_mount[] = {"mount", NULL};
145 int status;
146 char *output = nwz_run_pipe("mount", args_mount, &status);
147 nwz_lcdmsgf(true, 0, 0, "%d\n%s", status, output);
148 free(output);
149 wait_key();
150 const char *args_ls[] = {"ls", "/var", NULL};
151 output = nwz_run_pipe("ls", args_ls, &status);
152 nwz_lcdmsgf(true, 0, 0, "%d\n%s", status, output);
153 free(output);
154 wait_key();
155 const char *args_glogctl[] = {"glogctl", "flush", NULL};
156 output = nwz_run_pipe("/usr/local/bin/glogctl", args_glogctl, &status);
157 nwz_lcdmsgf(true, 0, 0, "%d\n%s", status, output);
158 free(output);
159 wait_key();
160 system("cp /var/GEMINILOG* /contents/");
161 sync();
162 execvp("/usr/local/bin/SpiderApp.of", argv);
163 return 0;
164#else
165 /* make sure backlight is on */
166 int fb_fd = nwz_fb_open(true);
167 if(fb_fd >= 0)
168 {
169 struct nwz_fb_brightness bl;
170 nwz_fb_get_brightness(fb_fd, &bl);
171 bl.level = NWZ_FB_BL_MAX_LEVEL;
172 nwz_fb_set_brightness(fb_fd, &bl);
173 nwz_fb_close(fb_fd);
174 }
175 /* run all tools menu */
176 NWZ_TOOL_MAIN(all_tools)(argc, argv);
177 /* run OF */
178 execvp("/usr/local/bin/SpiderApp.of", argv);
179 return 0;
180#endif
181} 157}
diff --git a/utils/nwztools/plattools/nwz_fb.h b/utils/nwztools/plattools/nwz_fb.h
index c857c5eb8a..9334b625c9 100644
--- a/utils/nwztools/plattools/nwz_fb.h
+++ b/utils/nwztools/plattools/nwz_fb.h
@@ -50,7 +50,90 @@ struct nwz_fb_brightness
50 int period; /* period in ms between steps when changing: >=10 */ 50 int period; /* period in ms between steps when changing: >=10 */
51}; 51};
52 52
53#define NWZ_FB_SET_BRIGHTNESS _IOW(NWZ_FB_TYPE, 0x07, struct nwz_fb_brightness) 53/* FB extensions:
54#define NWZ_FB_GET_BRIGHTNESS _IOR(NWZ_FB_TYPE, 0x08, struct nwz_fb_brightness) 54 *
55 * Sony added relatively complicated extensions to the framebuffer. They allow
56 * better control of framebuffer refresh, double-buffering and mixing with DSP
57 * (v4l2). Each outout (LCD and TV) has two buffers, called page 0 and 1 (or A
58 * and B). Each page has its own attributes (image info) that control
59 * transparency, rotation and updates. At any point in time, the LCD is drawing
60 * a page and one can select the next page to draw. Unless an UPDATE ioctl()
61 * is made to change it, the next page will be the same as the one being drawn.
62 *
63 * FIXME I don't know what the timer is, it seems irrelevant for the LCD but
64 * the OF uses it for TV, maybe this controls the refresh rate of the TV output?
65 *
66 * On a side note, this information only applies to a subset of LCD types (the
67 * LCD type can be gathered from icx_sysinfo):
68 * - BB(0): AQUILA BB LCD
69 * - SW(1): SWAN or FIJI LCD
70 * - FC(2): FALCON OLED
71 * - GM(3): GUAM and ROTA LCD
72 * - FR(5): FURANO LCD ---> /!\ DOES NOT APPLY /!\
73 * - SD(6): SPICA_D LCD
74 * - AQ(7): AQUILA LCD
75 */
76
77/* Image infomation:
78 * SET_MODE will change the attributes of the requested page (ie .page)
79 * GET_MODE will return the attributes of the currently being displayed page
80 * UPDATE will do the same thing as SET_MODE but immediately refreshes the screen */
81struct nwz_fb_image_info
82{
83 int tc_enable; /* enable(1)/disable(0) transparent color */
84 int t_color; /* transparent color (16bpp RGB565) */
85 int alpha; /* alpha ratio (0 - 255) */
86 int page; /* 2D framebuffer page(0/1) */
87 int rot; /* LCD image rotation(0/1=180deg.) */
88 int update; /* only use with NWZ_FB_UPDATE, ignored for others */
89};
90
91/* update type */
92#define NWZ_FB_ONLY_2D_MODE 0
93#define NWZ_FB_DSP_AND_2D_MODE 1
94
95/* frame buffer page infomation: when NWZ_FB_WAIT_REFREHS is called, the driver
96 * will wait until the next refresh or the timeout, whichever comes first. It
97 * will then fill this structure with the page status. */
98struct nwz_fb_status
99{
100 int timeout; /* waiting time for any frame ready (in units of 10 ms) */
101 int page0; /* page 0 is out of display or waiting to be displayed */
102 int page1; /* page 0 is out of display or waiting to be displayed */
103};
104
105/* frame buffer page status */
106#define NWZ_FB_OUT_OF_DISPLAY 0
107#define NWZ_FB_WAITING_FOR_ON_DISPLAY 1
108
109/* frame buffer update timer infomation (use I/F fb <-> 2D API) */
110struct nwz_fb_update_timer
111{
112 int timerflag; /* auto update off(0) / auto update on(1) */
113 int timeout; /* timeout timer value (ms) */
114};
115
116/* timer flags */
117#define NWZ_FB_TIMER_ON 1
118#define NWZ_FB_TIMER_OFF 0
119
120/* default and minimum timeout value */
121#define NWZ_FB_DEFAULT_TIMEOUT 60
122#define NWZ_FB_MIN_TIMEOUT 33
123
124/* mmap offsets for page 1 (page 0 is always at address 0) */
125#define NWZ_FB_LCD_PAGE_OFFSET 0x2f000
126
127/* NOTE: I renamed those from Sony's header, because their original names were
128 * pure crap */
129/* FIXME: Sony uses _IOR for NWZ_FB_WAIT_REFRESH but it should be _IORW */
130#define NWZ_FB_WAIT_REFRESH _IORW(NWZ_FB_TYPE, 0x00, struct nwz_fb_status)
131#define NWZ_FB_UPDATE _IOW(NWZ_FB_TYPE, 0x01, struct nwz_fb_image_info)
132#define NWZ_FB_SET_MODE _IOW(NWZ_FB_TYPE, 0x02, struct nwz_fb_image_info)
133#define NWZ_FB_GET_MODE _IOR(NWZ_FB_TYPE, 0x03, struct nwz_fb_image_info)
134#define NWZ_FB_UPDATE_TIMER _IOR(NWZ_FB_TYPE, 0x04, struct nwz_fb_update_timer)
135#define NWZ_FB_SET_BRIGHTNESS _IOW(NWZ_FB_TYPE, 0x07, struct nwz_fb_brightness)
136#define NWZ_FB_GET_BRIGHTNESS _IOR(NWZ_FB_TYPE, 0x08, struct nwz_fb_brightness)
137
55 138
56#endif /* __NWZ_FB_H__ */ 139#endif /* __NWZ_FB_H__ */
diff --git a/utils/nwztools/plattools/nwz_lib.c b/utils/nwztools/plattools/nwz_lib.c
index 087db8834a..43dc977d42 100644
--- a/utils/nwztools/plattools/nwz_lib.c
+++ b/utils/nwztools/plattools/nwz_lib.c
@@ -238,6 +238,27 @@ int nwz_fb_set_brightness(int fd, struct nwz_fb_brightness *bl)
238 return 1; 238 return 1;
239} 239}
240 240
241int nwz_fb_set_standard_mode(int fd)
242{
243 /* disable timer (apparently useless with LCD) */
244 struct nwz_fb_update_timer update_timer;
245 update_timer.timerflag = NWZ_FB_TIMER_OFF;
246 update_timer.timeout = NWZ_FB_DEFAULT_TIMEOUT;
247 if(ioctl(fd, NWZ_FB_UPDATE_TIMER, &update_timer) < 0)
248 return -1;
249 /* set page 0 mode to no transparency and no rotation */
250 struct nwz_fb_image_info mode_info;
251 mode_info.tc_enable = 0;
252 mode_info.t_color = 0;
253 mode_info.alpha = 0;
254 mode_info.rot = 0;
255 mode_info.page = 0;
256 mode_info.update = NWZ_FB_ONLY_2D_MODE;
257 if(ioctl(fd, NWZ_FB_UPDATE, &mode_info) < 0)
258 return -2;
259 return 0;
260}
261
241int nwz_adc_open(void) 262int nwz_adc_open(void)
242{ 263{
243 return open(NWZ_ADC_DEV, O_RDONLY); 264 return open(NWZ_ADC_DEV, O_RDONLY);
diff --git a/utils/nwztools/plattools/nwz_lib.h b/utils/nwztools/plattools/nwz_lib.h
index df0105a13d..9e7b8f16c2 100644
--- a/utils/nwztools/plattools/nwz_lib.h
+++ b/utils/nwztools/plattools/nwz_lib.h
@@ -85,6 +85,9 @@ void nwz_fb_close(int fb);
85int nwz_fb_get_brightness(int fd, struct nwz_fb_brightness *bl); 85int nwz_fb_get_brightness(int fd, struct nwz_fb_brightness *bl);
86/* set backlight brightness (return -1 on error, 1 on success) */ 86/* set backlight brightness (return -1 on error, 1 on success) */
87int nwz_fb_set_brightness(int fd, struct nwz_fb_brightness *bl); 87int nwz_fb_set_brightness(int fd, struct nwz_fb_brightness *bl);
88/* setup framebuffer to its standard mode: LCD output, page 0, no transparency
89 * and no rotation, 2D only updates */
90int nwz_fb_set_standard_mode(int fd);
88 91
89/* open adc device */ 92/* open adc device */
90int nwz_adc_open(void); 93int nwz_adc_open(void);
diff --git a/utils/nwztools/plattools/test_display.c b/utils/nwztools/plattools/test_display.c
index 1ebf40e813..0a8089eca9 100644
--- a/utils/nwztools/plattools/test_display.c
+++ b/utils/nwztools/plattools/test_display.c
@@ -25,7 +25,27 @@ int NWZ_TOOL_MAIN(test_display)(int argc, char **argv)
25{ 25{
26 /* clear screen and display welcome message */ 26 /* clear screen and display welcome message */
27 nwz_lcdmsg(true, 0, 0, "test_display"); 27 nwz_lcdmsg(true, 0, 0, "test_display");
28 nwz_lcdmsg(false, 3, 10, "This program will stop in 5 seconds"); 28 nwz_lcdmsg(false, 0, 1, "BACK: quit");
29 sleep(5); 29 /* wait for key */
30 int input_fd = nwz_key_open();
31 if(input_fd < 0)
32 {
33 sleep(2);
34 return 1;
35 }
36 while(1)
37 {
38 /* wait for event */
39 int ret = nwz_key_wait_event(input_fd, 1000000);
40 if(ret != 1)
41 continue;
42 struct input_event evt;
43 if(nwz_key_read_event(input_fd, &evt) != 1)
44 continue;
45 /* handle quit */
46 if(nwz_key_event_get_keycode(&evt) == NWZ_KEY_BACK && !nwz_key_event_is_press(&evt))
47 break;
48 }
49 nwz_key_close(input_fd);
30 return 0; 50 return 0;
31} 51}