Graphics Drawing Interface EZLCD4 display using serial
gdiezl4.h@2:d0ec618edc6d, 2011-03-15 (annotated)
- Committer:
- wbasser
- Date:
- Tue Mar 15 15:11:24 2011 +0000
- Revision:
- 2:d0ec618edc6d
- Parent:
- 0:607ac6f9ce7a
Version 00_00_03
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wbasser | 0:607ac6f9ce7a | 1 | /* mbed R/C Servo Library |
wbasser | 0:607ac6f9ce7a | 2 | * Copyright (c) 2007-2010 sford, cstyles |
wbasser | 0:607ac6f9ce7a | 3 | * |
wbasser | 0:607ac6f9ce7a | 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
wbasser | 0:607ac6f9ce7a | 5 | * of this software and associated documentation files (the "Software"), to deal |
wbasser | 0:607ac6f9ce7a | 6 | * in the Software without restriction, including without limitation the rights |
wbasser | 0:607ac6f9ce7a | 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
wbasser | 0:607ac6f9ce7a | 8 | * copies of the Software, and to permit persons to whom the Software is |
wbasser | 0:607ac6f9ce7a | 9 | * furnished to do so, subject to the following conditions: |
wbasser | 0:607ac6f9ce7a | 10 | * |
wbasser | 0:607ac6f9ce7a | 11 | * The above copyright notice and this permission notice shall be included in |
wbasser | 0:607ac6f9ce7a | 12 | * all copies or substantial portions of the Software. |
wbasser | 0:607ac6f9ce7a | 13 | * |
wbasser | 0:607ac6f9ce7a | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
wbasser | 0:607ac6f9ce7a | 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
wbasser | 0:607ac6f9ce7a | 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
wbasser | 0:607ac6f9ce7a | 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
wbasser | 0:607ac6f9ce7a | 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
wbasser | 0:607ac6f9ce7a | 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
wbasser | 0:607ac6f9ce7a | 20 | * THE SOFTWARE. |
wbasser | 0:607ac6f9ce7a | 21 | */ |
wbasser | 0:607ac6f9ce7a | 22 | |
wbasser | 0:607ac6f9ce7a | 23 | // ensure only one copy |
wbasser | 0:607ac6f9ce7a | 24 | #ifndef _GDIEZL4_H |
wbasser | 0:607ac6f9ce7a | 25 | #define _GDIEZL4_H |
wbasser | 0:607ac6f9ce7a | 26 | |
wbasser | 0:607ac6f9ce7a | 27 | // include files |
wbasser | 0:607ac6f9ce7a | 28 | #include "mbed.h" |
wbasser | 0:607ac6f9ce7a | 29 | #include "types.h" |
wbasser | 0:607ac6f9ce7a | 30 | #include "MODSERIAL.h" |
wbasser | 0:607ac6f9ce7a | 31 | #include "FPointer.h" |
wbasser | 0:607ac6f9ce7a | 32 | |
wbasser | 0:607ac6f9ce7a | 33 | // define the RGB macro |
wbasser | 0:607ac6f9ce7a | 34 | #define RGB( R, G, B ) (((( R >> 3 ) & 0x1F ) << 11 ) | ((( G >> 2 ) & 0x3F ) << 5 ) | (( B >> 3 ) & 0x1F )) |
wbasser | 0:607ac6f9ce7a | 35 | |
wbasser | 0:607ac6f9ce7a | 36 | // define the max X/Y in landscaple mode |
wbasser | 0:607ac6f9ce7a | 37 | #define MAX_X_SIZE 319 |
wbasser | 0:607ac6f9ce7a | 38 | #define MAX_Y_SIZE 233 |
wbasser | 0:607ac6f9ce7a | 39 | |
wbasser | 0:607ac6f9ce7a | 40 | // define some standard colcors |
wbasser | 0:607ac6f9ce7a | 41 | #define GDI_CLR_BLK RGB( 0, 0, 0 ) |
wbasser | 0:607ac6f9ce7a | 42 | #define GDI_CLR_WHT RGB( 255, 255, 255 ) |
wbasser | 0:607ac6f9ce7a | 43 | #define GDI_CLR_BLU RGB( 0, 0, 255 ) |
wbasser | 0:607ac6f9ce7a | 44 | #define GDI_CLR_RED RGB( 255, 0, 0 ) |
wbasser | 0:607ac6f9ce7a | 45 | #define GDI_CLR_GRN RGB( 0, 255, 0 ) |
wbasser | 0:607ac6f9ce7a | 46 | |
wbasser | 0:607ac6f9ce7a | 47 | // define the no button icon valu |
wbasser | 0:607ac6f9ce7a | 48 | #define GDI_BTN_NOICON 255 |
wbasser | 0:607ac6f9ce7a | 49 | |
wbasser | 0:607ac6f9ce7a | 50 | // define the button up/down masks |
wbasser | 0:607ac6f9ce7a | 51 | #define GDI_BTN_DNMSK 0x40 |
wbasser | 0:607ac6f9ce7a | 52 | #define GDI_BTN_UPMSK 0x80 |
wbasser | 0:607ac6f9ce7a | 53 | #define GDI_BTN_VLMSK 0x3F |
wbasser | 0:607ac6f9ce7a | 54 | |
wbasser | 0:607ac6f9ce7a | 55 | // define the pong value |
wbasser | 0:607ac6f9ce7a | 56 | #define GDI_PNG_VALUE 0x38 |
wbasser | 0:607ac6f9ce7a | 57 | |
wbasser | 0:607ac6f9ce7a | 58 | // class definition |
wbasser | 0:607ac6f9ce7a | 59 | class GdiEzL4 |
wbasser | 0:607ac6f9ce7a | 60 | { |
wbasser | 0:607ac6f9ce7a | 61 | public: |
wbasser | 0:607ac6f9ce7a | 62 | // construction/destruction |
wbasser | 0:607ac6f9ce7a | 63 | /** Graphics Drawing Interface (EZLCD4 ) construction |
wbasser | 0:607ac6f9ce7a | 64 | * |
wbasser | 0:607ac6f9ce7a | 65 | * @param pinTx = transmit pin |
wbasser | 0:607ac6f9ce7a | 66 | * @param pinRx = receive pin |
wbasser | 0:607ac6f9ce7a | 67 | */ |
wbasser | 0:607ac6f9ce7a | 68 | GdiEzL4( PinName pinTx, PinName pinRx ); |
wbasser | 0:607ac6f9ce7a | 69 | ~GdiEzL4( ); |
wbasser | 0:607ac6f9ce7a | 70 | |
wbasser | 0:607ac6f9ce7a | 71 | // attributes |
wbasser | 0:607ac6f9ce7a | 72 | public: |
wbasser | 0:607ac6f9ce7a | 73 | // enumerate the text direction- |
wbasser | 0:607ac6f9ce7a | 74 | enum GDITXTDIR { |
wbasser | 0:607ac6f9ce7a | 75 | GDI_TXT_NORTH = 0, // text direction north |
wbasser | 0:607ac6f9ce7a | 76 | GDI_TXT_EAST, // text direction east |
wbasser | 0:607ac6f9ce7a | 77 | GDI_TXT_SOUTH, // text direction south |
wbasser | 0:607ac6f9ce7a | 78 | GDI_TXT_WEST // text direction west |
wbasser | 0:607ac6f9ce7a | 79 | }; |
wbasser | 0:607ac6f9ce7a | 80 | |
wbasser | 0:607ac6f9ce7a | 81 | // enumerate the button state |
wbasser | 0:607ac6f9ce7a | 82 | enum GDIBTNSTATE { |
wbasser | 0:607ac6f9ce7a | 83 | GDI_BTN_UP = 1, // button up |
wbasser | 0:607ac6f9ce7a | 84 | GDI_BTN_DN, // button down |
wbasser | 0:607ac6f9ce7a | 85 | GDI_BTN_DSB, // button disabled |
wbasser | 0:607ac6f9ce7a | 86 | GDI_BTN_NVS // button non-visible |
wbasser | 0:607ac6f9ce7a | 87 | }; |
wbasser | 0:607ac6f9ce7a | 88 | |
wbasser | 0:607ac6f9ce7a | 89 | // define the button parameters |
wbasser | 0:607ac6f9ce7a | 90 | struct GDIBTNDEF { |
wbasser | 0:607ac6f9ce7a | 91 | GDIBTNSTATE eInitalState; // initial state |
wbasser | 0:607ac6f9ce7a | 92 | U8 nUpIcon; // up icon index |
wbasser | 0:607ac6f9ce7a | 93 | U8 nDnIcon; // down icon index |
wbasser | 0:607ac6f9ce7a | 94 | U8 nDsIcon; // disabled icon index |
wbasser | 0:607ac6f9ce7a | 95 | U16 wUpLfX; // upper left X |
wbasser | 0:607ac6f9ce7a | 96 | U8 nUpLfY; // upper left Y |
wbasser | 0:607ac6f9ce7a | 97 | U8 nTouchWidth; // touch width |
wbasser | 0:607ac6f9ce7a | 98 | U8 nTouchHeight; // touch height |
wbasser | 0:607ac6f9ce7a | 99 | }; |
wbasser | 0:607ac6f9ce7a | 100 | |
wbasser | 0:607ac6f9ce7a | 101 | private: |
wbasser | 0:607ac6f9ce7a | 102 | MODSERIAL m_serDisp; |
wbasser | 0:607ac6f9ce7a | 103 | FPointer m_pvFuncCallBack; |
wbasser | 0:607ac6f9ce7a | 104 | |
wbasser | 0:607ac6f9ce7a | 105 | // local functions |
wbasser | 0:607ac6f9ce7a | 106 | void LocalCallback( void ); |
wbasser | 0:607ac6f9ce7a | 107 | |
wbasser | 0:607ac6f9ce7a | 108 | // enumerate the LCD commands |
wbasser | 0:607ac6f9ce7a | 109 | enum COMMANDS { |
wbasser | 0:607ac6f9ce7a | 110 | EZ_CLS = 0x21, // 0x21 - clear screen |
wbasser | 0:607ac6f9ce7a | 111 | EZ_LON, // 0x22 - backlight on |
wbasser | 0:607ac6f9ce7a | 112 | EZ_LOF, // 0x23 - backlight off |
wbasser | 0:607ac6f9ce7a | 113 | EZ_PLT = 0x26, // 0x26 - plot a pixel |
wbasser | 0:607ac6f9ce7a | 114 | EZ_PIC = 0x2A, // 0x2A - draw a picture |
wbasser | 0:607ac6f9ce7a | 115 | EZ_FNT, // 0x2B - select the font |
wbasser | 0:607ac6f9ce7a | 116 | EZ_CHR, // 0x2C - draw a character |
wbasser | 0:607ac6f9ce7a | 117 | EZ_STR, // 0x2D - draw a string |
wbasser | 0:607ac6f9ce7a | 118 | EZ_SPS = 0x35, // 0x35 - store position |
wbasser | 0:607ac6f9ce7a | 119 | EZ_RPS, // 0x36 - restore position |
wbasser | 0:607ac6f9ce7a | 120 | EZ_CHB = 0x3C, // 0x3C - draw character on the background |
wbasser | 0:607ac6f9ce7a | 121 | EZ_STB, // 0x3D - draw a string on the background |
wbasser | 0:607ac6f9ce7a | 122 | EZ_VLN = 0x41, // 0x41 - draw a vertical line |
wbasser | 0:607ac6f9ce7a | 123 | EZ_ICF = 0x58, // 0x58 - draw an icon from serial flash |
wbasser | 0:607ac6f9ce7a | 124 | EZ_STY = 0x5F, // 0x5F - set y position |
wbasser | 0:607ac6f9ce7a | 125 | EZ_TXN = 0x60, // 0x60 - set text direction to north |
wbasser | 0:607ac6f9ce7a | 126 | EZ_TXE, // 0x61 - set text direction to east |
wbasser | 0:607ac6f9ce7a | 127 | EZ_TXS, // 0x62 - set text direction to south |
wbasser | 0:607ac6f9ce7a | 128 | EZ_TXW, // 0x63 - set text direction to west |
wbasser | 0:607ac6f9ce7a | 129 | EZ_STX = 0x6E, // 0x6E - set X position |
wbasser | 0:607ac6f9ce7a | 130 | EZ_BKL = 0x80, // 0x80 - brightness |
wbasser | 0:607ac6f9ce7a | 131 | EZ_PNG = 0x83, // 0x83 - ping the unit |
wbasser | 0:607ac6f9ce7a | 132 | EZ_FGC, // 0x84 - set foreground color |
wbasser | 0:607ac6f9ce7a | 133 | EZ_SXY, // 0x85 - set X/y position |
wbasser | 0:607ac6f9ce7a | 134 | EZ_PXY = 0x87, // 0x87 - plot a pixel at x,y |
wbasser | 0:607ac6f9ce7a | 135 | EZ_LIN, // 0x88 - draw a line |
wbasser | 0:607ac6f9ce7a | 136 | EZ_CIR, // 0x89 - draw a circle |
wbasser | 0:607ac6f9ce7a | 137 | EZ_ARC = 0x8F, // 0x8F - draw an arc |
wbasser | 0:607ac6f9ce7a | 138 | EZ_PIE, // 0x90 - draw a pie |
wbasser | 0:607ac6f9ce7a | 139 | EZ_BGC = 0x94, // 0x94 - set background color |
wbasser | 0:607ac6f9ce7a | 140 | EZ_CRF = 0x99, // 0x99 - draw a filled circle |
wbasser | 0:607ac6f9ce7a | 141 | EZ_BMP = 0x9E, // 0x9E - draw a bitmap |
wbasser | 0:607ac6f9ce7a | 142 | EZ_HLN = 0xA0, // 0xA0 - draw a horizontal line |
wbasser | 0:607ac6f9ce7a | 143 | EZ_BOX = 0xA2, // 0xA2 - draw a box |
wbasser | 0:607ac6f9ce7a | 144 | EZ_BXF, // 0xA3 - draw a filled box |
wbasser | 0:607ac6f9ce7a | 145 | EZ_BTD = 0xB0, // 0xB0 - define a touch button |
wbasser | 0:607ac6f9ce7a | 146 | EZ_BTS, // 0xB1 - changes a button state |
wbasser | 0:607ac6f9ce7a | 147 | EZ_BTP, // 0xB2 - sets the button protocol |
wbasser | 0:607ac6f9ce7a | 148 | EZ_BUP, // 0xB3 - all buttons up |
wbasser | 0:607ac6f9ce7a | 149 | EZ_BDL, // 0xB4 - delete all buttons |
wbasser | 0:607ac6f9ce7a | 150 | EZ_BOF = 0xD0, // 0xD0 - buzzer off |
wbasser | 0:607ac6f9ce7a | 151 | EZ_BON, // 0xD1 - buzzer on |
wbasser | 0:607ac6f9ce7a | 152 | EZ_BEE // 0xD2 - beep the buzzer for some time |
wbasser | 0:607ac6f9ce7a | 153 | }; |
wbasser | 0:607ac6f9ce7a | 154 | |
wbasser | 0:607ac6f9ce7a | 155 | public: |
wbasser | 0:607ac6f9ce7a | 156 | // implementation |
wbasser | 0:607ac6f9ce7a | 157 | /** backlight ontrol |
wbasser | 0:607ac6f9ce7a | 158 | * |
wbasser | 0:607ac6f9ce7a | 159 | * @param bOffOn = state of the backlight |
wbasser | 0:607ac6f9ce7a | 160 | */ |
wbasser | 0:607ac6f9ce7a | 161 | void BacklightCtl( BOOL bOffOn ); |
wbasser | 0:607ac6f9ce7a | 162 | |
wbasser | 0:607ac6f9ce7a | 163 | /** clear the screen |
wbasser | 0:607ac6f9ce7a | 164 | * |
wbasser | 0:607ac6f9ce7a | 165 | * @param wColor = background color |
wbasser | 0:607ac6f9ce7a | 166 | */ |
wbasser | 0:607ac6f9ce7a | 167 | void ClearScreen( U16 wColor ); |
wbasser | 0:607ac6f9ce7a | 168 | |
wbasser | 0:607ac6f9ce7a | 169 | /** Draw a rectangle |
wbasser | 0:607ac6f9ce7a | 170 | * |
wbasser | 0:607ac6f9ce7a | 171 | * @param wColor = color of the rectangle |
wbasser | 0:607ac6f9ce7a | 172 | * @param wSx = starting X location ( top left ) |
wbasser | 0:607ac6f9ce7a | 173 | * @param nSy = starting Y location ( top left ) |
wbasser | 0:607ac6f9ce7a | 174 | * @param wWidth = width of the rectangle |
wbasser | 0:607ac6f9ce7a | 175 | * @param nHeight = height of the rectangle |
wbasser | 0:607ac6f9ce7a | 176 | * @param bFill = TRUE if rectangle is filled |
wbasser | 0:607ac6f9ce7a | 177 | */ |
wbasser | 0:607ac6f9ce7a | 178 | void DrawRect( U16 wColor, U16 wSx, U8 nSy, U16 wWidth, U8 nHeight, BOOL fFill ); |
wbasser | 0:607ac6f9ce7a | 179 | |
wbasser | 0:607ac6f9ce7a | 180 | /** Draw a line |
wbasser | 0:607ac6f9ce7a | 181 | * |
wbasser | 0:607ac6f9ce7a | 182 | * @param wColor = color of the line |
wbasser | 0:607ac6f9ce7a | 183 | * @param wSx = starting X location ( top left ) |
wbasser | 0:607ac6f9ce7a | 184 | * @param nSy = starting Y location ( top left ) |
wbasser | 0:607ac6f9ce7a | 185 | * @param wEx = ending X location ( bottom right ) |
wbasser | 0:607ac6f9ce7a | 186 | * @param nEy = ending Y location ( bottom right ) |
wbasser | 0:607ac6f9ce7a | 187 | */ |
wbasser | 0:607ac6f9ce7a | 188 | void DrawLine( U16 wColor, U16 wSx, U8 nSy, U16 wEx, U8 nEy ); |
wbasser | 0:607ac6f9ce7a | 189 | |
wbasser | 0:607ac6f9ce7a | 190 | /** Draw an Icon |
wbasser | 0:607ac6f9ce7a | 191 | * |
wbasser | 0:607ac6f9ce7a | 192 | * @param wSx = starting X location ( top left ) |
wbasser | 0:607ac6f9ce7a | 193 | * @param nSy = starting Y location ( top left ) |
wbasser | 0:607ac6f9ce7a | 194 | * @param nIcon = icon index |
wbasser | 0:607ac6f9ce7a | 195 | */ |
wbasser | 0:607ac6f9ce7a | 196 | void DrawIcon( U16 wSx, U8 nSy, U8 nIcon ); |
wbasser | 0:607ac6f9ce7a | 197 | |
wbasser | 0:607ac6f9ce7a | 198 | /** Draw a character |
wbasser | 0:607ac6f9ce7a | 199 | * |
wbasser | 0:607ac6f9ce7a | 200 | * @param wColor = color of the character |
wbasser | 0:607ac6f9ce7a | 201 | * @param nFont = font index |
wbasser | 0:607ac6f9ce7a | 202 | * @param wSx = starting X location ( top left ) |
wbasser | 0:607ac6f9ce7a | 203 | * @param nSy = starting Y location ( top left ) |
wbasser | 0:607ac6f9ce7a | 204 | * @param bBackground = display as inverted background |
wbasser | 0:607ac6f9ce7a | 205 | * @param eDir = text direction |
wbasser | 0:607ac6f9ce7a | 206 | * @param cChar = character to draw |
wbasser | 0:607ac6f9ce7a | 207 | */ |
wbasser | 0:607ac6f9ce7a | 208 | void DrawChar( U16 wColor, U8 nFont, U16 wSx, U8 nSy, BOOL bBackground, GDITXTDIR eDir, C8 cChar ); |
wbasser | 0:607ac6f9ce7a | 209 | |
wbasser | 0:607ac6f9ce7a | 210 | /** draw a string |
wbasser | 0:607ac6f9ce7a | 211 | * |
wbasser | 0:607ac6f9ce7a | 212 | * @param wColor = color of the character |
wbasser | 0:607ac6f9ce7a | 213 | * @param nFont = font index |
wbasser | 0:607ac6f9ce7a | 214 | * @param wSx = starting X location ( top left ) |
wbasser | 0:607ac6f9ce7a | 215 | * @param nSy = starting Y location ( top left ) |
wbasser | 0:607ac6f9ce7a | 216 | * @param bBackground = display as inverted background |
wbasser | 0:607ac6f9ce7a | 217 | * @param eDir = text direction |
wbasser | 0:607ac6f9ce7a | 218 | * @param pszMsg = pointer to the message |
wbasser | 0:607ac6f9ce7a | 219 | */ |
wbasser | 0:607ac6f9ce7a | 220 | void DrawString( U16 wFgClr, U16 wBgClr, U8 nFont, U16 wSx, U8 nSy, BOOL bBackground, GDITXTDIR eDir, PC8 pszMsg ); |
wbasser | 0:607ac6f9ce7a | 221 | |
wbasser | 0:607ac6f9ce7a | 222 | /** backlight ontrol |
wbasser | 0:607ac6f9ce7a | 223 | * |
wbasser | 0:607ac6f9ce7a | 224 | * @param nBtnIdx = button index |
wbasser | 0:607ac6f9ce7a | 225 | * @param ptBugDef -> pointer to the button definition structure |
wbasser | 0:607ac6f9ce7a | 226 | */ |
wbasser | 0:607ac6f9ce7a | 227 | void DrawButton( U8 nBtnIdx, GDIBTNDEF* ptButDef ); |
wbasser | 0:607ac6f9ce7a | 228 | |
wbasser | 0:607ac6f9ce7a | 229 | /** backlight ontrol |
wbasser | 0:607ac6f9ce7a | 230 | * |
wbasser | 0:607ac6f9ce7a | 231 | * @param bOffOn = state of the backlight |
wbasser | 0:607ac6f9ce7a | 232 | */ |
wbasser | 0:607ac6f9ce7a | 233 | void RemoveAllButtons( void ); |
wbasser | 0:607ac6f9ce7a | 234 | |
wbasser | 0:607ac6f9ce7a | 235 | /** backlight ontrol |
wbasser | 0:607ac6f9ce7a | 236 | * |
wbasser | 0:607ac6f9ce7a | 237 | * @param bOffOn = state of the backlight |
wbasser | 0:607ac6f9ce7a | 238 | */ |
wbasser | 0:607ac6f9ce7a | 239 | void PingDisplay( void ); |
wbasser | 0:607ac6f9ce7a | 240 | |
wbasser | 0:607ac6f9ce7a | 241 | /** backlight ontrol |
wbasser | 0:607ac6f9ce7a | 242 | * |
wbasser | 0:607ac6f9ce7a | 243 | * @param bOffOn = state of the backlight |
wbasser | 0:607ac6f9ce7a | 244 | */ |
wbasser | 2:d0ec618edc6d | 245 | void attach( U32 ( *function )( U32 ) = 0) { m_pvFuncCallBack.attach( function ); } |
wbasser | 0:607ac6f9ce7a | 246 | |
wbasser | 0:607ac6f9ce7a | 247 | /** backlight ontrol |
wbasser | 0:607ac6f9ce7a | 248 | * |
wbasser | 0:607ac6f9ce7a | 249 | * @param bOffOn = state of the backlight |
wbasser | 0:607ac6f9ce7a | 250 | */ |
wbasser | 0:607ac6f9ce7a | 251 | template<class T> |
wbasser | 2:d0ec618edc6d | 252 | void attach( T* item, U32 ( T::*method )( U32 )) { m_pvFuncCallBack.attach( item, method ); } |
wbasser | 0:607ac6f9ce7a | 253 | }; |
wbasser | 0:607ac6f9ce7a | 254 | |
wbasser | 0:607ac6f9ce7a | 255 | |
wbasser | 0:607ac6f9ce7a | 256 | #endif |
wbasser | 0:607ac6f9ce7a | 257 |