📄 lcd_support.c
字号:
set_pixel(yoff, xoff + p, (bits & 0x01) ? fg : bg); bits >>= 1; }#endif }}static voidlcd_refresh(void){ int row, col; for (row = screen_start; row < screen_height; row++) { for (col = 0; col < VISIBLE_SCREEN_WIDTH; col++) { if ((col+screen_pan) < screen_width) { lcd_drawc(screen[row][col+screen_pan], col, row); } else { lcd_drawc(' ', col, row); } } } if (cursor_enable) { lcd_drawc(CURSOR_ON, curX-screen_pan, curY); }}static voidlcd_scroll(void){ int col; cyg_uint8 *c1; cyg_uint32 *lc0, *lc1, *lcn;#ifndef CYGSEM_AAED2000_LCD_PORTRAIT_MODE cyg_uint32 *fb_row0, *fb_row1, *fb_rown;#endif // First scroll up the virtual screen#if ((SCREEN_WIDTH%4) != 0)#error Scroll code optimized for screen with multiple of 4 columns#endif lc0 = (cyg_uint32 *)&screen[0][0]; lc1 = (cyg_uint32 *)&screen[1][0]; lcn = (cyg_uint32 *)&screen[screen_height][0]; while (lc1 != lcn) { *lc0++ = *lc1++; } c1 = &screen[screen_height-1][0]; for (col = 0; col < screen_width; col++) { *c1++ = 0x20; }#ifdef CYGSEM_AAED2000_LCD_PORTRAIT_MODE // Redrawing the screen in this mode is hard :-) lcd_refresh();#else fb_row0 = lcd_fb(screen_start*FONT_HEIGHT, 0); fb_row1 = lcd_fb((screen_start+1)*FONT_HEIGHT, 0); fb_rown = lcd_fb(screen_end*FONT_HEIGHT, 0);#if 1 while (fb_row1 != fb_rown) { *fb_row0++ = *fb_row1++; }#else // Optimized ARM assembly "move" code asm __volatile( "mov r0,%0;" "mov r1,%1;" "mov r2,%2;" "10: ldmia r1!,{r3-r10};" "stmia r0!,{r3-r10};" "cmp r1,r2;" "bne 10b" : : "r"(fb_row0), "r"(fb_row1), "r"(fb_rown) : "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10" );#endif // Erase bottom line for (col = 0; col < screen_width; col++) { lcd_drawc(' ', col, screen_end-1); }#endif}// Draw one character at the current positionvoidlcd_putc(cyg_int8 c){ if (cursor_enable) { lcd_drawc(screen[curY][curX], curX-screen_pan, curY); } switch (c) { case '\r': curX = 0; break; case '\n': curY++; break; case '\b': curX--; if (curX < 0) { curY--; if (curY < 0) curY = 0; curX = screen_width-1; } break; default: if (((cyg_uint8)c < FIRST_CHAR) || ((cyg_uint8)c > LAST_CHAR)) c = '.'; screen[curY][curX] = c; lcd_drawc(c, curX-screen_pan, curY); curX++; if (curX == screen_width) { curY++; curX = 0; } } if (curY >= screen_height) { lcd_scroll(); curY = (screen_height-1); } if (cursor_enable) { lcd_drawc(CURSOR_ON, curX-screen_pan, curY); }}// Basic LCD 'printf()' support#include <stdarg.h>#define is_digit(c) ((c >= '0') && (c <= '9'))static int_cvt(unsigned long val, char *buf, long radix, char *digits){ char temp[80]; char *cp = temp; int length = 0; if (val == 0) { /* Special case */ *cp++ = '0'; } else { while (val) { *cp++ = digits[val % radix]; val /= radix; } } while (cp != temp) { *buf++ = *--cp; length++; } *buf = '\0'; return (length);}static intlcd_vprintf(void (*putc)(cyg_int8), const char *fmt0, va_list ap){ char c, sign, *cp; int left_prec, right_prec, zero_fill, length, pad, pad_on_right; char buf[32]; long val; while ((c = *fmt0++)) { cp = buf; length = 0; if (c == '%') { c = *fmt0++; left_prec = right_prec = pad_on_right = 0; if (c == '-') { c = *fmt0++; pad_on_right++; } if (c == '0') { zero_fill = TRUE; c = *fmt0++; } else { zero_fill = FALSE; } while (is_digit(c)) { left_prec = (left_prec * 10) + (c - '0'); c = *fmt0++; } if (c == '.') { c = *fmt0++; zero_fill++; while (is_digit(c)) { right_prec = (right_prec * 10) + (c - '0'); c = *fmt0++; } } else { right_prec = left_prec; } sign = '\0'; switch (c) { case 'd': case 'x': case 'X': val = va_arg(ap, long); switch (c) { case 'd': if (val < 0) { sign = '-'; val = -val; } length = _cvt(val, buf, 10, "0123456789"); break; case 'x': length = _cvt(val, buf, 16, "0123456789abcdef"); break; case 'X': length = _cvt(val, buf, 16, "0123456789ABCDEF"); break; } break; case 's': cp = va_arg(ap, char *); length = strlen(cp); break; case 'c': c = va_arg(ap, long /*char*/); (*putc)(c); continue; default: (*putc)('?'); } pad = left_prec - length; if (sign != '\0') { pad--; } if (zero_fill) { c = '0'; if (sign != '\0') { (*putc)(sign); sign = '\0'; } } else { c = ' '; } if (!pad_on_right) { while (pad-- > 0) { (*putc)(c); } } if (sign != '\0') { (*putc)(sign); } while (length-- > 0) { (*putc)(c = *cp++); if (c == '\n') { (*putc)('\r'); } } if (pad_on_right) { while (pad-- > 0) { (*putc)(' '); } } } else { (*putc)(c); if (c == '\n') { (*putc)('\r'); } } } // FIXME return 0;}int_lcd_printf(char const *fmt, ...){ int ret; va_list ap; va_start(ap, fmt); ret = lcd_vprintf(lcd_putc, fmt, ap); va_end(ap); return (ret);}voidlcd_setbg(int red, int green, int blue){ bg = RGB_RED(red) | RGB_GREEN(green) | RGB_BLUE(blue);}voidlcd_setfg(int red, int green, int blue){ fg = RGB_RED(red) | RGB_GREEN(green) | RGB_BLUE(blue);}//// Support LCD/keyboard (PS2) as a virtual I/O channel// Adapted from i386/pcmb_screen.c//static int _timeout = 500;static cyg_boollcd_comm_getc_nonblock(void* __ch_data, cyg_uint8* ch){ if( !aaed2000_KeyboardTest() ) return false; *ch = aaed2000_KeyboardGetc(); return true;}static cyg_uint8lcd_comm_getc(void* __ch_data){ cyg_uint8 ch; while (!lcd_comm_getc_nonblock(__ch_data, &ch)) ; return ch;}static voidlcd_comm_putc(void* __ch_data, cyg_uint8 c){ lcd_putc(c);}static voidlcd_comm_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len){#if 0 CYGARC_HAL_SAVE_GP(); while(__len-- > 0) lcd_comm_putc(__ch_data, *__buf++); CYGARC_HAL_RESTORE_GP();#endif}static voidlcd_comm_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len){#if 0 CYGARC_HAL_SAVE_GP(); while(__len-- > 0) *__buf++ = lcd_comm_getc(__ch_data); CYGARC_HAL_RESTORE_GP();#endif}static cyg_boollcd_comm_getc_timeout(void* __ch_data, cyg_uint8* ch){ int delay_count; cyg_bool res; delay_count = _timeout * 2; // delay in .5 ms steps for(;;) { res = lcd_comm_getc_nonblock(__ch_data, ch); if (res || 0 == delay_count--) break; CYGACC_CALL_IF_DELAY_US(500); } return res;}static intlcd_comm_control(void *__ch_data, __comm_control_cmd_t __func, ...){ static int vector = 0; int ret = -1; static int irq_state = 0; CYGARC_HAL_SAVE_GP(); switch (__func) { case __COMMCTL_IRQ_ENABLE: ret = irq_state; irq_state = 1; break; case __COMMCTL_IRQ_DISABLE: ret = irq_state; irq_state = 0; break; case __COMMCTL_DBG_ISR_VECTOR: ret = vector; break; case __COMMCTL_SET_TIMEOUT: { va_list ap; va_start(ap, __func); ret = _timeout; _timeout = va_arg(ap, cyg_uint32); va_end(ap); break; } case __COMMCTL_FLUSH_OUTPUT: ret = 0; break; default: break; } CYGARC_HAL_RESTORE_GP(); return ret;}static intlcd_comm_isr(void *__ch_data, int* __ctrlc, CYG_ADDRWORD __vector, CYG_ADDRWORD __data){#if 0 char ch; cyg_drv_interrupt_acknowledge(__vector); *__ctrlc = 0; if (lcd_comm_getc_nonblock(__ch_data, &ch)) { if (ch == 0x03) { *__ctrlc = 1; } } return CYG_ISR_HANDLED;#else return 0;#endif}voidlcd_comm_init(void){ static int init = 0; if (!init) { hal_virtual_comm_table_t* comm; int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); init = 1; lcd_on(false); if (!aaed2000_KeyboardInit()) { // No keyboard - no LCD display return; } // Initialize screen cursor_enable = true; lcd_init(16); lcd_screen_clear(); // Setup procs in the vector table CYGACC_CALL_IF_SET_CONSOLE_COMM(1); // FIXME - should be controlled by CDL comm = CYGACC_CALL_IF_CONSOLE_PROCS(); //CYGACC_COMM_IF_CH_DATA_SET(*comm, chan); CYGACC_COMM_IF_WRITE_SET(*comm, lcd_comm_write); CYGACC_COMM_IF_READ_SET(*comm, lcd_comm_read); CYGACC_COMM_IF_PUTC_SET(*comm, lcd_comm_putc); CYGACC_COMM_IF_GETC_SET(*comm, lcd_comm_getc); CYGACC_COMM_IF_CONTROL_SET(*comm, lcd_comm_control); CYGACC_COMM_IF_DBG_ISR_SET(*comm, lcd_comm_isr); CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, lcd_comm_getc_timeout); // Restore original console CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); }}#ifdef CYGPKG_REDBOOT#include <redboot.h>// Get here when RedBoot is idle. If it's been long enough, then// dim the LCD. The problem is - how to determine other activities// so at this doesn't get in the way. In the default case, this will// be called from RedBoot every 10ms (CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT)#define MAX_IDLE_TIME (30*100)static voididle(bool is_idle){ static int idle_time = 0; static bool was_idled = false; if (is_idle) { if (!was_idled) { if (++idle_time == MAX_IDLE_TIME) { was_idled = true; lcd_on(false); } } } else { idle_time = 0; if (was_idled) { was_idled = false; lcd_on(true); } }}RedBoot_idle(idle, RedBoot_AFTER_NETIO);#endif#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -