fb_support.c
来自「开放源码实时操作系统源码.」· C语言 代码 · 共 681 行 · 第 1/2 页
C
681 行
}
}
static void
lcd_scroll(void)
{
int row, col;
cyg_uint8 *c1, *c2;
// First scroll up the virtual screen
for (row = (screen_start+1); row < screen_height; row++) {
c1 = &screen[row-1][0];
c2 = &screen[row][0];
for (col = 0; col < screen_width; col++) {
*c1++ = *c2++;
}
}
c1 = &screen[screen_height-1][0];
for (col = 0; col < screen_width; col++) {
*c1++ = 0x20;
}
lcd_refresh();
}
// Draw one character at the current position
void
lcd_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);
}
}
void
lcd_setbg(int red, int green, int blue)
{
bg = RGB_RED(red) | RGB_GREEN(green) | RGB_BLUE(blue);
}
void
lcd_setfg(int red, int green, int blue)
{
fg = RGB_RED(red) | RGB_GREEN(green) | RGB_BLUE(blue);
}
static int _timeout = 500;
static int
_hexdigit(char c)
{
if ((c >= '0') && (c <= '9')) {
return c - '0';
} else
if ((c >= 'A') && (c <= 'F')) {
return (c - 'A') + 0x0A;
} else
if ((c >= 'a') && (c <= 'f')) {
return (c - 'a') + 0x0a;
}
}
static int
_hex(char *cp)
{
return (_hexdigit(*cp)<<4) | _hexdigit(*(cp+1));
}
static unsigned short
parse_color(char *cp)
{
int red, green, blue;
while (*cp && (*cp != 'c')) cp++;
if (cp) {
cp += 2;
if (*cp == '#') {
red = _hex(cp+1);
green = _hex(cp+3);
blue = _hex(cp+5);
#ifdef USE_RGB565
return RGB_RED(red>>3) | RGB_GREEN(green>>2) | RGB_BLUE(blue>>3);
#else
return RGB_RED(red>>3) | RGB_GREEN(green>>3) | RGB_BLUE(blue>>3);
#endif
} else {
// Should be "None"
return 0xFFFF;
}
} else {
return 0xFFFF;
}
}
#ifndef CYGINT_ISO_STDIO_FORMATTED_IO
static int
get_int(char **_cp)
{
char *cp = *_cp;
char c;
int val = 0;
while ((c = *cp++) && (c != ' ')) {
if ((c >= '0') && (c <= '9')) {
val = val * 10 + (c - '0');
} else {
return -1;
}
}
*_cp = cp;
return val;
}
#endif
int
show_xpm(char *xpm[], int screen_pos)
{
int i, row, col, offset;
char *cp;
int nrows, ncols, nclrs;
unsigned short colors[256]; // Mapped by character index
cp = xpm[0];
#ifdef CYGINT_ISO_STDIO_FORMATTED_IO
if (sscanf(cp, "%d %d %d", &ncols, &nrows, &nclrs) != 3) {
#else
if (((ncols = get_int(&cp)) < 0) ||
((nrows = get_int(&cp)) < 0) ||
((nclrs = get_int(&cp)) < 0)) {
#endif
diag_printf("Can't parse XPM data, sorry\n");
return 0;
}
// printf("%d rows, %d cols, %d colors\n", nrows, ncols, nclrs);
for (i = 0; i < 256; i++) {
colors[i] = 0x0000;
}
for (i = 0; i < nclrs; i++) {
cp = xpm[i+1];
colors[(unsigned int)*cp] = parse_color(&cp[1]);
// printf("Color[%c] = %x\n", *cp, colors[(unsigned int)*cp]);
}
#ifdef LOGO_AT_TOP
offset = screen_pos;
#else
offset = screen_pos-nrows;
#endif
for (row = 0; row < nrows; row++) {
cp = xpm[nclrs+1+row];
for (col = 0; col < ncols; col++) {
set_pixel(row+offset, col, colors[(unsigned int)*cp++]);
}
}
#ifdef LOGO_AT_TOP
screen_start = (nrows + (FONT_HEIGHT-1))/FONT_HEIGHT;
return offset+nrows;
#else
screen_height = offset / FONT_HEIGHT;
return offset;
#endif
}
void fb_init(int depth)
{
int cable = dcfb_cable_check();
unsigned long **parm_list[4] = {
dc_parm_vga, dc_parm_vga, dc_parm_interlace, dc_parm_composite,
};
unsigned long **dc_parms = parm_list[cable];
unsigned long a, d, *p;
switch(depth) {
default:
case 16:
p = dc_parms[0];
break;
case 32:
p = dc_parms[1];
break;
}
HAL_WRITE_UINT32(RESETREG, 0);
HAL_WRITE_UINT32(BORDERRGB, 0);
while(1) {
a = *p++; d = *p++;
if (!a) break;
HAL_WRITE_UINT32(a, d);
}
lcd_clear();
}
static cyg_bool
lcd_comm_getc_nonblock(void* __ch_data, cyg_uint8* ch)
{
return false;
}
static cyg_uint8
lcd_comm_getc(void* __ch_data)
{
cyg_uint8 ch;
while (!lcd_comm_getc_nonblock(__ch_data, &ch)) ;
return ch;
}
static void
lcd_comm_putc(void* __ch_data, cyg_uint8 c)
{
lcd_putc(c);
}
static void
lcd_comm_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len)
{
}
static void
lcd_comm_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
{
}
static cyg_bool
lcd_comm_getc_timeout(void* __ch_data, cyg_uint8* ch)
{
int delay_count;
cyg_bool res;
delay_count = _timeout * 10; // delay in .1 ms steps
for(;;) {
res = lcd_comm_getc_nonblock(__ch_data, ch);
if (res || 0 == delay_count--)
break;
CYGACC_CALL_IF_DELAY_US(100);
}
return res;
}
static int
lcd_comm_control(void *__ch_data, __comm_control_cmd_t __func, ...)
{
int ret = 0;
switch (__func) {
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:
break;
default:
break;
}
return ret;
}
static int
lcd_comm_isr(void *__ch_data, int* __ctrlc,
CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
{
return 0;
}
void fb_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);
// Setup procs in the vector table
CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
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);
init = 1;
}
}
//-----------------------------------------------------------------------------
// End of fb_support.c
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?