diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/SOURCES | 1 | ||||
-rw-r--r-- | firmware/backlight.c | 2 | ||||
-rw-r--r-- | firmware/export/config-player.h | 2 | ||||
-rw-r--r-- | firmware/export/id3.h | 1 | ||||
-rw-r--r-- | firmware/id3.c | 3 | ||||
-rw-r--r-- | firmware/target/arm/iriver/h10/lcd-h10_5gb.c | 114 | ||||
-rw-r--r-- | firmware/target/coldfire/iaudio/lcd-remote-iaudio.c | 125 | ||||
-rw-r--r-- | firmware/target/coldfire/iaudio/m3/button-m3.c | 2 | ||||
-rw-r--r-- | firmware/target/coldfire/iaudio/m3/lcd-m3.c | 303 |
9 files changed, 152 insertions, 401 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index 0a8ac2a8e3..1d60ea1016 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -513,6 +513,7 @@ target/coldfire/iaudio/m3/backlight-m3.c | |||
513 | target/coldfire/iaudio/m3/button-m3.c | 513 | target/coldfire/iaudio/m3/button-m3.c |
514 | target/coldfire/iaudio/m3/fmradio_i2c-m3.c | 514 | target/coldfire/iaudio/m3/fmradio_i2c-m3.c |
515 | target/coldfire/iaudio/m3/lcd-m3.c | 515 | target/coldfire/iaudio/m3/lcd-m3.c |
516 | target/coldfire/iaudio/m3/lcd-as-m3.S | ||
516 | target/coldfire/iaudio/m3/power-m3.c | 517 | target/coldfire/iaudio/m3/power-m3.c |
517 | target/coldfire/iaudio/m3/powermgmt-m3.c | 518 | target/coldfire/iaudio/m3/powermgmt-m3.c |
518 | target/coldfire/iaudio/m3/system-m3.c | 519 | target/coldfire/iaudio/m3/system-m3.c |
diff --git a/firmware/backlight.c b/firmware/backlight.c index 0f66fbf574..4c4471ace6 100644 --- a/firmware/backlight.c +++ b/firmware/backlight.c | |||
@@ -468,7 +468,7 @@ void backlight_thread(void) | |||
468 | lcd_remote_off(); | 468 | lcd_remote_off(); |
469 | break; | 469 | break; |
470 | #elif defined HAVE_REMOTE_LCD_AS_MAIN | 470 | #elif defined HAVE_REMOTE_LCD_AS_MAIN |
471 | case SYS_REMOTE_PLUGGED: | 471 | case SYS_REMOTE_PLUGGED: |
472 | lcd_on(); | 472 | lcd_on(); |
473 | lcd_update(); | 473 | lcd_update(); |
474 | break; | 474 | break; |
diff --git a/firmware/export/config-player.h b/firmware/export/config-player.h index b9e3035951..c69fe8cfcb 100644 --- a/firmware/export/config-player.h +++ b/firmware/export/config-player.h | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | /* Uncomment this if you want to enable ATA power-off control. | 47 | /* Uncomment this if you want to enable ATA power-off control. |
48 | * Attention, some players crash when ATA power-off is enabled! */ | 48 | * Attention, some players crash when ATA power-off is enabled! */ |
49 | //#define HAVE_ATA_POWER_OFF | 49 | #define HAVE_ATA_POWER_OFF |
50 | 50 | ||
51 | /* Define this if you control ata power player style | 51 | /* Define this if you control ata power player style |
52 | (with PB4, new player only) */ | 52 | (with PB4, new player only) */ |
diff --git a/firmware/export/id3.h b/firmware/export/id3.h index bb3b6a6fe5..267f1b4afa 100644 --- a/firmware/export/id3.h +++ b/firmware/export/id3.h | |||
@@ -49,6 +49,7 @@ enum | |||
49 | AFMT_WAVPACK, /* WavPack */ | 49 | AFMT_WAVPACK, /* WavPack */ |
50 | AFMT_ALAC, /* Apple Lossless Audio Codec */ | 50 | AFMT_ALAC, /* Apple Lossless Audio Codec */ |
51 | AFMT_AAC, /* Advanced Audio Coding (AAC) in M4A container */ | 51 | AFMT_AAC, /* Advanced Audio Coding (AAC) in M4A container */ |
52 | AFMT_MOD, /* MOD File Format */ | ||
52 | AFMT_SHN, /* Shorten */ | 53 | AFMT_SHN, /* Shorten */ |
53 | AFMT_SID, /* SID File Format */ | 54 | AFMT_SID, /* SID File Format */ |
54 | AFMT_ADX, /* ADX File Format */ | 55 | AFMT_ADX, /* ADX File Format */ |
diff --git a/firmware/id3.c b/firmware/id3.c index f594528910..87b4ce9d31 100644 --- a/firmware/id3.c +++ b/firmware/id3.c | |||
@@ -90,6 +90,9 @@ const struct afmt_entry audio_formats[AFMT_NUM_CODECS] = | |||
90 | [AFMT_AAC] = | 90 | [AFMT_AAC] = |
91 | AFMT_ENTRY("AAC", "aac", NULL, "mp4\0" ), | 91 | AFMT_ENTRY("AAC", "aac", NULL, "mp4\0" ), |
92 | /* Shorten */ | 92 | /* Shorten */ |
93 | [AFMT_MOD] = | ||
94 | AFMT_ENTRY("MOD", "mod", NULL, "mod\0" ), | ||
95 | /* Shorten */ | ||
93 | [AFMT_SHN] = | 96 | [AFMT_SHN] = |
94 | AFMT_ENTRY("SHN", "shorten", NULL, "shn\0" ), | 97 | AFMT_ENTRY("SHN", "shorten", NULL, "shn\0" ), |
95 | /* SID File Format */ | 98 | /* SID File Format */ |
diff --git a/firmware/target/arm/iriver/h10/lcd-h10_5gb.c b/firmware/target/arm/iriver/h10/lcd-h10_5gb.c index 5b022e09c5..669654f5c3 100644 --- a/firmware/target/arm/iriver/h10/lcd-h10_5gb.c +++ b/firmware/target/arm/iriver/h10/lcd-h10_5gb.c | |||
@@ -108,6 +108,7 @@ void lcd_init_device(void) | |||
108 | { | 108 | { |
109 | CLCD_CLOCK_SRC |= 0xc0000000; /* Set LCD interface clock to PLL */ | 109 | CLCD_CLOCK_SRC |= 0xc0000000; /* Set LCD interface clock to PLL */ |
110 | /* H10 LCD is initialised by the bootloader */ | 110 | /* H10 LCD is initialised by the bootloader */ |
111 | lcd_write_reg(R_ENTRY_MODE, 0x1030); /* BGR =1, ID1 = 1, ID0 = 1 */ | ||
111 | } | 112 | } |
112 | 113 | ||
113 | /*** update functions ***/ | 114 | /*** update functions ***/ |
@@ -275,88 +276,51 @@ void lcd_blit_yuv(unsigned char * const src[3], | |||
275 | 276 | ||
276 | 277 | ||
277 | /* Update a fraction of the display. */ | 278 | /* Update a fraction of the display. */ |
278 | void lcd_update_rect(int x0, int y0, int width, int height) | 279 | void lcd_update_rect(int x, int y, int width, int height) |
279 | { | 280 | { |
280 | int x1, y1; | 281 | const fb_data *addr; |
281 | int newx,newwidth; | 282 | int bytes_to_write; |
282 | unsigned long *addr; | 283 | |
284 | if (x + width >= LCD_WIDTH) | ||
285 | width = LCD_WIDTH - x; | ||
286 | if (y + height >= LCD_HEIGHT) | ||
287 | height = LCD_HEIGHT - y; | ||
288 | |||
289 | if ((width <= 0) || (height <= 0)) | ||
290 | return; /* Nothing left to do. 0 would hang the transfer. */ | ||
291 | |||
292 | /* Ensure x and width are both even, so we can read | ||
293 | * 32-bit aligned data from the framebuffer */ | ||
294 | width = (width + (x & 1) + 1) & ~1; | ||
295 | x &= ~1; | ||
296 | |||
297 | lcd_write_reg(R_VERT_RAM_ADDR_POS, (LCD_HEIGHT-1) << 8); | ||
298 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, ((x + width - 1) << 8) | x); | ||
299 | lcd_write_reg(R_RAM_ADDR_SET, (y << 8) | x); | ||
283 | 300 | ||
284 | /* Ensure x and width are both even - so we can read 32-bit aligned | ||
285 | data from lcd_framebuffer */ | ||
286 | newx=x0&~1; | ||
287 | newwidth=width&~1; | ||
288 | if (newx+newwidth < x0+width) { newwidth+=2; } | ||
289 | x0=newx; width=newwidth; | ||
290 | |||
291 | /* calculate the drawing region */ | ||
292 | y1 = (y0 + height) - 1; /* max vert */ | ||
293 | x1 = (x0 + width) - 1; /* max horiz */ | ||
294 | |||
295 | |||
296 | /* swap max horiz < start horiz */ | ||
297 | if (y1 < y0) { | ||
298 | int t; | ||
299 | t = y0; | ||
300 | y0 = y1; | ||
301 | y1 = t; | ||
302 | } | ||
303 | |||
304 | /* swap max vert < start vert */ | ||
305 | if (x1 < x0) { | ||
306 | int t; | ||
307 | t = x0; | ||
308 | x0 = x1; | ||
309 | x1 = t; | ||
310 | } | ||
311 | |||
312 | /* max horiz << 8 | start horiz */ | ||
313 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (x1 << 8) | x0); | ||
314 | |||
315 | /* max vert << 8 | start vert */ | ||
316 | lcd_write_reg(R_VERT_RAM_ADDR_POS, (y1 << 8) | y0); | ||
317 | |||
318 | /* start vert << 8 | start horiz */ | ||
319 | lcd_write_reg(R_RAM_ADDR_SET, (y0 << 8) | x0); | ||
320 | |||
321 | /* start drawing */ | ||
322 | lcd_send_cmd(R_WRITE_DATA_2_GRAM); | 301 | lcd_send_cmd(R_WRITE_DATA_2_GRAM); |
323 | 302 | ||
324 | addr = (unsigned long*)&lcd_framebuffer[y0][x0]; | 303 | addr = &lcd_framebuffer[y][x]; |
325 | 304 | bytes_to_write = width * height * sizeof(fb_data); | |
326 | while (height > 0) { | 305 | /* must be <= 0x10000, but that's guaranteed on H10. */ |
327 | int c, r; | ||
328 | int h, pixels_to_write; | ||
329 | |||
330 | pixels_to_write = (width * height) * 2; | ||
331 | h = height; | ||
332 | |||
333 | /* calculate how much we can do in one go */ | ||
334 | if (pixels_to_write > 0x10000) { | ||
335 | h = (0x10000/2) / width; | ||
336 | pixels_to_write = (width * h) * 2; | ||
337 | } | ||
338 | |||
339 | LCD2_BLOCK_CTRL = 0x10000080; | ||
340 | LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1); | ||
341 | LCD2_BLOCK_CTRL = 0x34000000; | ||
342 | 306 | ||
343 | /* for each row */ | 307 | LCD2_BLOCK_CTRL = 0x10000080; |
344 | for (r = 0; r < h; r++) { | 308 | LCD2_BLOCK_CONFIG = 0xc0010000 | (bytes_to_write - 1); |
345 | /* for each column */ | 309 | LCD2_BLOCK_CTRL = 0x34000000; |
346 | for (c = 0; c < width; c += 2) { | 310 | |
347 | while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK)); | 311 | do |
348 | 312 | { | |
349 | /* output 2 pixels */ | 313 | int w = width >> 1; |
350 | LCD2_BLOCK_DATA = *addr++; | 314 | do |
351 | } | 315 | { |
352 | addr += (LCD_WIDTH - width)/2; | 316 | while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK)); |
317 | LCD2_BLOCK_DATA = *(unsigned long*)addr; /* output 2 pixels */ | ||
318 | addr += 2; | ||
353 | } | 319 | } |
354 | 320 | while (--w > 0); | |
355 | while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY)); | 321 | addr += LCD_WIDTH - width; |
356 | LCD2_BLOCK_CONFIG = 0; | ||
357 | |||
358 | height -= h; | ||
359 | } | 322 | } |
323 | while (--height > 0); | ||
360 | } | 324 | } |
361 | 325 | ||
362 | /* Update the display. | 326 | /* Update the display. |
diff --git a/firmware/target/coldfire/iaudio/lcd-remote-iaudio.c b/firmware/target/coldfire/iaudio/lcd-remote-iaudio.c index 5a03dc6180..6565d3088d 100644 --- a/firmware/target/coldfire/iaudio/lcd-remote-iaudio.c +++ b/firmware/target/coldfire/iaudio/lcd-remote-iaudio.c | |||
@@ -64,83 +64,106 @@ bool remote_initialized = false; | |||
64 | static inline void _write_byte(unsigned data) | 64 | static inline void _write_byte(unsigned data) |
65 | { | 65 | { |
66 | asm volatile ( | 66 | asm volatile ( |
67 | "move.l (%[gpo0]), %%d0 \n" /* Get current state of data line */ | 67 | "move.w %%sr,%%d2 \n" /* Get current interrupt level */ |
68 | "and.l %[dbit], %%d0 \n" | 68 | "move.w #0x2700,%%sr \n" /* Disable interrupts */ |
69 | |||
70 | "move.l (%[gpo0]), %%d0 \n" /* Get current state of data port */ | ||
71 | "move.l %%d0, %%d1 \n" | ||
72 | "and.l %[dbit], %%d1 \n" /* Check current state of data line */ | ||
69 | "beq.s 1f \n" /* and set it as previous-state bit */ | 73 | "beq.s 1f \n" /* and set it as previous-state bit */ |
70 | "bset #8, %[data] \n" | 74 | "bset #8, %[data] \n" |
71 | "1: \n" | 75 | "1: \n" |
72 | "move.l %[data], %%d0 \n" /* Compute the 'bit derivative', i.e. a value */ | 76 | "move.l %[data], %%d1 \n" /* Compute the 'bit derivative', i.e. a value */ |
73 | "lsr.l #1, %%d0 \n" /* with 1's where the data changes from the */ | 77 | "lsr.l #1, %%d1 \n" /* with 1's where the data changes from the */ |
74 | "eor.l %%d0, %[data] \n" /* previous state, and 0's where it doesn't */ | 78 | "eor.l %%d1, %[data] \n" /* previous state, and 0's where it doesn't */ |
75 | "swap %[data] \n" /* Shift data to upper byte */ | 79 | "swap %[data] \n" /* Shift data to upper byte */ |
76 | "lsl.l #8, %[data] \n" | 80 | "lsl.l #8, %[data] \n" |
77 | 81 | ||
78 | "move.l %[cbit], %%d1 \n" /* Prepare mask for flipping CLK */ | 82 | "eor.l %[cbit], %%d0 \n" /* precalculate opposite state of clock line */ |
79 | "or.l %[dbit], %%d1 \n" /* and DATA at once */ | 83 | |
80 | |||
81 | "lsl.l #1,%[data] \n" /* Shift out MSB */ | 84 | "lsl.l #1,%[data] \n" /* Shift out MSB */ |
82 | "bcc.s 1f \n" | 85 | "bcc.s 1f \n" |
83 | "eor.l %%d1, (%[gpo0]) \n" /* 1: Flip both CLK and DATA */ | 86 | "eor.l %[dbit], %%d0 \n" /* 1: Flip data bit */ |
84 | ".word 0x51fa \n" /* (trapf.w - shadow next insn) */ | ||
85 | "1: \n" | 87 | "1: \n" |
86 | "eor.l %[cbit], (%[gpo0]) \n" /* else flip CLK only */ | 88 | "move.l %%d0, %%d1 \n" |
87 | "eor.l %[cbit], (%[gpo0]) \n" /* Flip CLK again */ | 89 | "move.l %%d0, (%[gpo0]) \n" /* Output new state and set CLK = 0*/ |
90 | "eor.l %[cbit], %%d1 \n" | ||
91 | "nop \n" | ||
88 | 92 | ||
89 | "lsl.l #1,%[data] \n" /* ..unrolled.. */ | 93 | "lsl.l #1,%[data] \n" /* ..unrolled.. */ |
90 | "bcc.s 1f \n" | 94 | "bcc.s 1f \n" |
91 | "eor.l %%d1, (%[gpo0]) \n" | 95 | "eor.l %[dbit], %%d0 \n" |
92 | ".word 0x51fa \n" | ||
93 | "1: \n" | 96 | "1: \n" |
94 | "eor.l %[cbit], (%[gpo0]) \n" | 97 | "move.l %%d1, (%[gpo0]) \n" /* set CLK = 1 (delayed) */ |
95 | "eor.l %[cbit], (%[gpo0]) \n" | 98 | "move.l %%d0, %%d1 \n" |
99 | "move.l %%d0, (%[gpo0]) \n" | ||
100 | "eor.l %[cbit], %%d1 \n" | ||
101 | "nop \n" | ||
96 | 102 | ||
97 | "lsl.l #1,%[data] \n" | 103 | "lsl.l #1,%[data] \n" /* ..unrolled.. */ |
98 | "bcc.s 1f \n" | 104 | "bcc.s 1f \n" |
99 | "eor.l %%d1, (%[gpo0]) \n" | 105 | "eor.l %[dbit], %%d0 \n" |
100 | ".word 0x51fa \n" | ||
101 | "1: \n" | 106 | "1: \n" |
102 | "eor.l %[cbit], (%[gpo0]) \n" | 107 | "move.l %%d1, (%[gpo0]) \n" |
103 | "eor.l %[cbit], (%[gpo0]) \n" | 108 | "move.l %%d0, %%d1 \n" |
109 | "move.l %%d0, (%[gpo0]) \n" | ||
110 | "eor.l %[cbit], %%d1 \n" | ||
111 | "nop \n" | ||
104 | 112 | ||
105 | "lsl.l #1,%[data] \n" | 113 | "lsl.l #1,%[data] \n" /* ..unrolled.. */ |
106 | "bcc.s 1f \n" | 114 | "bcc.s 1f \n" |
107 | "eor.l %%d1, (%[gpo0]) \n" | 115 | "eor.l %[dbit], %%d0 \n" |
108 | ".word 0x51fa \n" | ||
109 | "1: \n" | 116 | "1: \n" |
110 | "eor.l %[cbit], (%[gpo0]) \n" | 117 | "move.l %%d1, (%[gpo0]) \n" |
111 | "eor.l %[cbit], (%[gpo0]) \n" | 118 | "move.l %%d0, %%d1 \n" |
119 | "move.l %%d0, (%[gpo0]) \n" | ||
120 | "eor.l %[cbit], %%d1 \n" | ||
121 | "nop \n" | ||
112 | 122 | ||
113 | "lsl.l #1,%[data] \n" | 123 | "lsl.l #1,%[data] \n" /* ..unrolled.. */ |
114 | "bcc.s 1f \n" | 124 | "bcc.s 1f \n" |
115 | "eor.l %%d1, (%[gpo0]) \n" | 125 | "eor.l %[dbit], %%d0 \n" |
116 | ".word 0x51fa \n" | ||
117 | "1: \n" | 126 | "1: \n" |
118 | "eor.l %[cbit], (%[gpo0]) \n" | 127 | "move.l %%d1, (%[gpo0]) \n" |
119 | "eor.l %[cbit], (%[gpo0]) \n" | 128 | "move.l %%d0, %%d1 \n" |
129 | "move.l %%d0, (%[gpo0]) \n" | ||
130 | "eor.l %[cbit], %%d1 \n" | ||
131 | "nop \n" | ||
120 | 132 | ||
121 | "lsl.l #1,%[data] \n" | 133 | "lsl.l #1,%[data] \n" /* ..unrolled.. */ |
122 | "bcc.s 1f \n" | 134 | "bcc.s 1f \n" |
123 | "eor.l %%d1, (%[gpo0]) \n" | 135 | "eor.l %[dbit], %%d0 \n" |
124 | ".word 0x51fa \n" | ||
125 | "1: \n" | 136 | "1: \n" |
126 | "eor.l %[cbit], (%[gpo0]) \n" | 137 | "move.l %%d1, (%[gpo0]) \n" |
127 | "eor.l %[cbit], (%[gpo0]) \n" | 138 | "move.l %%d0, %%d1 \n" |
139 | "move.l %%d0, (%[gpo0]) \n" | ||
140 | "eor.l %[cbit], %%d1 \n" | ||
141 | "nop \n" | ||
128 | 142 | ||
129 | "lsl.l #1,%[data] \n" | 143 | "lsl.l #1,%[data] \n" /* ..unrolled.. */ |
130 | "bcc.s 1f \n" | 144 | "bcc.s 1f \n" |
131 | "eor.l %%d1, (%[gpo0]) \n" | 145 | "eor.l %[dbit], %%d0 \n" |
132 | ".word 0x51fa \n" | ||
133 | "1: \n" | 146 | "1: \n" |
134 | "eor.l %[cbit], (%[gpo0]) \n" | 147 | "move.l %%d1, (%[gpo0]) \n" |
135 | "eor.l %[cbit], (%[gpo0]) \n" | 148 | "move.l %%d0, %%d1 \n" |
149 | "move.l %%d0, (%[gpo0]) \n" | ||
150 | "eor.l %[cbit], %%d1 \n" | ||
151 | "nop \n" | ||
136 | 152 | ||
137 | "lsl.l #1,%[data] \n" | 153 | "lsl.l #1,%[data] \n" /* ..unrolled.. */ |
138 | "bcc.s 1f \n" | 154 | "bcc.s 1f \n" |
139 | "eor.l %%d1, (%[gpo0]) \n" | 155 | "eor.l %[dbit], %%d0 \n" |
140 | ".word 0x51fa \n" | ||
141 | "1: \n" | 156 | "1: \n" |
142 | "eor.l %[cbit], (%[gpo0]) \n" | 157 | "move.l %%d1, (%[gpo0]) \n" |
143 | "eor.l %[cbit], (%[gpo0]) \n" | 158 | "move.l %%d0, %%d1 \n" |
159 | "move.l %%d0, (%[gpo0]) \n" | ||
160 | "eor.l %[cbit], %%d1 \n" | ||
161 | "nop \n" | ||
162 | |||
163 | "nop \n" | ||
164 | "move.l %%d1, (%[gpo0]) \n" /* set CLK = 1 (delayed) */ | ||
165 | |||
166 | "move.w %%d2, %%sr \n" /* Restore interrupt level */ | ||
144 | : /* outputs */ | 167 | : /* outputs */ |
145 | [data]"+d"(data) | 168 | [data]"+d"(data) |
146 | : /* inputs */ | 169 | : /* inputs */ |
@@ -148,7 +171,7 @@ static inline void _write_byte(unsigned data) | |||
148 | [cbit]"d"(0x00004000), | 171 | [cbit]"d"(0x00004000), |
149 | [dbit]"d"(0x00002000) | 172 | [dbit]"d"(0x00002000) |
150 | : /* clobbers */ | 173 | : /* clobbers */ |
151 | "d0", "d1" | 174 | "d0", "d1", "d2" |
152 | ); | 175 | ); |
153 | } | 176 | } |
154 | 177 | ||
@@ -157,7 +180,7 @@ static inline void _write_byte(unsigned data) | |||
157 | static inline void _write_fast(unsigned data) | 180 | static inline void _write_fast(unsigned data) |
158 | { | 181 | { |
159 | asm volatile ( | 182 | asm volatile ( |
160 | "move.w %%sr,%%d3 \n" /* Get current interrupt level */ | 183 | "move.w %%sr,%%d2 \n" /* Get current interrupt level */ |
161 | "move.w #0x2700,%%sr \n" /* Disable interrupts */ | 184 | "move.w #0x2700,%%sr \n" /* Disable interrupts */ |
162 | 185 | ||
163 | "move.l (%[gpo0]), %%d0 \n" /* Get current state of data port */ | 186 | "move.l (%[gpo0]), %%d0 \n" /* Get current state of data port */ |
@@ -239,7 +262,7 @@ static inline void _write_fast(unsigned data) | |||
239 | "move.l %%d1, (%[gpo0]) \n" | 262 | "move.l %%d1, (%[gpo0]) \n" |
240 | "move.l %%d0, (%[gpo0]) \n" | 263 | "move.l %%d0, (%[gpo0]) \n" |
241 | 264 | ||
242 | "move.w %%d3, %%sr \n" /* Restore interrupt level */ | 265 | "move.w %%d2, %%sr \n" /* Restore interrupt level */ |
243 | : /* outputs */ | 266 | : /* outputs */ |
244 | [data]"+d"(data) | 267 | [data]"+d"(data) |
245 | : /* inputs */ | 268 | : /* inputs */ |
@@ -247,7 +270,7 @@ static inline void _write_fast(unsigned data) | |||
247 | [cbit]"d"(0x00004000), | 270 | [cbit]"d"(0x00004000), |
248 | [dbit]"d"(0x00002000) | 271 | [dbit]"d"(0x00002000) |
249 | : /* clobbers */ | 272 | : /* clobbers */ |
250 | "d0", "d1", "d2", "d3" | 273 | "d0", "d1", "d2" |
251 | ); | 274 | ); |
252 | } | 275 | } |
253 | 276 | ||
diff --git a/firmware/target/coldfire/iaudio/m3/button-m3.c b/firmware/target/coldfire/iaudio/m3/button-m3.c index ecea221a4c..f5d4b59363 100644 --- a/firmware/target/coldfire/iaudio/m3/button-m3.c +++ b/firmware/target/coldfire/iaudio/m3/button-m3.c | |||
@@ -116,7 +116,7 @@ int button_read_device(void) | |||
116 | else | 116 | else |
117 | btn |= BUTTON_RC_VOL_DOWN; | 117 | btn |= BUTTON_RC_VOL_DOWN; |
118 | } | 118 | } |
119 | if ((GPIO_READ & 0x80000000) == 0) | 119 | if ((GPIO_READ & 0x80000000) == 0) |
120 | btn |= BUTTON_RC_PLAY; | 120 | btn |= BUTTON_RC_PLAY; |
121 | } | 121 | } |
122 | 122 | ||
diff --git a/firmware/target/coldfire/iaudio/m3/lcd-m3.c b/firmware/target/coldfire/iaudio/m3/lcd-m3.c index ae72832a82..4bc22380f5 100644 --- a/firmware/target/coldfire/iaudio/m3/lcd-m3.c +++ b/firmware/target/coldfire/iaudio/m3/lcd-m3.c | |||
@@ -61,263 +61,6 @@ static int cached_contrast = DEFAULT_CONTRAST_SETTING; | |||
61 | bool initialized = false; | 61 | bool initialized = false; |
62 | 62 | ||
63 | 63 | ||
64 | /* Standard low-level byte writer. Requires CLK high on entry */ | ||
65 | static inline void _write_byte(unsigned data) | ||
66 | { | ||
67 | asm volatile ( | ||
68 | "move.l (%[gpo0]), %%d0 \n" /* Get current state of data line */ | ||
69 | "and.l %[dbit], %%d0 \n" | ||
70 | "beq.s 1f \n" /* and set it as previous-state bit */ | ||
71 | "bset #8, %[data] \n" | ||
72 | "1: \n" | ||
73 | "move.l %[data], %%d0 \n" /* Compute the 'bit derivative', i.e. a value */ | ||
74 | "lsr.l #1, %%d0 \n" /* with 1's where the data changes from the */ | ||
75 | "eor.l %%d0, %[data] \n" /* previous state, and 0's where it doesn't */ | ||
76 | "swap %[data] \n" /* Shift data to upper byte */ | ||
77 | "lsl.l #8, %[data] \n" | ||
78 | |||
79 | "move.l %[cbit], %%d1 \n" /* Prepare mask for flipping CLK */ | ||
80 | "or.l %[dbit], %%d1 \n" /* and DATA at once */ | ||
81 | |||
82 | "lsl.l #1,%[data] \n" /* Shift out MSB */ | ||
83 | "bcc.s 1f \n" | ||
84 | "eor.l %%d1, (%[gpo0]) \n" /* 1: Flip both CLK and DATA */ | ||
85 | ".word 0x51fa \n" /* (trapf.w - shadow next insn) */ | ||
86 | "1: \n" | ||
87 | "eor.l %[cbit], (%[gpo0]) \n" /* else flip CLK only */ | ||
88 | "eor.l %[cbit], (%[gpo0]) \n" /* Flip CLK again */ | ||
89 | |||
90 | "lsl.l #1,%[data] \n" /* ..unrolled.. */ | ||
91 | "bcc.s 1f \n" | ||
92 | "eor.l %%d1, (%[gpo0]) \n" | ||
93 | ".word 0x51fa \n" | ||
94 | "1: \n" | ||
95 | "eor.l %[cbit], (%[gpo0]) \n" | ||
96 | "eor.l %[cbit], (%[gpo0]) \n" | ||
97 | |||
98 | "lsl.l #1,%[data] \n" | ||
99 | "bcc.s 1f \n" | ||
100 | "eor.l %%d1, (%[gpo0]) \n" | ||
101 | ".word 0x51fa \n" | ||
102 | "1: \n" | ||
103 | "eor.l %[cbit], (%[gpo0]) \n" | ||
104 | "eor.l %[cbit], (%[gpo0]) \n" | ||
105 | |||
106 | "lsl.l #1,%[data] \n" | ||
107 | "bcc.s 1f \n" | ||
108 | "eor.l %%d1, (%[gpo0]) \n" | ||
109 | ".word 0x51fa \n" | ||
110 | "1: \n" | ||
111 | "eor.l %[cbit], (%[gpo0]) \n" | ||
112 | "eor.l %[cbit], (%[gpo0]) \n" | ||
113 | |||
114 | "lsl.l #1,%[data] \n" | ||
115 | "bcc.s 1f \n" | ||
116 | "eor.l %%d1, (%[gpo0]) \n" | ||
117 | ".word 0x51fa \n" | ||
118 | "1: \n" | ||
119 | "eor.l %[cbit], (%[gpo0]) \n" | ||
120 | "eor.l %[cbit], (%[gpo0]) \n" | ||
121 | |||
122 | "lsl.l #1,%[data] \n" | ||
123 | "bcc.s 1f \n" | ||
124 | "eor.l %%d1, (%[gpo0]) \n" | ||
125 | ".word 0x51fa \n" | ||
126 | "1: \n" | ||
127 | "eor.l %[cbit], (%[gpo0]) \n" | ||
128 | "eor.l %[cbit], (%[gpo0]) \n" | ||
129 | |||
130 | "lsl.l #1,%[data] \n" | ||
131 | "bcc.s 1f \n" | ||
132 | "eor.l %%d1, (%[gpo0]) \n" | ||
133 | ".word 0x51fa \n" | ||
134 | "1: \n" | ||
135 | "eor.l %[cbit], (%[gpo0]) \n" | ||
136 | "eor.l %[cbit], (%[gpo0]) \n" | ||
137 | |||
138 | "lsl.l #1,%[data] \n" | ||
139 | "bcc.s 1f \n" | ||
140 | "eor.l %%d1, (%[gpo0]) \n" | ||
141 | ".word 0x51fa \n" | ||
142 | "1: \n" | ||
143 | "eor.l %[cbit], (%[gpo0]) \n" | ||
144 | "eor.l %[cbit], (%[gpo0]) \n" | ||
145 | : /* outputs */ | ||
146 | [data]"+d"(data) | ||
147 | : /* inputs */ | ||
148 | [gpo0]"a"(&GPIO_OUT), | ||
149 | [cbit]"d"(0x20000000), | ||
150 | [dbit]"d"(0x04000000) | ||
151 | : /* clobbers */ | ||
152 | "d0", "d1" | ||
153 | ); | ||
154 | } | ||
155 | |||
156 | /* Fast low-level byte writer. Don't use with high CPU clock. | ||
157 | * Requires CLK high on entry */ | ||
158 | static inline void _write_fast(unsigned data) | ||
159 | { | ||
160 | asm volatile ( | ||
161 | "move.w %%sr,%%d3 \n" /* Get current interrupt level */ | ||
162 | "move.w #0x2700,%%sr \n" /* Disable interrupts */ | ||
163 | |||
164 | "move.l (%[gpo0]), %%d0 \n" /* Get current state of data port */ | ||
165 | "move.l %%d0, %%d1 \n" | ||
166 | "and.l %[dbit], %%d1 \n" /* Check current state of data line */ | ||
167 | "beq.s 1f \n" /* and set it as previous-state bit */ | ||
168 | "bset #8, %[data] \n" | ||
169 | "1: \n" | ||
170 | "move.l %[data], %%d1 \n" /* Compute the 'bit derivative', i.e. a value */ | ||
171 | "lsr.l #1, %%d1 \n" /* with 1's where the data changes from the */ | ||
172 | "eor.l %%d1, %[data] \n" /* previous state, and 0's where it doesn't */ | ||
173 | "swap %[data] \n" /* Shift data to upper byte */ | ||
174 | "lsl.l #8, %[data] \n" | ||
175 | |||
176 | "move.l %%d0, %%d1 \n" /* precalculate opposite state of clock line */ | ||
177 | "eor.l %[cbit], %%d1 \n" | ||
178 | |||
179 | "lsl.l #1,%[data] \n" /* Shift out MSB */ | ||
180 | "bcc.s 1f \n" | ||
181 | "eor.l %[dbit], %%d0 \n" /* 1: Flip data bit */ | ||
182 | "eor.l %[dbit], %%d1 \n" /* for both clock states */ | ||
183 | "1: \n" | ||
184 | "move.l %%d1, (%[gpo0]) \n" /* Output new state and set CLK */ | ||
185 | "move.l %%d0, (%[gpo0]) \n" /* reset CLK */ | ||
186 | |||
187 | "lsl.l #1,%[data] \n" /* ..unrolled.. */ | ||
188 | "bcc.s 1f \n" | ||
189 | "eor.l %[dbit], %%d0 \n" | ||
190 | "eor.l %[dbit], %%d1 \n" | ||
191 | "1: \n" | ||
192 | "move.l %%d1, (%[gpo0]) \n" | ||
193 | "move.l %%d0, (%[gpo0]) \n" | ||
194 | |||
195 | "lsl.l #1,%[data] \n" | ||
196 | "bcc.s 1f \n" | ||
197 | "eor.l %[dbit], %%d0 \n" | ||
198 | "eor.l %[dbit], %%d1 \n" | ||
199 | "1: \n" | ||
200 | "move.l %%d1, (%[gpo0]) \n" | ||
201 | "move.l %%d0, (%[gpo0]) \n" | ||
202 | |||
203 | "lsl.l #1,%[data] \n" | ||
204 | "bcc.s 1f \n" | ||
205 | "eor.l %[dbit], %%d0 \n" | ||
206 | "eor.l %[dbit], %%d1 \n" | ||
207 | "1: \n" | ||
208 | "move.l %%d1, (%[gpo0]) \n" | ||
209 | "move.l %%d0, (%[gpo0]) \n" | ||
210 | |||
211 | "lsl.l #1,%[data] \n" | ||
212 | "bcc.s 1f \n" | ||
213 | "eor.l %[dbit], %%d0 \n" | ||
214 | "eor.l %[dbit], %%d1 \n" | ||
215 | "1: \n" | ||
216 | "move.l %%d1, (%[gpo0]) \n" | ||
217 | "move.l %%d0, (%[gpo0]) \n" | ||
218 | |||
219 | "lsl.l #1,%[data] \n" | ||
220 | "bcc.s 1f \n" | ||
221 | "eor.l %[dbit], %%d0 \n" | ||
222 | "eor.l %[dbit], %%d1 \n" | ||
223 | "1: \n" | ||
224 | "move.l %%d1, (%[gpo0]) \n" | ||
225 | "move.l %%d0, (%[gpo0]) \n" | ||
226 | |||
227 | "lsl.l #1,%[data] \n" | ||
228 | "bcc.s 1f \n" | ||
229 | "eor.l %[dbit], %%d0 \n" | ||
230 | "eor.l %[dbit], %%d1 \n" | ||
231 | "1: \n" | ||
232 | "move.l %%d1, (%[gpo0]) \n" | ||
233 | "move.l %%d0, (%[gpo0]) \n" | ||
234 | |||
235 | "lsl.l #1,%[data] \n" | ||
236 | "bcc.s 1f \n" | ||
237 | "eor.l %[dbit], %%d0 \n" | ||
238 | "eor.l %[dbit], %%d1 \n" | ||
239 | "1: \n" | ||
240 | "move.l %%d1, (%[gpo0]) \n" | ||
241 | "move.l %%d0, (%[gpo0]) \n" | ||
242 | |||
243 | "move.w %%d3, %%sr \n" /* Restore interrupt level */ | ||
244 | : /* outputs */ | ||
245 | [data]"+d"(data) | ||
246 | : /* inputs */ | ||
247 | [gpo0]"a"(&GPIO_OUT), | ||
248 | [cbit]"d"(0x20000000), | ||
249 | [dbit]"d"(0x04000000) | ||
250 | : /* clobbers */ | ||
251 | "d0", "d1", "d2", "d3" | ||
252 | ); | ||
253 | } | ||
254 | |||
255 | void lcd_write_command(int cmd) | ||
256 | { | ||
257 | RS_LO; | ||
258 | CS_LO; | ||
259 | _write_byte(cmd); | ||
260 | CS_HI; | ||
261 | } | ||
262 | |||
263 | void lcd_write_command_e(int cmd, int data) | ||
264 | { | ||
265 | RS_LO; | ||
266 | CS_LO; | ||
267 | _write_byte(cmd); | ||
268 | _write_byte(data); | ||
269 | CS_HI; | ||
270 | } | ||
271 | |||
272 | void lcd_write_data(const fb_data *p_words, int count) | ||
273 | { | ||
274 | const unsigned char *p_bytes = (const unsigned char *)p_words; | ||
275 | const unsigned char *p_end = (const unsigned char *)(p_words + count); | ||
276 | |||
277 | RS_HI; | ||
278 | CS_LO; | ||
279 | if (cpu_frequency < 50000000) | ||
280 | { | ||
281 | while (p_bytes < p_end) | ||
282 | _write_fast(*p_bytes++); | ||
283 | } | ||
284 | else | ||
285 | { | ||
286 | while (p_bytes < p_end) | ||
287 | _write_byte(*p_bytes++); | ||
288 | } | ||
289 | CS_HI; | ||
290 | } | ||
291 | |||
292 | static void lcd_mono_data(const unsigned char *p_words, int count) | ||
293 | { | ||
294 | unsigned data; | ||
295 | const unsigned char *p_bytes = p_words; | ||
296 | const unsigned char *p_end = p_words + count; | ||
297 | |||
298 | RS_HI; | ||
299 | CS_LO; | ||
300 | if (cpu_frequency < 50000000) | ||
301 | { | ||
302 | while (p_bytes < p_end) | ||
303 | { | ||
304 | data = *p_bytes++; | ||
305 | _write_fast(data); | ||
306 | _write_fast(data); | ||
307 | } | ||
308 | } | ||
309 | else | ||
310 | { | ||
311 | while (p_bytes < p_end) | ||
312 | { | ||
313 | data = *p_bytes++; | ||
314 | _write_byte(data); | ||
315 | _write_byte(data); | ||
316 | } | ||
317 | } | ||
318 | CS_HI; | ||
319 | } | ||
320 | |||
321 | int lcd_default_contrast(void) | 64 | int lcd_default_contrast(void) |
322 | { | 65 | { |
323 | return DEFAULT_CONTRAST_SETTING; | 66 | return DEFAULT_CONTRAST_SETTING; |
@@ -457,6 +200,9 @@ void lcd_init_device(void) | |||
457 | #endif | 200 | #endif |
458 | } | 201 | } |
459 | 202 | ||
203 | /* Helper function. */ | ||
204 | void lcd_mono_data(const unsigned char *data, int count); | ||
205 | |||
460 | /* Performance function that works with an external buffer | 206 | /* Performance function that works with an external buffer |
461 | note that by and bheight are in 8-pixel units! */ | 207 | note that by and bheight are in 8-pixel units! */ |
462 | void lcd_blit_mono(const unsigned char *data, int x, int by, int width, | 208 | void lcd_blit_mono(const unsigned char *data, int x, int by, int width, |
@@ -477,20 +223,28 @@ void lcd_blit_mono(const unsigned char *data, int x, int by, int width, | |||
477 | } | 223 | } |
478 | } | 224 | } |
479 | 225 | ||
480 | /* TODO: implement grey blit function */ | 226 | /* Helper function for lcd_grey_phase_blit(). */ |
227 | void lcd_grey_data(unsigned char *values, unsigned char *phases, int count); | ||
481 | 228 | ||
482 | /* Performance function that works with an external buffer | 229 | /* Performance function that works with an external buffer |
483 | note that by and bheight are in 8-pixel units! */ | 230 | note that by and bheight are in 8-pixel units! */ |
484 | void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases, | 231 | void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases, |
485 | int x, int by, int width, int bheight, int stride) | 232 | int x, int by, int width, int bheight, int stride) |
486 | { | 233 | { |
487 | (void)values; | 234 | if (initialized) |
488 | (void)phases; | 235 | { |
489 | (void)x; | 236 | stride <<= 3; /* 8 pixels per block */ |
490 | (void)by; | 237 | while (bheight--) |
491 | (void)width; | 238 | { |
492 | (void)bheight; | 239 | lcd_write_command(LCD_SET_PAGE | ((by > 5 ? by + 2 : by) & 0xf)); |
493 | (void)stride; | 240 | lcd_write_command_e(LCD_SET_COLUMN | ((x >> 4) & 0xf), x & 0xf); |
241 | |||
242 | lcd_grey_data(values, phases, width); | ||
243 | values += stride; | ||
244 | phases += stride; | ||
245 | by++; | ||
246 | } | ||
247 | } | ||
494 | } | 248 | } |
495 | 249 | ||
496 | /* Update the display. | 250 | /* Update the display. |
@@ -501,12 +255,13 @@ void lcd_update(void) | |||
501 | int y; | 255 | int y; |
502 | if (initialized) | 256 | if (initialized) |
503 | { | 257 | { |
504 | for(y = 0;y < LCD_FBHEIGHT;y++) { | 258 | for(y = 0;y < LCD_FBHEIGHT;y++) |
259 | { | ||
505 | /* Copy display bitmap to hardware. | 260 | /* Copy display bitmap to hardware. |
506 | The COM48-COM63 lines are not connected so we have to skip | 261 | The COM48-COM63 lines are not connected so we have to skip |
507 | them. Further, the column address doesn't wrap, so we | 262 | them. Further, the column address doesn't wrap, so we |
508 | have to update one page at a time. */ | 263 | have to update one page at a time. */ |
509 | lcd_write_command(LCD_SET_PAGE | (y>5?y+2:y)); | 264 | lcd_write_command(LCD_SET_PAGE | (y > 5 ? y + 2 : y)); |
510 | lcd_write_command_e(LCD_SET_COLUMN | 0, 0); | 265 | lcd_write_command_e(LCD_SET_COLUMN | 0, 0); |
511 | lcd_write_data(lcd_framebuffer[y], LCD_WIDTH); | 266 | lcd_write_data(lcd_framebuffer[y], LCD_WIDTH); |
512 | } | 267 | } |
@@ -536,7 +291,7 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
536 | COM48-COM63 are not connected, so we need to skip those */ | 291 | COM48-COM63 are not connected, so we need to skip those */ |
537 | for (; y <= ymax; y++) | 292 | for (; y <= ymax; y++) |
538 | { | 293 | { |
539 | lcd_write_command(LCD_SET_PAGE | ((y > 5?y + 2:y) & 0xf)); | 294 | lcd_write_command(LCD_SET_PAGE | ((y > 5 ? y + 2 : y) & 0xf)); |
540 | lcd_write_command_e(LCD_SET_COLUMN | ((x >> 4) & 0xf), x & 0xf); | 295 | lcd_write_command_e(LCD_SET_COLUMN | ((x >> 4) & 0xf), x & 0xf); |
541 | 296 | ||
542 | lcd_write_data(&lcd_framebuffer[y][x], width); | 297 | lcd_write_data(&lcd_framebuffer[y][x], width); |
@@ -547,19 +302,23 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
547 | void lcd_set_invert_display(bool yesno) | 302 | void lcd_set_invert_display(bool yesno) |
548 | { | 303 | { |
549 | cached_invert = yesno; | 304 | cached_invert = yesno; |
550 | if(initialized) | 305 | if (initialized) |
551 | lcd_write_command(LCD_REVERSE | yesno); | 306 | lcd_write_command(LCD_REVERSE | yesno); |
552 | } | 307 | } |
553 | 308 | ||
554 | void lcd_set_flip(bool yesno) | 309 | void lcd_set_flip(bool yesno) |
555 | { | 310 | { |
556 | cached_flip = yesno; | 311 | cached_flip = yesno; |
557 | if(initialized) { | 312 | if (initialized) |
558 | if(yesno) { | 313 | { |
314 | if(yesno) | ||
315 | { | ||
559 | lcd_write_command(LCD_SELECT_ADC | 0); | 316 | lcd_write_command(LCD_SELECT_ADC | 0); |
560 | lcd_write_command(LCD_SELECT_SHL | 0); | 317 | lcd_write_command(LCD_SELECT_SHL | 0); |
561 | lcd_write_command_e(LCD_SET_COM0, 16); | 318 | lcd_write_command_e(LCD_SET_COM0, 16); |
562 | } else { | 319 | } |
320 | else | ||
321 | { | ||
563 | lcd_write_command(LCD_SELECT_ADC | 1); | 322 | lcd_write_command(LCD_SELECT_ADC | 1); |
564 | lcd_write_command(LCD_SELECT_SHL | 8); | 323 | lcd_write_command(LCD_SELECT_SHL | 8); |
565 | lcd_write_command_e(LCD_SET_COM0, 0); | 324 | lcd_write_command_e(LCD_SET_COM0, 0); |