source: rtems/c/src/lib/libbsp/arm/raspberrypi/console/outch.c @ b83c23e6

5
Last change on this file since b83c23e6 was b83c23e6, checked in by Pavel Pisa <pisa@…>, on 06/28/16 at 15:07:02

arm/raspberrypi: resolve BSP warnings.

  • Property mode set to 100644
File size: 9.8 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup raspberrypi
5 *
6 * @brief displaying characters on the console
7 */
8
9/**
10 *
11 * Copyright (c) 2015 Yang Qiao
12 * based on work by:
13 * Copyright (C) 1998  Eric Valette (valette@crf.canon.fr)
14 *                     Canon Centre Recherche France.
15 *
16 *  The license and distribution terms for this file may be
17 *  found in the file LICENSE in this distribution or at
18 *  http://www.rtems.org/license/LICENSE.
19 *
20 * Till Straumann <strauman@slac.stanford.edu>, 2003/9:
21 *  - added handling of basic escape sequences (cursor movement
22 *    and erasing; just enough for the line editor 'libtecla' to
23 *    work...)
24 *
25 */
26
27#include <bsp.h>
28#include <bsp/vc.h>
29#include <bsp/rpi-fb.h>
30#include <rtems/fb.h>
31
32#include <stdlib.h>
33#include <string.h>
34#include "font_data.h"
35
36static void wr_cursor(
37  int           r,
38  int           c
39)
40{
41  /* dummy function for now */
42}
43
44#define TAB_SPACE 4
45#define CONSOLE_BG_COL 0x00
46#define CONSOLE_FG_COL 0xa0
47
48static void          *fb_mem = NULL;
49static unsigned short maxCol;
50static unsigned short maxRow;
51static unsigned short bytes_per_pixel;
52static unsigned int   bytes_per_line;
53static unsigned int   bytes_per_char_line;
54static unsigned char  row;
55static unsigned char  column;
56static unsigned int   nLines;
57static uint32_t       fgx, bgx, eorx;
58static int            rpi_video_initialized;
59
60static const int video_font_draw_table32[ 16 ][ 4 ] = {
61  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
62  { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff },
63  { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 },
64  { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff },
65  { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 },
66  { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff },
67  { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 },
68  { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff },
69  { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 },
70  { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff },
71  { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 },
72  { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff },
73  { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 },
74  { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff },
75  { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 },
76  { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff }
77};
78
79static void scroll( void )
80{
81  int      i, j;      /* Counters */
82  uint8_t *pt_scroll, *pt_bitmap;  /* Pointers on the bit-map  */
83
84  pt_bitmap = fb_mem;
85  j = 0;
86  pt_bitmap = pt_bitmap + j;
87  pt_scroll = pt_bitmap + bytes_per_char_line;
88
89  for ( i = j; i < maxRow - 1; i++ ) {
90    memcpy( pt_bitmap, pt_scroll, bytes_per_char_line );
91    pt_bitmap = pt_bitmap + bytes_per_char_line;
92    pt_scroll = pt_bitmap + bytes_per_char_line;
93  }
94
95  /*
96   * Blank characters are displayed on the last line.
97   */
98  memset( pt_bitmap, 0, bytes_per_char_line );
99}
100
101static void doCRNL(
102  int cr,
103  int nl
104)
105{
106  if ( nl ) {
107    if ( ++row == maxRow ) {
108      scroll();   /* Scroll the screen now */
109      row = maxRow - 1;
110    }
111
112    nLines++;
113  }
114
115  if ( cr )
116    column = 0;
117
118  /* Move cursor on the next location  */
119  if ( cr || nl ) {
120    wr_cursor( row, column );
121  }
122}
123
124static void advanceCursor( void )
125{
126  if ( ++column == maxCol )
127    doCRNL( 1, 1 );
128  else
129    wr_cursor( row, column );
130}
131
132static void gotorc(
133  int r,
134  int c
135)
136{
137  column = c;
138  row = r;
139  wr_cursor( row, column );
140}
141
142static void video_drawchars(
143  int           r,
144  int           c,
145  unsigned char ch
146)
147{
148  if ( fb_mem == NULL ) {
149    return;
150  }
151
152  uint8_t *cdat, *dest, *dest0;
153  int      rows, offset;
154
155  offset = r * bytes_per_char_line + c * bytes_per_pixel * RPI_FONT_WIDTH;
156  dest0 = fb_mem + offset;
157
158  /*
159   * only 32-bit per pixel format is supported for now
160   */
161  cdat = rpi_font + ch * RPI_FONT_HEIGHT;
162
163  for ( rows = RPI_FONT_HEIGHT, dest = dest0;
164        rows--; dest += bytes_per_line ) {
165    uint8_t bits = *cdat++;
166
167    ( (uint32_t *) dest )[ 0 ] =
168      ( video_font_draw_table32
169        [ bits >> 4 ][ 0 ] & eorx ) ^ bgx;
170    ( (uint32_t *) dest )[ 1 ] =
171      ( video_font_draw_table32
172        [ bits >> 4 ][ 1 ] & eorx ) ^ bgx;
173    ( (uint32_t *) dest )[ 2 ] =
174      ( video_font_draw_table32
175        [ bits >> 4 ][ 2 ] & eorx ) ^ bgx;
176    ( (uint32_t *) dest )[ 3 ] =
177      ( video_font_draw_table32
178        [ bits >> 4 ][ 3 ] & eorx ) ^ bgx;
179
180    ( (uint32_t *) dest )[ 4 ] =
181      ( video_font_draw_table32
182        [ bits & 15 ][ 0 ] & eorx ) ^ bgx;
183    ( (uint32_t *) dest )[ 5 ] =
184      ( video_font_draw_table32
185        [ bits & 15 ][ 1 ] & eorx ) ^ bgx;
186    ( (uint32_t *) dest )[ 6 ] =
187      ( video_font_draw_table32
188        [ bits & 15 ][ 2 ] & eorx ) ^ bgx;
189    ( (uint32_t *) dest )[ 7 ] =
190      ( video_font_draw_table32
191        [ bits & 15 ][ 3 ] & eorx ) ^ bgx;
192  }
193}
194
195#define ESC ( (char) 27 )
196/* erase current location without moving the cursor */
197#define BLANK ( (char) 0x7f )
198
199static void videoPutChar( char ch )
200{
201  switch ( ch ) {
202    case '\b': {
203      if ( column )
204        column--;
205
206      /* Move cursor on the previous location  */
207      wr_cursor( row, column );
208      return;
209    }
210    case '\t': {
211      int i;
212
213      i = TAB_SPACE - ( column & ( TAB_SPACE - 1 ) );
214
215      while ( i-- ) {
216
217        video_drawchars( row, column, ' ' );
218        column += 1;
219
220        if ( column >= maxCol ) {
221          doCRNL( 1, 1 );
222          return;
223        }
224      }
225
226      wr_cursor( row, column );
227
228      return;
229    }
230    case '\n': {
231      doCRNL( 0, 1 );
232      return;
233    }
234    case 7:   {     /* Bell code must be inserted here */
235      return;
236    }
237    case '\r': {
238      doCRNL( 1, 0 );
239      return;
240    }
241    case BLANK: {
242      video_drawchars( row, column, ' ' );
243
244      wr_cursor( row, column );
245
246      return;
247    }
248    default: {
249      // *pt_bitmap = (unsigned char)ch | attribute;
250      video_drawchars( row, column, ch );
251      advanceCursor();
252      return;
253    }
254  }
255}
256
257/* trivial state machine to handle escape sequences:
258 *
259 *                    ---------------------------------
260 *                   |                                 |
261 *                   |                                 |
262 * KEY:        esc   V    [          DCABHKJ       esc |
263 * STATE:   0 -----> 27 -----> '[' ----------> -1 -----
264 *          ^\        \          \               \
265 * KEY:     | \other   \ other    \ other         \ other
266 *           <-------------------------------------
267 *
268 * in state '-1', the DCABHKJ cases are handled
269 *
270 * (cursor motion and screen clearing)
271 */
272
273#define DONE ( -1 )
274
275static int handleEscape(
276  int  oldState,
277  char ch
278)
279{
280  int rval = 0;
281  int ro, co;
282
283  switch ( oldState ) {
284    case DONE:  /*  means the previous char terminated an ESC sequence... */
285    case 0:
286
287      if ( 27 == ch ) {
288        rval = 27;   /* START of an ESC sequence */
289      }
290
291      break;
292
293    case 27:
294
295      if ( '[' == ch ) {
296        rval = ch;  /* received ESC '[', so far */
297      } else {
298        /* dump suppressed 'ESC'; outch will append the char */
299        videoPutChar( ESC );
300      }
301
302      break;
303
304    case '[':
305      /* handle 'ESC' '[' sequences here */
306      ro = row;
307      co = column;
308      rval = DONE; /* done */
309
310      switch ( ch ) {
311        case 'D': /* left */
312
313          if ( co > 0 )
314            co--;
315
316          break;
317        case 'C': /* right */
318
319          if ( co < maxCol )
320            co++;
321
322          break;
323        case 'A': /* up    */
324
325          if ( ro > 0 )
326            ro--;
327
328          break;
329        case 'B': /* down */
330
331          if ( ro < maxRow )
332            ro++;
333
334          break;
335        case 'H': /* home */
336          ro = co = 0;
337          break;
338        case 'K': /* clear to end of line */
339
340          while ( column < maxCol - 1 )
341            videoPutChar( ' ' );
342
343          videoPutChar( BLANK );
344          break;
345        case 'J':     /* clear to end of screen */
346
347          while ( ( ( row < maxRow - 1 ) || ( column < maxCol - 1 ) ) )
348            videoPutChar( ' ' );
349
350          videoPutChar( BLANK );
351          break;
352        default:
353          videoPutChar( ESC );
354          videoPutChar( '[' );
355          /* DONT move the cursor */
356          ro = -1;
357          rval = 0;
358          break;
359      }
360
361      // /* reset cursor */
362      if ( ro >= 0 )
363        gotorc( ro, co );
364
365    default:
366      break;
367  }
368
369  return rval;
370}
371
372static void clear_screen( void )
373{
374  int i, j;
375
376  for ( j = 0; j < maxRow; j++ ) {
377    for ( i = 0; i < maxCol; i++ ) {
378      videoPutChar( ' ' );
379    }
380  }
381
382  column = 0;
383  row = 0;
384}
385
386void rpi_fb_outch( char c )
387{
388  static int escaped = 0;
389
390  if ( !( escaped = handleEscape( escaped, c ) ) ) {
391    if ( '\n' == c )
392      videoPutChar( '\r' );
393
394    videoPutChar( c );
395  }
396}
397
398void rpi_video_init( void )
399{
400  int ret = rpi_fb_init();
401
402  if ( ( ret != RPI_FB_INIT_OK ) &&
403       ( ret != RPI_FB_INIT_ALREADY_INITIALIZED ) ) {
404    rpi_video_initialized = 0;
405    return;
406  }
407
408  struct fb_var_screeninfo fb_var_info;
409  struct fb_fix_screeninfo fb_fix_info;
410  rpi_get_var_screen_info( &fb_var_info );
411  rpi_get_fix_screen_info( &fb_fix_info );
412  maxCol = fb_var_info.xres / RPI_FONT_WIDTH;
413  maxRow = fb_var_info.yres / RPI_FONT_HEIGHT;
414  bytes_per_pixel = fb_var_info.bits_per_pixel / 8;
415  bytes_per_line = bytes_per_pixel * fb_var_info.xres;
416  bytes_per_char_line = RPI_FONT_HEIGHT * bytes_per_line;
417  fb_mem = RTEMS_DEVOLATILE( void *, fb_fix_info.smem_start );
418  column = 0;
419  row = 0;
420  nLines = 0;
421  fgx = ( CONSOLE_FG_COL << 24 ) |
422        ( CONSOLE_FG_COL << 16 ) |
423        ( CONSOLE_FG_COL << 8 ) |
424        CONSOLE_FG_COL;
425  bgx = ( CONSOLE_BG_COL << 24 ) |
426        ( CONSOLE_BG_COL << 16 ) |
427        ( CONSOLE_BG_COL << 8 ) |
428        CONSOLE_BG_COL;
429  eorx = fgx ^ bgx;
430  clear_screen();
431  rpi_video_initialized = 1;
432}
433
434int rpi_video_is_initialized( void )
435{
436  return rpi_video_initialized;
437}
438
439/* for old DOS compatibility n-curses type of applications */
440void gotoxy(
441  int x,
442  int y
443);
444int whereX( void );
445int whereY( void );
446
447void gotoxy(
448  int x,
449  int y
450)
451{
452  gotorc( y, x );
453}
454
455int whereX( void )
456{
457  return row;
458}
459
460int whereY( void )
461{
462  return column;
463}
Note: See TracBrowser for help on using the repository browser.