00001
00017 #include <stdint.h>
00018 #include <stdbool.h>
00019 #include <stdlib.h>
00020 #include <stdio.h>
00021 #include <string.h>
00022 #include <ctype.h>
00023
00024 #include "displayconfigall.h"
00025 #include "display.h"
00026 #include "textdisplay.h"
00027
00028 #ifdef TEXTDISPLAY_FONT_8x8
00029 #include "displayfont8x8.h"
00030 #define FONT_ASCII_START (' ')
00031 #define FONT_CHARACTERS (100)
00032 #define FONT_BITS_MASK (0x7)
00033 #define FONT_BITS_LOG2 (3)
00034 #define fontBits chars_8x8_bits
00035 #endif
00036
00037 #ifdef TEXTDISPLAY_FONT_6x8
00038 #include "displayfont6x8.h"
00039 #define FONT_ASCII_START (' ')
00040 #define FONT_CHARACTERS (100)
00041 #define FONT_BITS_MASK (0x7)
00042 #define FONT_BITS_LOG2 (3)
00043 #define fontBits chars_6x8_bits
00044 #endif
00045
00046 #ifdef TEXTDISPLAY_NUMBER_FONT_16x20
00047 #include "displayfont16x20.h"
00048 #define FONT_ASCII_START ('0')
00049 #define FONT_CHARACTERS (12)
00050 #define FONT_BITS_MASK (0xF)
00051 #define FONT_BITS_LOG2 (4)
00052 #define fontBits numbers_16x20_bits
00053 #endif
00054
00055
00058
00059
00060
00061
00062 typedef enum TEXTDISPLAY_UpdateMode_t
00063 {
00064 TEXTDISPLAY_UPDATE_MODE_FULL,
00065 TEXTDISPLAY_UPDATE_MODE_LINE,
00066 TEXTDISPLAY_UPDATE_MODE_CHAR,
00067 TEXTDISPLAY_UPDATE_MODE_NONE
00068 } TEXTDISPLAY_UpdateMode_t;
00069
00070
00071 typedef struct TEXTDISPLAY_Device_t
00072 {
00073 int displayDeviceNo;
00074
00075 DISPLAY_Device_t displayDevice;
00076
00077 unsigned int columns;
00078 unsigned int lines;
00079
00080 bool scrollEnable;
00081
00082
00083
00084
00085
00086 bool lfToCrLf;
00089 DISPLAY_PixelMatrix_t lineBuffer;
00092 char* charBuffer;
00093 char** charArray;
00095 uint8_t rgbColor[3];
00097 unsigned int xpos;
00098 unsigned int ypos;
00100 TEXTDISPLAY_UpdateMode_t updateMode;
00102 bool initialized;
00104 } TEXTDISPLAY_Device_t;
00105
00106
00107 typedef struct TEXTDISPLAY_CharBuffers_t
00108 {
00109 unsigned int lines;
00110 unsigned int columns;
00112 char* charBuffer;
00113 char** charArray;
00114 } TEXTDISPLAY_CharBuffers_t;
00115
00116
00117
00118
00119
00120
00121
00122 static TEXTDISPLAY_Device_t textdisplayTbl[TEXTDISPLAY_DEVICES_MAX];
00123
00124
00125
00126 char charBufferDevice0[TEXTDISPLAY_DEVICE_0_LINES * TEXTDISPLAY_DEVICE_0_COLUMNS];
00127 char* charArrayDevice0[TEXTDISPLAY_DEVICE_0_LINES];
00128
00129 #if (TEXTDISPLAY_DEVICES_MAX == 2)
00130 char charBufferDevice1[TEXTDISPLAY_DEVICE_1_LINES * TEXTDISPLAY_DEVICE_1_COLUMNS];
00131 char* charArrayDevice1[TEXTDISPLAY_DEVICE_1_LINES];
00132 #endif
00133
00134 #if (TEXTDISPLAY_DEVICES_MAX == 3)
00135 char charBufferDevice2[TEXTDISPLAY_DEVICE_2_LINES * TEXTDISPLAY_DEVICE_2_COLUMNS];
00136 char* charArrayDevice2[TEXTDISPLAY_DEVICE_2_LINES];
00137 #endif
00138
00139 #if (TEXTDISPLAY_DEVICES_MAX == 4)
00140 char charBufferDevice3[TEXTDISPLAY_DEVICE_3_LINES * TEXTDISPLAY_DEVICE_3_COLUMNS];
00141 char* charArrayDevice3[TEXTDISPLAY_DEVICE_3_LINES];
00142 #endif
00143
00144
00145 static TEXTDISPLAY_CharBuffers_t charBufferTbl[TEXTDISPLAY_DEVICES_MAX] =
00146 {
00147 {
00148 TEXTDISPLAY_DEVICE_0_LINES,
00149 TEXTDISPLAY_DEVICE_0_COLUMNS,
00150 charBufferDevice0,
00151 charArrayDevice0
00152 },
00153 #if (TEXTDISPLAY_DEVICES_MAX == 2)
00154 {
00155 TEXTDISPLAY_DEVICE_1_LINES,
00156 TEXTDISPLAY_DEVICE_1_COLUMNS,
00157 charBufferDevice1,
00158 charArrayDevice1
00159 },
00160 #endif
00161 #if (TEXTDISPLAY_DEVICES_MAX == 3)
00162 {
00163 TEXTDISPLAY_DEVICE_2_LINES,
00164 TEXTDISPLAY_DEVICE_2_COLUMNS,
00165 charBufferDevice2,
00166 charArrayDevice2
00167 },
00168 #endif
00169 #if (TEXTDISPLAY_DEVICES_MAX == 4)
00170 {
00171 TEXTDISPLAY_DEVICE_3_LINES,
00172 TEXTDISPLAY_DEVICE_3_COLUMNS,
00173 charBufferDevice3,
00174 charArrayDevice3
00175 },
00176 #endif
00177 };
00178
00179
00180
00181
00182
00183
00184
00185 static void TextdisplayClear (TEXTDISPLAY_Device_t* textdisplay);
00186 static void TextdisplayScrollUp (TEXTDISPLAY_Device_t* textdisplay);
00187 static void TextdisplayCharAdd (TEXTDISPLAY_Device_t* textdisplay,
00188 int c);
00189 static EMSTATUS TextdisplayLineDraw (TEXTDISPLAY_Device_t* textdisplay,
00190 unsigned int y);
00191 static EMSTATUS TextdisplayUpdate (TEXTDISPLAY_Device_t* textdisplay);
00192
00196
00197
00198
00199
00200
00210 EMSTATUS TEXTDISPLAY_New(TEXTDISPLAY_Config_t *config,
00211 TEXTDISPLAY_Handle_t *handle)
00212 {
00213 TEXTDISPLAY_Device_t* textdisplay;
00214 int deviceNo;
00215 unsigned int i;
00216 EMSTATUS status;
00217
00218
00219 for (textdisplay=NULL,
00220 deviceNo=0; deviceNo<TEXTDISPLAY_DEVICES_MAX; deviceNo++)
00221 {
00222 if (false == textdisplayTbl[deviceNo].initialized)
00223 {
00224 textdisplay = &textdisplayTbl[deviceNo];
00225 break;
00226 }
00227 }
00228 if (NULL == textdisplay)
00229 {
00230 return TEXTDISPLAY_EMSTATUS_NOT_ENOUGH_MEMORY;
00231 }
00232
00233
00234 status =
00235 DISPLAY_DeviceGet(config->displayDeviceNo, &textdisplay->displayDevice);
00236 if (DISPLAY_EMSTATUS_OK != status)
00237 return status;
00238
00239
00240
00241 if (DISPLAY_ADDRESSING_BY_ROWS_ONLY == textdisplay->displayDevice.addressMode)
00242 {
00243 status =
00244 textdisplay->displayDevice.
00245 pPixelMatrixAllocate (&textdisplay->displayDevice,
00246 textdisplay->displayDevice.geometry.width,
00247 #ifdef EMWIN_WORKAROUND
00248 textdisplay->displayDevice.geometry.width,
00249 #endif
00250 FONT_HEIGHT,
00251 &textdisplay->lineBuffer);
00252 if (DISPLAY_EMSTATUS_OK != status)
00253 return status;
00254
00255 status =
00256 textdisplay->displayDevice.
00257 pPixelMatrixClear (&textdisplay->displayDevice,
00258 textdisplay->lineBuffer,
00259 textdisplay->displayDevice.geometry.width,
00260 FONT_HEIGHT);
00261
00262 if (DISPLAY_EMSTATUS_OK != status)
00263 return status;
00264 }
00265 else
00266 {
00267 textdisplay->lineBuffer = NULL;
00268 }
00269
00270
00271
00272 if (charBufferTbl[deviceNo].lines >
00273 textdisplay->displayDevice.geometry.height / FONT_HEIGHT)
00274 return TEXTDISPLAY_EMSTATUS_OUT_OF_RANGE;
00275 if (charBufferTbl[deviceNo].columns >
00276 textdisplay->displayDevice.geometry.width / FONT_WIDTH)
00277 return TEXTDISPLAY_EMSTATUS_OUT_OF_RANGE;
00278
00279
00280 textdisplay->lines = charBufferTbl[deviceNo].lines;
00281 textdisplay->columns = charBufferTbl[deviceNo].columns;
00282 textdisplay->charBuffer = charBufferTbl[deviceNo].charBuffer;
00283 textdisplay->charArray = charBufferTbl[deviceNo].charArray;
00284
00285
00286 textdisplay->displayDeviceNo = config->displayDeviceNo;
00287 textdisplay->scrollEnable = config->scrollEnable;
00288 textdisplay->lfToCrLf = config->lfToCrLf;
00289
00290
00291 for (i=0; i<textdisplay->lines; i++)
00292 textdisplay->charArray[i] =
00293 textdisplay->charBuffer + textdisplay->columns * i;
00294
00295
00296
00297 textdisplay->rgbColor[0] = 0xff;
00298 textdisplay->rgbColor[1] = 0xff;
00299 textdisplay->rgbColor[2] = 0xff;
00300
00301
00302 TextdisplayClear(textdisplay);
00303
00304 textdisplay->initialized = true;
00305
00306 *handle = (TEXTDISPLAY_Handle_t*) textdisplay;
00307
00308 return TEXTDISPLAY_EMSTATUS_OK;
00309 }
00310
00311
00312
00322 EMSTATUS TEXTDISPLAY_Delete(TEXTDISPLAY_Handle_t handle)
00323 {
00324 TEXTDISPLAY_Device_t* textdisplay = (TEXTDISPLAY_Device_t*) handle;
00325
00326 if (textdisplay->initialized)
00327 {
00328 textdisplay->charBuffer = NULL;
00329 textdisplay->charArray = NULL;
00330
00331 if (textdisplay->lineBuffer)
00332 {
00333 textdisplay->displayDevice.pPixelMatrixFree (&textdisplay->displayDevice,
00334 textdisplay->lineBuffer);
00335 textdisplay->lineBuffer = NULL;
00336 }
00337
00338
00339 textdisplay->displayDeviceNo = -1;
00340
00341 textdisplay->initialized = false;
00342
00343 return TEXTDISPLAY_EMSTATUS_OK;
00344 }
00345
00346 return TEXTDISPLAY_EMSTATUS_INVALID_PARAM;
00347 }
00348
00349
00350
00361 EMSTATUS TEXTDISPLAY_LfToCrLf(TEXTDISPLAY_Handle_t handle,
00362 bool on)
00363 {
00364 TEXTDISPLAY_Device_t* textdisplay = (TEXTDISPLAY_Device_t*) handle;
00365
00366 textdisplay->lfToCrLf = on;
00367
00368 return TEXTDISPLAY_EMSTATUS_OK;
00369 }
00370
00371
00372
00381 EMSTATUS TEXTDISPLAY_WriteChar(TEXTDISPLAY_Handle_t handle,
00382 char c)
00383 {
00384 TEXTDISPLAY_Device_t* textdisplay = (TEXTDISPLAY_Device_t*) handle;
00385
00386
00387 if (false == textdisplay->initialized)
00388 {
00389 return TEXTDISPLAY_EMSTATUS_NOT_INITIALIZED;
00390 }
00391
00392
00393 if (DISPLAY_ADDRESSING_BY_ROWS_ONLY == textdisplay->displayDevice.addressMode)
00394 {
00395 textdisplay->updateMode = TEXTDISPLAY_UPDATE_MODE_LINE;
00396 }
00397 else
00398 {
00399 textdisplay->updateMode = TEXTDISPLAY_UPDATE_MODE_CHAR;
00400 }
00401
00402 if (textdisplay->scrollEnable)
00403 {
00404
00405
00406 if ((0==textdisplay->xpos) && (textdisplay->ypos == textdisplay->lines-1))
00407 {
00408 textdisplay->updateMode = TEXTDISPLAY_UPDATE_MODE_FULL;
00409 }
00410 }
00411 else
00412 {
00413
00414
00415 if ((0==textdisplay->xpos) && (0==textdisplay->ypos))
00416 {
00417 textdisplay->updateMode = TEXTDISPLAY_UPDATE_MODE_FULL;
00418 }
00419 }
00420
00421
00422 if (c == '\f')
00423 {
00424 TextdisplayClear(textdisplay);
00425
00426 textdisplay->updateMode = TEXTDISPLAY_UPDATE_MODE_FULL;
00427 return TextdisplayUpdate(textdisplay);
00428 }
00429
00430
00431 if (textdisplay->lfToCrLf && (c == '\n'))
00432 {
00433 TextdisplayCharAdd(textdisplay, '\r');
00434 }
00435 TextdisplayCharAdd(textdisplay, c);
00436
00437 if (TEXTDISPLAY_UPDATE_MODE_NONE != textdisplay->updateMode)
00438
00439 return TextdisplayUpdate(textdisplay);
00440 else
00441 return TEXTDISPLAY_EMSTATUS_OK;
00442 }
00443
00444
00445
00454 EMSTATUS TEXTDISPLAY_WriteString(TEXTDISPLAY_Handle_t handle,
00455 char* str)
00456 {
00457 TEXTDISPLAY_Device_t* textdisplay = (TEXTDISPLAY_Device_t*) handle;
00458 EMSTATUS status;
00459 char c;
00460 bool displayUpdated=false;
00461
00462
00463 if (false == textdisplay->initialized)
00464 {
00465 return TEXTDISPLAY_EMSTATUS_NOT_INITIALIZED;
00466 }
00467
00468
00469 if (DISPLAY_ADDRESSING_BY_ROWS_ONLY == textdisplay->displayDevice.addressMode)
00470 {
00471 textdisplay->updateMode = TEXTDISPLAY_UPDATE_MODE_LINE;
00472 }
00473 else
00474 {
00475 textdisplay->updateMode = TEXTDISPLAY_UPDATE_MODE_CHAR;
00476 }
00477
00478 while (*str)
00479 {
00480
00481 displayUpdated = false;
00482
00483
00484
00485 if ((0==textdisplay->xpos) && (0==textdisplay->ypos) &&
00486 (false == textdisplay->scrollEnable))
00487 {
00488 TextdisplayClear(textdisplay);
00489 textdisplay->updateMode = TEXTDISPLAY_UPDATE_MODE_FULL;
00490 }
00491
00492 c = *str;
00493
00494 switch (c)
00495 {
00496 case '\f':
00497
00498 TextdisplayClear(textdisplay);
00499 textdisplay->updateMode = TEXTDISPLAY_UPDATE_MODE_FULL;
00500 break;
00501
00502 case '\n':
00503
00504 status = TextdisplayUpdate(textdisplay);
00505 if (status != TEXTDISPLAY_EMSTATUS_OK)
00506 return status;
00507
00508 displayUpdated = true;
00509
00510
00511 if (textdisplay->lfToCrLf)
00512 {
00513 TextdisplayCharAdd(textdisplay, '\r');
00514 }
00515
00516 TextdisplayCharAdd(textdisplay, c);
00517 break;
00518
00519 default:
00520 TextdisplayCharAdd(textdisplay, c);
00521 break;
00522 }
00523
00524
00525
00526 if ((textdisplay->xpos >= textdisplay->columns) ||
00527 (textdisplay->updateMode == TEXTDISPLAY_UPDATE_MODE_FULL))
00528 {
00529 status = TextdisplayUpdate(textdisplay);
00530 if (status != TEXTDISPLAY_EMSTATUS_OK)
00531 return status;
00532 displayUpdated = true;
00533 }
00534
00535 str++;
00536 }
00537
00538
00539 if (!displayUpdated)
00540 return TextdisplayUpdate(textdisplay);
00541 else
00542 return TEXTDISPLAY_EMSTATUS_OK;
00543 }
00544
00545
00548
00549
00550
00551
00552
00557 static void TextdisplayClear(TEXTDISPLAY_Device_t* textdisplay)
00558 {
00559 if (textdisplay->charArray)
00560 {
00561
00562 #if (FONT_ASCII_START>' ') || (FONT_ASCII_START+FONT_CHARACTERS<' ')
00563
00564
00565
00566 memset(textdisplay->charBuffer, FONT_CHARACTERS - 1,
00567 textdisplay->lines * textdisplay->columns);
00568 #else
00569 memset(textdisplay->charBuffer, 0,
00570 textdisplay->lines * textdisplay->columns);
00571 #endif
00572
00573
00574 textdisplay->xpos = 0;
00575 textdisplay->ypos = 0;
00576
00577 textdisplay->updateMode = TEXTDISPLAY_UPDATE_MODE_FULL;
00578 }
00579 }
00580
00581
00582
00587 static void TextdisplayScrollUp(TEXTDISPLAY_Device_t* textdisplay)
00588 {
00589 unsigned int y;
00590
00591
00592 for (y = 0; y < (textdisplay->lines - 1); y++)
00593 {
00594 memcpy(textdisplay->charArray[y],
00595 textdisplay->charArray[y + 1],
00596 textdisplay->columns);
00597 }
00598
00599
00600 memset(&textdisplay->charArray[textdisplay->lines - 1][0],
00601 0,
00602 textdisplay->columns);
00603
00604 textdisplay->xpos = 0;
00605 textdisplay->ypos = textdisplay->lines - 1;
00606 textdisplay->updateMode = TEXTDISPLAY_UPDATE_MODE_FULL;
00607 }
00608
00609
00610 #ifdef INCLUDE_VIDEO_TERMINAL_ESCAPE_SEQUENCE_SUPPORT
00611
00622 static bool TextdisplayEscapeSequence(TEXTDISPLAY_Device_t* textdisplay,
00623 int c)
00624 {
00625 #define ASCII_ESC (27)
00626 #define ESC_SEQ_SIZE_MAX (4)
00627 #define ESC_SEQ_MAX (6)
00628 static char escapeSequence[ESC_SEQ_SIZE_MAX]= {0,0,0,0};
00629 static const char escapeSequences[ESC_SEQ_MAX][ESC_SEQ_SIZE_MAX] =
00630 {
00631
00632
00633
00634 TEXTDISPLAY_ESC_SEQ_CURSOR_HOME_VT100,
00635 TEXTDISPLAY_ESC_SEQ_CURSOR_HOME_VT52,
00636 TEXTDISPLAY_ESC_SEQ_CURSOR_UP_ONE_LINE,
00637 TEXTDISPLAY_ESC_SEQ_CURSOR_DOWN_ONE_LINE,
00638 TEXTDISPLAY_ESC_SEQ_CURSOR_RIGHT_ONE_CHAR,
00639 TEXTDISPLAY_ESC_SEQ_CURSOR_LEFT_ONE_CHAR
00640 };
00641 #define TEXTDISPLAY_ESC_SEQNO_CURSOR_HOME_VT100 (0)
00642 #define TEXTDISPLAY_ESC_SEQNO_CURSOR_HOME_VT52 (1)
00643 #define TEXTDISPLAY_ESC_SEQNO_CURSOR_UP_ONE_LINE (2)
00644 #define TEXTDISPLAY_ESC_SEQNO_CURSOR_DOWN_ONE_LINE (3)
00645 #define TEXTDISPLAY_ESC_SEQNO_CURSOR_RIGHT_ONE_CHAR (4)
00646 #define TEXTDISPLAY_ESC_SEQNO_CURSOR_LEFT_ONE_CHAR (5)
00647
00648 char* pChar;
00649 int seqNo;
00650 bool anyMatch = false;
00651
00652
00653 if (ASCII_ESC == c)
00654 {
00655
00656
00657 memset(escapeSequence, 0, ESC_SEQ_SIZE_MAX);
00658 escapeSequence[0]=c;
00659 textdisplay->updateMode = TEXTDISPLAY_UPDATE_MODE_NONE;
00660 return true;
00661 }
00662
00663 if (ASCII_ESC != escapeSequence[0])
00664 {
00665
00666 return false;
00667 }
00668 else
00669 {
00670 unsigned int len;
00671
00672
00673
00674
00675
00676 pChar = escapeSequence;
00677 while (*(++pChar));
00678 *pChar = c;
00679
00680 len = strlen(escapeSequence);
00681
00682 for (seqNo=0; seqNo<ESC_SEQ_MAX; seqNo++)
00683 {
00684
00685 if (0 == strncmp(escapeSequence, escapeSequences[seqNo], len))
00686 {
00687
00688
00689 anyMatch = true;
00690 textdisplay->updateMode = TEXTDISPLAY_UPDATE_MODE_NONE;
00691
00692
00693 if (len == strlen(escapeSequences[seqNo]))
00694 {
00695 switch (seqNo)
00696 {
00697 case TEXTDISPLAY_ESC_SEQNO_CURSOR_HOME_VT100:
00698 case TEXTDISPLAY_ESC_SEQNO_CURSOR_HOME_VT52:
00699
00700 textdisplay->ypos = 0;
00701 textdisplay->xpos = 0;
00702 break;
00703 case TEXTDISPLAY_ESC_SEQNO_CURSOR_UP_ONE_LINE:
00704
00705 if (textdisplay->ypos)
00706 textdisplay->ypos--;
00707 break;
00708 case TEXTDISPLAY_ESC_SEQNO_CURSOR_DOWN_ONE_LINE:
00709
00710 if (textdisplay->ypos < textdisplay->lines-1)
00711 textdisplay->ypos++;
00712 break;
00713 case TEXTDISPLAY_ESC_SEQNO_CURSOR_RIGHT_ONE_CHAR:
00714
00715 if (textdisplay->xpos < textdisplay->columns-1)
00716 textdisplay->xpos++;
00717 break;
00718 case TEXTDISPLAY_ESC_SEQNO_CURSOR_LEFT_ONE_CHAR:
00719
00720 if (textdisplay->xpos)
00721 textdisplay->xpos--;
00722 break;
00723 }
00724
00725
00726 memset(escapeSequence, 0, ESC_SEQ_SIZE_MAX);
00727 textdisplay->updateMode = TEXTDISPLAY_UPDATE_MODE_NONE;
00728 return true;
00729 }
00730
00731
00732
00733 break;
00734 }
00735 }
00736
00737 if (false == anyMatch)
00738 {
00739
00740 memset(escapeSequence, 0, ESC_SEQ_SIZE_MAX);
00741 return false;
00742 }
00743
00744 if (ESC_SEQ_SIZE_MAX-1 == len)
00745 {
00746
00747
00748 memset(escapeSequence, 0, ESC_SEQ_SIZE_MAX);
00749 textdisplay->updateMode = TEXTDISPLAY_UPDATE_MODE_NONE;
00750 return true;
00751 }
00752
00753 return anyMatch;
00754 }
00755 }
00756
00757 #endif
00758
00759
00760
00773 static void TextdisplayCharAdd(TEXTDISPLAY_Device_t* textdisplay,
00774 int c)
00775 {
00776 switch (c)
00777 {
00778 case '\r':
00779 textdisplay->xpos = 0;
00780 return;
00781
00782 case '\n':
00783 textdisplay->ypos = textdisplay->ypos + 1;
00784 textdisplay->xpos = 0;
00785 if (textdisplay->ypos >= textdisplay->lines)
00786 {
00787 if (textdisplay->scrollEnable)
00788 {
00789
00790 TextdisplayScrollUp(textdisplay);
00791 textdisplay->ypos = (textdisplay->lines - 1);
00792 }
00793 else
00794 {
00795 TextdisplayClear(textdisplay);
00796 }
00797 }
00798 return;
00799
00800 case '\b':
00801 if ( (DISPLAY_COLOUR_MODE_MONOCHROME !=
00802 textdisplay->displayDevice.colourMode) &&
00803 (DISPLAY_COLOUR_MODE_MONOCHROME_INVERSE !=
00804 textdisplay->displayDevice.colourMode) )
00805 {
00806 if (textdisplay->rgbColor[1] == 0xff)
00807 {
00808 textdisplay->rgbColor[1] = 0x00;
00809 textdisplay->rgbColor[2] = 0x00;
00810 }
00811 else
00812 {
00813 textdisplay->rgbColor[1] = 0xff;
00814 textdisplay->rgbColor[2] = 0xff;
00815 }
00816 return;
00817 }
00818
00819 }
00820
00821 #ifdef INCLUDE_VIDEO_TERMINAL_ESCAPE_SEQUENCE_SUPPORT
00822 if (TextdisplayEscapeSequence(textdisplay, c))
00823 {
00824
00825 return;
00826 }
00827 #endif
00828
00829
00830 if (!isprint(c))
00831 {
00832 c = ' ';
00833 }
00834
00835 #if 100 > FONT_CHARACTERS
00836
00837
00838 if ( (FONT_ASCII_START>c) || (FONT_ASCII_START+FONT_CHARACTERS<=c) )
00839 {
00840 #if (FONT_ASCII_START>' ') || (FONT_ASCII_START+FONT_CHARACTERS<' ')
00841
00842
00843 c = FONT_ASCII_START + FONT_CHARACTERS - 1;
00844 #else
00845 c = ' ';
00846 #endif
00847 }
00848 #endif
00849
00850 if (textdisplay->xpos >= textdisplay->columns)
00851 {
00852 textdisplay->xpos = 0;
00853 textdisplay->ypos = textdisplay->ypos + 1;
00854 }
00855 if (textdisplay->ypos >= textdisplay->lines)
00856 {
00857 if (textdisplay->scrollEnable)
00858 {
00859 TextdisplayScrollUp(textdisplay);
00860 textdisplay->ypos = textdisplay->lines - 1;
00861 }
00862 else
00863 {
00864 TextdisplayClear(textdisplay);
00865 }
00866 }
00867 textdisplay->charArray[textdisplay->ypos][textdisplay->xpos] =
00868 c - FONT_ASCII_START;
00869
00870 textdisplay->xpos = textdisplay->xpos + 1;
00871
00872 return;
00873 }
00874
00875
00876
00884 static EMSTATUS TextdisplayLineDraw(TEXTDISPLAY_Device_t* textdisplay,
00885 unsigned int y)
00886 {
00887 unsigned int x, i;
00888 uint8_t c;
00889 FontBits_t* rowPtr = (FontBits_t*) textdisplay->lineBuffer;
00890 FontBits_t pixelBits;
00891
00892 for (i = 0; i < FONT_HEIGHT; i++)
00893 {
00894 for (x = 0; x < textdisplay->columns; x++)
00895 {
00896 c = textdisplay->charArray[y][x];
00897
00898 pixelBits = fontBits[c + FONT_CHARACTERS * i];
00899
00900 switch (textdisplay->displayDevice.colourMode)
00901 {
00902 #if (8 == FONT_WIDTH) || (16 == FONT_WIDTH)
00903 case DISPLAY_COLOUR_MODE_MONOCHROME:
00904 rowPtr[x] = pixelBits;
00905 break;
00906
00907 case DISPLAY_COLOUR_MODE_MONOCHROME_INVERSE:
00908 rowPtr[x] = ~pixelBits;
00909 break;
00910 #elif (8 > FONT_WIDTH) || (16 > FONT_WIDTH)
00911 case DISPLAY_COLOUR_MODE_MONOCHROME_INVERSE:
00912 pixelBits = ~pixelBits;
00913 case DISPLAY_COLOUR_MODE_MONOCHROME:
00914 {
00915 int startPixel = x * FONT_WIDTH;
00916 int pixelNo = startPixel;
00917 for (; pixelNo<startPixel+FONT_WIDTH; pixelBits>>=1, pixelNo++)
00918 {
00919 if (pixelBits & 0x1)
00920 {
00921 rowPtr[pixelNo>>FONT_BITS_LOG2] |= 1 << (pixelNo&FONT_BITS_MASK);
00922 }
00923 else
00924 {
00925 rowPtr[pixelNo>>FONT_BITS_LOG2] &= ~(1 << (pixelNo&FONT_BITS_MASK));
00926 }
00927 }
00928 }
00929 break;
00930 #endif
00931 }
00932 }
00933
00934 #if (8 != FONT_WIDTH) || (16 != FONT_WIDTH)
00935
00936 if (textdisplay->displayDevice.colourMode ==
00937 DISPLAY_COLOUR_MODE_MONOCHROME_INVERSE)
00938 {
00939 int usedBits;
00940 int startPixel = x * FONT_WIDTH;
00941
00942
00943 usedBits = startPixel & FONT_BITS_MASK;
00944 if (usedBits)
00945 {
00946
00947 rowPtr[startPixel>>FONT_BITS_LOG2] &= (1<<usedBits)-1;
00948
00949 startPixel += (sizeof(FontBits_t)*8) - usedBits;
00950 }
00951 memset (&rowPtr[startPixel>>FONT_BITS_LOG2], 0xff,
00952 (textdisplay->displayDevice.geometry.width - startPixel)/8);
00953 }
00954 #endif
00955
00956 rowPtr +=
00957 textdisplay->displayDevice.geometry.stride / (sizeof(FontBits_t) * 8) ;
00958 }
00959
00960 return
00961 textdisplay->displayDevice.pPixelMatrixDraw(&textdisplay->displayDevice,
00962 textdisplay->lineBuffer,
00963 0,
00964 textdisplay->columns*FONT_WIDTH,
00965 #ifdef EMWIN_WORKAROUND
00966 textdisplay->columns*FONT_WIDTH,
00967 #endif
00968 y * FONT_HEIGHT,
00969 FONT_HEIGHT);
00970 }
00971
00972
00973
00980 static EMSTATUS TextdisplayUpdate(TEXTDISPLAY_Device_t* textdisplay)
00981 {
00982 unsigned int i;
00983 EMSTATUS status;
00984
00985 switch (textdisplay->updateMode)
00986 {
00987 case TEXTDISPLAY_UPDATE_MODE_NONE:
00988 default:
00989 break;
00990
00991 case TEXTDISPLAY_UPDATE_MODE_FULL:
00992
00993
00994
00995 switch (textdisplay->displayDevice.addressMode)
00996 {
00997 case DISPLAY_ADDRESSING_BY_ROWS_ONLY:
00998
00999
01000 for (i=0; i<textdisplay->lines; i++)
01001
01002 TextdisplayLineDraw(textdisplay, i);
01003
01004
01005 if (textdisplay->lines * FONT_HEIGHT <
01006 textdisplay->displayDevice.geometry.height)
01007 {
01008 switch (textdisplay->displayDevice.colourMode)
01009 {
01010 case DISPLAY_COLOUR_MODE_MONOCHROME:
01011 memset (textdisplay->lineBuffer, 0x00,
01012 textdisplay->displayDevice.geometry.width/8);
01013 break;
01014 case DISPLAY_COLOUR_MODE_MONOCHROME_INVERSE:
01015 memset (textdisplay->lineBuffer, 0xff,
01016 textdisplay->displayDevice.geometry.width/8);
01017 break;
01018 default:
01019 return TEXTDISPLAY_EMSTATUS_NOT_SUPPORTED;
01020 }
01021
01022 for (i = textdisplay->lines * FONT_HEIGHT;
01023 i < textdisplay->displayDevice.geometry.height;
01024 i++)
01025 {
01026 status =
01027 textdisplay->displayDevice.pPixelMatrixDraw(&textdisplay->displayDevice,
01028 textdisplay->lineBuffer,
01029 0,
01030 textdisplay->displayDevice.geometry.width,
01031 #ifdef EMWIN_WORKAROUND
01032 textdisplay->displayDevice.geometry.width,
01033 #endif
01034 i,
01035 1);
01036 if (DISPLAY_EMSTATUS_OK != status)
01037 return status;
01038 }
01039 }
01040 break;
01041
01042 default:
01043 return TEXTDISPLAY_EMSTATUS_NOT_SUPPORTED;
01044 }
01045
01046 case TEXTDISPLAY_UPDATE_MODE_LINE:
01047
01048 switch (textdisplay->displayDevice.addressMode)
01049 {
01050 case DISPLAY_ADDRESSING_BY_ROWS_ONLY:
01051
01052
01053 return TextdisplayLineDraw(textdisplay, textdisplay->ypos);
01054
01055 default:
01056 return TEXTDISPLAY_EMSTATUS_NOT_SUPPORTED;
01057 }
01058
01059 case TEXTDISPLAY_UPDATE_MODE_CHAR:
01060 return TEXTDISPLAY_EMSTATUS_NOT_SUPPORTED;
01061 }
01062 return TEXTDISPLAY_EMSTATUS_OK;
01063 }
01064
01068
01069
01070
01071
01072
01073
01074