From 152b1e31c3dce8976e7086f257f9334d3ee8bf8f Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Wed, 30 Aug 2000 08:21:24 +0000 Subject: 2000-08-26 Rosimildo da Silva * Added generic Micro FrameBuffer interface for MicroWindows. This interface allows MicroWindows to under RTEMS. A sample driver has been developed for the pc386 BSP. See pc386/fb_vga.c as a sample. * Added Uniform Input Device interface for MicroWindows. See PC386 bsp for sample drivers for mouse and keyboard (console). * mw-bf: New directory. * Makefile.am, configure.in, wrapup/Makefile.am: Account for mw-fb. * mw-fb/Makefile.am: New file. * mw-fb/mw_fb.c: New file. * mw-fb/mw_fb.h: New file. * mw-fb/mw_uid.c: New file. * mw-fb/mw_uid.h: New file. --- c/src/libmisc/ChangeLog | 16 ++++ c/src/libmisc/Makefile.am | 2 +- c/src/libmisc/configure.in | 1 + c/src/libmisc/mw-fb/Makefile.am | 40 ++++++++++ c/src/libmisc/mw-fb/mw_fb.c | 137 ++++++++++++++++++++++++++++++++++ c/src/libmisc/mw-fb/mw_fb.h | 153 ++++++++++++++++++++++++++++++++++++++ c/src/libmisc/mw-fb/mw_uid.c | 157 +++++++++++++++++++++++++++++++++++++++ c/src/libmisc/mw-fb/mw_uid.h | 143 +++++++++++++++++++++++++++++++++++ c/src/libmisc/wrapup/Makefile.am | 2 +- 9 files changed, 649 insertions(+), 2 deletions(-) create mode 100644 c/src/libmisc/mw-fb/Makefile.am create mode 100644 c/src/libmisc/mw-fb/mw_fb.c create mode 100644 c/src/libmisc/mw-fb/mw_fb.h create mode 100644 c/src/libmisc/mw-fb/mw_uid.c create mode 100644 c/src/libmisc/mw-fb/mw_uid.h (limited to 'c') diff --git a/c/src/libmisc/ChangeLog b/c/src/libmisc/ChangeLog index 101734ce64..5a864fd495 100644 --- a/c/src/libmisc/ChangeLog +++ b/c/src/libmisc/ChangeLog @@ -1,3 +1,19 @@ +2000-08-26 Rosimildo da Silva + + * Added generic Micro FrameBuffer interface for MicroWindows. + This interface allows MicroWindows to under RTEMS. A sample + driver has been developed for the pc386 BSP. See + pc386/fb_vga.c as a sample. + * Added Uniform Input Device interface for MicroWindows. + See PC386 bsp for sample drivers for mouse and keyboard (console). + * mw-bf: New directory. + * Makefile.am, configure.in, wrapup/Makefile.am: Account for mw-fb. + * mw-fb/Makefile.am: New file. + * mw-fb/mw_fb.c: New file. + * mw-fb/mw_fb.h: New file. + * mw-fb/mw_uid.c: New file. + * mw-fb/mw_uid.h: New file. + 2000-08-10 Joel Sherrill * ChangeLog: New file. diff --git a/c/src/libmisc/Makefile.am b/c/src/libmisc/Makefile.am index 45cff91454..801d129052 100644 --- a/c/src/libmisc/Makefile.am +++ b/c/src/libmisc/Makefile.am @@ -5,7 +5,7 @@ AUTOMAKE_OPTIONS = foreign 1.4 ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal -SUBDIRS = dummy dumpbuf stackchk monitor cpuuse rtmonuse untar wrapup +SUBDIRS = dummy dumpbuf stackchk monitor cpuuse rtmonuse untar mw-fb wrapup EXTRA_DIST = README diff --git a/c/src/libmisc/configure.in b/c/src/libmisc/configure.in index 13c4a55369..a93ff32c7a 100644 --- a/c/src/libmisc/configure.in +++ b/c/src/libmisc/configure.in @@ -39,5 +39,6 @@ monitor/Makefile rtmonuse/Makefile stackchk/Makefile untar/Makefile +mw-fb/Makefile wrapup/Makefile ) diff --git a/c/src/libmisc/mw-fb/Makefile.am b/c/src/libmisc/mw-fb/Makefile.am new file mode 100644 index 0000000000..51fb22bfe2 --- /dev/null +++ b/c/src/libmisc/mw-fb/Makefile.am @@ -0,0 +1,40 @@ +## +## $Id$ +## + +AUTOMAKE_OPTIONS = foreign 1.4 + +LIBNAME = libmw-fb-tmp +LIB = ${ARCH}/${LIBNAME}.a + +C_FILES = mw_fb.c mw_uid.c +C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o) + +H_FILES = mw_fb.h mw_uid.h +noinst_HEADERS = $(H_FILES) + +SRCS = $(C_FILES) $(H_FILES) +OBJS = $(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../../../automake/lib.am + +PREINSTALL_FILES = $(PROJECT_INCLUDE)/rtems $(H_FILES:%=$(PROJECT_INCLUDE)/rtems/%) + +$(PROJECT_INCLUDE)/rtems: + @$(mkinstalldirs) $@ +$(PROJECT_INCLUDE)/rtems/%.h: %.h + $(INSTALL_DATA) $< $@ + +# +# (OPTIONAL) Add local stuff here using += +# + +${LIB}: ${OBJS} + $(make-library) + +all: ${ARCH} $(PREINSTALL_FILES) $(LIB) $(TMPINSTALL_FILES) + +EXTRA_DIST += $(C_FILES) $(H_FILES) + +include $(top_srcdir)/../../../automake/local.am diff --git a/c/src/libmisc/mw-fb/mw_fb.c b/c/src/libmisc/mw-fb/mw_fb.c new file mode 100644 index 0000000000..c54b113654 --- /dev/null +++ b/c/src/libmisc/mw-fb/mw_fb.c @@ -0,0 +1,137 @@ +/* +///////////////////////////////////////////////////////////////////////////// +// $Header$ +// +// Copyright (c) 2000 - Rosimildo da Silva +// +// MODULE DESCRIPTION: +// Wrapper API around the ioctls calls for the Micro FrameBuffer +// interface for Embedded Systems +// +// All functions returns 0 on success. Any other value should be +// decoded as an error. A list of errors will be created over time. +// +// MODIFICATION/HISTORY: +// +// $Log$ +// +///////////////////////////////////////////////////////////////////////////// +*/ + +#include +#include + + +/* + * This function returns the information regarding the display. + * It is called just after the driver be opened to get all needed + * information about the driver. No change in the mode of operation + * of the driver is done with this call. + */ + int ufb_get_screen_info( int fd, struct fb_screeninfo *info ) + { + return ioctl( fd, FB_SCREENINFO, ( void *)info); + } + + + +/* + * Returns the mode of the graphics subsystem + */ + int ufb_get_mode( int fd, int *mode ) + { + struct fb_exec_function exec; + exec.func_no = FB_FUNC_GET_MODE; + exec.param = ( void *)mode; + return ioctl( fd, FB_EXEC_FUNCTION , ( void *)&exec ); + } + + +/* + * Returns the current collor pallete + */ + int ufb_get_palette( int fd, struct fb_cmap *color ) + { + return ioctl( fd, FB_GETPALETTE, ( void *)color ); + } + + +/* + * Set the current collor pallete + */ + int ufb_set_palette( int fd, struct fb_cmap *color ) + { + return ioctl( fd, FB_SETPALETTE, ( void *)color ); + } + +/* + * Does all necessary initialization to put the device in + * graphics mode + */ + int ufb_enter_graphics( int fd, int mode ) + { + struct fb_exec_function exec; + exec.func_no = FB_FUNC_ENTER_GRAPHICS; + exec.param = ( void *)mode; + return ioctl( fd, FB_EXEC_FUNCTION , ( void *)&exec ); + } + + +/* + * Switch the device back to the default mode of operation. + * In most cases it put the device back to plain text mode. + */ + int ufb_exit_graphics( int fd ) + { + struct fb_exec_function exec; + exec.func_no = FB_FUNC_EXIT_GRAPHICS; + exec.param = 0; + return ioctl( fd, FB_EXEC_FUNCTION , ( void *)&exec ); + } + +/* + * Tell the driver that the "virtual buffer" is dirty, and an update + * of it to the real device, maybe a serial/parallel LCD or whatever + * is required + */ + int ufb_buffer_is_dirty( int fd ) + { + struct fb_exec_function exec; + exec.func_no = FB_FUNC_IS_DIRTY; + exec.param = 0; + return ioctl( fd, FB_EXEC_FUNCTION , ( void *)&exec ); + } + + + +/* + * This function maps the physical ( kernel mode ) address of the framebuffer device + * and maps it to the user space address. + */ + int ufb_mmap_to_user_space( int fd, void **fb_addr, void *physical_addr, unsigned long size ) + { + #ifdef __rtems__ + /* RTEMS runs in ring 0, and there is no distinction between + user space and kernel space, so we just return the same + pointer to the caller. + */ + *fb_addr = physical_addr; + return 0; + #else + /* other kernels might want to map it to the user space, + maybe using mmap() + */ + return 0; + #endif + + } + + +/* + * This function unmaps memory of the FB from the user's space + */ + int ufb_unmmap_from_user_space( int fd, void *addr ) + { + return 0; + } + diff --git a/c/src/libmisc/mw-fb/mw_fb.h b/c/src/libmisc/mw-fb/mw_fb.h new file mode 100644 index 0000000000..ab965c1cb4 --- /dev/null +++ b/c/src/libmisc/mw-fb/mw_fb.h @@ -0,0 +1,153 @@ +/* +///////////////////////////////////////////////////////////////////////////// +// $Header$ +// +// Copyright (c) 2000 - Rosimildo da Silva +// +// MODULE DESCRIPTION: +// Micro FrameBuffer interface for Embedded Systems. +// +// MODIFICATION/HISTORY: +// +// $Log$ +// +///////////////////////////////////////////////////////////////////////////// +*/ +#ifndef _MW_FB_H +#define _MW_FB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* ioctls + 0x46 is 'F' */ +#define FB_SCREENINFO 0x4601 +#define FB_GETPALETTE 0x4602 +#define FB_SETPALETTE 0x4603 +#define FB_EXEC_FUNCTION 0x4604 + + +#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ +#define FB_TYPE_PLANES 1 /* Non interleaved planes */ +#define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */ +#define FB_TYPE_TEXT 3 /* Text/attributes */ +#define FB_TYPE_VGA_PLANES 4 /* EGA/VGA planes */ +#define FB_TYPE_VIRTUAL_BUFFER 5 /* Virtual Buffer */ + + +#define FB_VISUAL_MONO01 0 /* Monochr. 1=Black 0=White */ +#define FB_VISUAL_MONO10 1 /* Monochr. 1=White 0=Black */ +#define FB_VISUAL_TRUECOLOR 2 /* True color */ +#define FB_VISUAL_PSEUDOCOLOR 3 /* Pseudo color (like atari) */ +#define FB_VISUAL_DIRECTCOLOR 4 /* Direct color */ +#define FB_VISUAL_STATIC_PSEUDOCOLOR 5 /* Pseudo color readonly */ + +#define FB_ACCEL_NONE 0 /* no hardware accelerator */ + +/* no dependency on any other header file */ +typedef unsigned long __u32; +typedef unsigned short __u16; + +struct fb_screeninfo { + __u32 xres; /* visible resolution */ + __u32 yres; + __u32 bits_per_pixel; /* guess what */ + __u32 line_length; /* number of chars per line */ + volatile char *smem_start; /* Start of frame buffer mem */ + /* (physical address) */ + __u32 smem_len; /* Length of frame buffer mem */ + __u32 type; /* see FB_TYPE_* */ + __u32 visual; /* see FB_VISUAL_* */ + +}; + +struct fb_cmap { + __u32 start; /* First entry */ + __u32 len; /* Number of entries */ + __u16 *red; /* Red values */ + __u16 *green; + __u16 *blue; + __u16 *transp; /* transparency, can be NULL */ +}; + +/* type of function to be executed at the driver level */ +#define FB_FUNC_ENTER_GRAPHICS 0 +#define FB_FUNC_EXIT_GRAPHICS 1 +#define FB_FUNC_IS_DIRTY 2 +#define FB_FUNC_GET_MODE 3 + +struct fb_exec_function +{ + int func_no; + void *param; +}; + + +/* Micro Framebuffer API Wrapper */ + +/* + * This function returns the information regarding the display. + * It is called just after the driver be opened to get all needed + * information about the driver. No change in the mode of operation + * of the driver is done with this call. + */ +extern int ufb_get_screen_info( int fd, struct fb_screeninfo *info ); + + +/* + * Returns the mode of the graphics subsystem + */ +extern int ufb_get_mode( int fd, int *mode ); + + +/* + * Returns the current collor pallete + */ +extern int ufb_get_palette( int fd, struct fb_cmap *color ); + +/* + * Set the current collor pallete + */ +extern int ufb_set_palette( int fd, struct fb_cmap *color ); + +/* + * Does all necessary initialization to put the device in + * graphics mode + */ +extern int ufb_enter_graphics( int fd, int mode ); + + +/* + * Switch the device back to the default mode of operation. + * In most cases it put the device back to plain text mode. + */ +extern int ufb_exit_graphics( int fd ); + + +/* + * Tell the driver that the "virtual buffer" is dirty, and an update + * of it to the real device, maybe a serial/parallel LCD or whatever + * is required + */ +extern int ufb_buffer_is_dirty( int fd ); + + +/* + * This function maps the physical ( kernel mode ) address of the framebuffer device + * and maps it to the user space address. + */ + int ufb_mmap_to_user_space( int fd, void **fb_addr, void *physical_addr, unsigned long size ); + + + +/* + * This function unmaps memory of the FB from the user's space + */ + int ufb_unmmap_from_user_space( int fd, void *addr ); + +#ifdef __cplusplus +} +#endif + +#endif /* _MW_FB_H */ diff --git a/c/src/libmisc/mw-fb/mw_uid.c b/c/src/libmisc/mw-fb/mw_uid.c new file mode 100644 index 0000000000..5d368a96ff --- /dev/null +++ b/c/src/libmisc/mw-fb/mw_uid.c @@ -0,0 +1,157 @@ +/* +///////////////////////////////////////////////////////////////////////////// +// $Header$ +// +// Copyright (c) 2000 - Rosimildo da Silva +// +// MODULE DESCRIPTION: +// This module implements the input devices interface used by MicroWindows +// in an embedded system environment. +// It uses the RTEMS message queue as the repository for the messages posted +// by the devices registered. +// +// MODIFICATION/HISTORY: +// +// $Log$ +// +///////////////////////////////////////////////////////////////////////////// +*/ +#include +#include +#include +#include +#include +#include + +#include +#include + +static rtems_id queue_id = 0; +static int open_count = 0; + +/* +#define MW_DEBUG_ON 1 +*/ + +/* open a message queue with the kernel */ +int uid_open_queue( const char *q_name, int flags, size_t max_msgs ) +{ + static rtems_name queue_name; + + /* + * For the first device calling this function we would create the queue. + * It is assumed that this call is done at initialization, and no concerns + * regarding multi-threading is taken in consideration here. + */ + if( !open_count ) + { + rtems_status_code status; + queue_name = rtems_build_name( q_name[0], + q_name[1], + q_name[2], + q_name[3] ); + status = rtems_message_queue_create( queue_name, + max_msgs, + sizeof( struct MW_UID_MESSAGE ), + RTEMS_FIFO | RTEMS_LOCAL, + &queue_id ); + if( status != RTEMS_SUCCESSFUL ) + { +#ifdef MW_DEBUG_ON + printk( "UID_Queue: error creating queue: %d\n", status ); +#endif + return -1; + } +#ifdef MW_DEBUG_ON + printk( "UID_Queue: id=%X\n", queue_id ); +#endif + } + open_count++; + return 0; +} + + +/* close message queue */ +int uid_close_queue( void ) +{ + if( open_count == 1 ) + { + rtems_message_queue_delete( queue_id ); + queue_id = 0; + } + open_count--; + return 0; +} + +/* reads for a message from the device */ +int uid_read_message( struct MW_UID_MESSAGE *m, unsigned long timeout ) +{ + rtems_status_code status; + rtems_unsigned32 size = 0; + unsigned long micro_secs = timeout*1000; + int wait = ( timeout != 0 ); + + status = rtems_message_queue_receive( queue_id, + (void*)m, + &size, + wait ? RTEMS_WAIT : RTEMS_NO_WAIT, + TOD_MICROSECONDS_TO_TICKS(micro_secs ) ); + + if( status == RTEMS_SUCCESSFUL ) + { + return size; + } + else if( ( status == RTEMS_UNSATISFIED ) || ( status == RTEMS_TIMEOUT ) ) + { + /* this macro returns -1 */ + set_errno_and_return_minus_one( ETIMEDOUT ); + } + /* Here we have one error condition */ +#ifdef MW_DEBUG_ON + printk( "UID_Queue: error reading queue: %d\n", status ); +#endif + return -1; +} + + +/* + * add a message to the queue of events. This method cna be used to + * simulate hardware events, and it can be very handy during development + * a new interface. + */ +int uid_send_message( struct MW_UID_MESSAGE *m ) +{ + rtems_status_code status; + status = rtems_message_queue_send( queue_id, ( void * )m, + sizeof( struct MW_UID_MESSAGE ) ); + return status == RTEMS_SUCCESSFUL ? 0 : -1; +} + +/* + * register the device to insert events to the message + * queue named as the value passed in q_name + */ +int uid_register_device( int fd, const char *q_name ) +{ + return ioctl( fd, MW_UID_REGISTER_DEVICE, q_name ); +} + +/* tell this device to stop adding events to the queue */ +int uid_unregister_device( int fd ) +{ + return ioctl( fd, MW_UID_UNREGISTER_DEVICE, NULL ); +} + +/* set the keyboard */ +int uid_set_kbd_mode( int fd, int mode, int *old_mode ) +{ + if (ioctl( fd, MV_KDGKBMODE, old_mode) < 0) + { + return -1; + } + if (ioctl(fd, MV_KDSKBMODE, mode ) < 0 ) + { + return -1; + } + return 0; +} diff --git a/c/src/libmisc/mw-fb/mw_uid.h b/c/src/libmisc/mw-fb/mw_uid.h new file mode 100644 index 0000000000..459c3a057c --- /dev/null +++ b/c/src/libmisc/mw-fb/mw_uid.h @@ -0,0 +1,143 @@ +/* +///////////////////////////////////////////////////////////////////////////// +// $Header$ +// +// Copyright (c) 2000 - Rosimildo da Silva +// +// MODULE DESCRIPTION: +// This module defines the interface for input devices used by MicroWindows +// in an embedded system environment. +// +// MODIFICATION/HISTORY: +// +// $Log$ +// +///////////////////////////////////////////////////////////////////////////// +*/ +#ifndef _MW_UID_H +#define _MW_UID_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* 0x41XX -- IOCLT functions for the Micro Input Devices commands */ +#define MW_UID_REGISTER_DEVICE 0x4100 +#define MW_UID_UNREGISTER_DEVICE 0x4101 + + +/* devices supported by MicroWindows */ +enum MW_INPUT_DEVICE_TYPE +{ + MV_UID_INVALID = 0, + MV_UID_REL_POS = 1, /* mouse */ + MV_UID_ABS_POS = 2, /* touch-screen */ + MV_UID_KBD = 3, /* keyboard */ + MV_UID_TIMER = 4 /* timer -- not used */ +}; + + +/* matching MicroWindows */ +#define MV_BUTTON_RIGHT 0x01 +#define MV_BUTTON_CENTER 0x02 +#define MV_BUTTON_LEFT 0x04 + +/* modifiers of the keyboard type devices */ +#define MV_KEY_MODIFIER_SHIFT_DOWN 0x10 +#define MV_KEY_MODIFIER_ALT_DOWN 0x20 + +/* indication of the LEDS */ +#define MV_KEY_MODIFIER_CAPS_ON 0x04 +#define MV_KEY_MODIFIER_NUN_LOCK_ON 0x02 +#define MV_KEY_SCROLL_LOCK_ON 0x01 + +/* keyboard modes -- default ASCII */ +#define MV_KEY_MODE_ASCII 0x01 +/* + * This mode one event is sent when a key is pressed, + * and another one is send when a key is released. + */ +#define MV_KEY_MODE_SCANCODE 0x00 + + +/* these defines match with the linux keyboard range + for ioctls functions for the keyboard interface. + 0x4BXX --- keyboard related functions + */ +#define MV_KDGKBMODE 0x4B44 /* gets current keyboard mode */ +#define MV_KDSKBMODE 0x4B45 /* sets current keyboard mode */ + +/* + * Message generated by input devices controlled by MicroWindows. + */ +struct MW_UID_MESSAGE +{ + enum MW_INPUT_DEVICE_TYPE type; /* device type */ + union + { + /* fired when keyboard events are raised */ + struct kbd_t { + unsigned short code; /* keycode or scancode */ + unsigned char modifiers; /* key modifiers */ + unsigned char mode; /* current Kbd mode */ + } kbd; + + /* fired when position events are raised, mouse, touch screen, etc */ + struct pos_t { + unsigned short btns; /* indicates which buttons are pressed */ + short x; /* x location */ + short y; /* y location */ + short z; /* z location, 0 for 2D */ + } pos; + + /* fired by a timer device periodically */ + struct timer_t { + unsigned long frt; /* free running timer */ + unsigned long seq; /* sequence number */ + } tmr; + + } m; +}; + + +/* + * API for creating/closing/accessing the message queue used by the micro + * input device interface. All functions in this interface returns a + * zero ( 0 ) on success. One exception for that is the "read" routine + * that returns the number of bytes read. Negaive numbers indicate errors + * + * The implementation of the message queue for RTEMS uses a POSIX message + * queue interface. It should be very portable among systems with a POSIX + * support. + */ + +/* creates the message queue that holds events from the input devices */ +extern int uid_open_queue( const char *q_name, int flags, size_t max_msgs ); + +/* closes message queue */ +extern int uid_close_queue( void ); + +/* + * reads a message from the queue. It waits up to the specified + * timeout in mili-seconds. + */ +extern int uid_read_message( struct MW_UID_MESSAGE *m, unsigned long timeout ); + +/* write a message to the queue */ +extern int uid_write_message( struct MW_UID_MESSAGE *m ); + + +/* register device to insert data to the queue */ +extern int uid_register_device( int fd, const char *q_name ); + +/* unregister device to stop adding messages to the queue */ +extern int uid_unregister_device( int fd ); + +/* set the keyboard */ +extern int uid_set_kbd_mode( int fd, int mode, int *old_mode ); + +#ifdef __cplusplus +} +#endif + +#endif /* _MW_UID_H */ diff --git a/c/src/libmisc/wrapup/Makefile.am b/c/src/libmisc/wrapup/Makefile.am index 49a0f6d42a..ea88fc1a97 100644 --- a/c/src/libmisc/wrapup/Makefile.am +++ b/c/src/libmisc/wrapup/Makefile.am @@ -13,7 +13,7 @@ include $(top_srcdir)/../../../automake/lib.am TMP_LIBS = ../monitor/$(ARCH)/libmonitor-tmp.a \ ../untar/$(ARCH)/libuntar-tmp.a ../stackchk/$(ARCH)/libstackchk-tmp.a \ ../cpuuse/$(ARCH)/libcpuuse-tmp.a ../rtmonuse/$(ARCH)/librtmonuse-tmp.a \ - ../dumpbuf/$(ARCH)/libdumpbuf-tmp.a + ../dumpbuf/$(ARCH)/libdumpbuf-tmp.a ../mw-fb/$(ARCH)/libmw-fb-tmp.a $(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a: $(LIB) $(INSTALL_DATA) $< $@ -- cgit v1.2.3