![](/media/cache/group/Semtech_stack_color_logo_highres.jpg.50x50_q85.jpg)
Source code for the SX126xDVK1xAS Dev Kit. This example code has only been tested on the Nucleo L476RG
Dependencies: mbed DmTftLibrary SX126xLib
DisplayDriver.cpp
00001 /* 00002 ______ _ 00003 / _____) _ | | 00004 ( (____ _____ ____ _| |_ _____ ____| |__ 00005 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00006 _____) ) ____| | | || |_| ____( (___| | | | 00007 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00008 (C)2016 Semtech 00009 00010 Description: Display driver implementation 00011 00012 Maintainer: Gregory Cristian & Gilbert Menth 00013 */ 00014 00015 #include "mbed.h" 00016 #include "Eeprom.h" 00017 #include "DisplayDriver.h" 00018 #include "DmTftIli9341.h" 00019 #include "DmTouch.h" 00020 #include "DmTouchCalibration.h" 00021 00022 00023 //If DISPLAY_INVERT is defined as 1 then the display will be inverted from its native orientation 00024 #define DISPLAY_INVERT 1 00025 00026 #define MAX_GO_STRING 30 00027 #define SPACE_ASCII 0x20 00028 #define FONT_WIDTH 8 00029 00030 // DmTftIli9341( PinName cs, PinName dc, PinName mosi, PinName miso, PinName clk ) 00031 // DM_TFT28_105 00032 DmTftIli9341 Tft( D10, D9, D11, D12, D13 ); 00033 DmTouch Touch( DmTouch::DM_TFT28_105, D9, D11, D12 ); 00034 DmTouchCalibration Calibration = DmTouchCalibration( &Tft, &Touch ); 00035 00036 /* 00037 * Used only to define pull-up on the CS lines 00038 */ 00039 DigitalInOut CsTouch( D4, PIN_OUTPUT, PullUp, 1 ); 00040 DigitalInOut CsDisplay( D10, PIN_OUTPUT, PullUp, 1 ); 00041 DigitalInOut CsSDCard( D8, PIN_OUTPUT, PullUp, 1 ); 00042 DigitalInOut CsFlash( D6, PIN_OUTPUT, PullUp, 1 ); 00043 DigitalOut DebugPin( A3 ); 00044 00045 MenuSettings_t MenuSettings; 00046 char GoTmpString[MAX_GO_STRING]; 00047 00048 static int BmpWidth; 00049 static int BmpHeight; 00050 static uint8_t BmpImageoffset; 00051 00052 00053 static bool BmpReadHeader( uint8_t *thisBmp ); 00054 static uint16_t Read16( uint8_t *src ); 00055 static uint32_t Read32( uint8_t *src ); 00056 static void DrawBmpFromFlash( uint8_t *thisBmp, int x, int y ); 00057 00058 00059 void DisplayDriverInit( void ) 00060 { 00061 Tft.init( ); 00062 Touch.init( ); 00063 00064 DisplayDriverCalibrate( ); 00065 Tft.clearScreen( ); 00066 00067 for( uint8_t i = 0; i < MAX_GO_STRING; i++) GoTmpString[i] = SPACE_ASCII; 00068 } 00069 00070 // Calibrates the touch screen 00071 void DisplayDriverCalibrate( void ) 00072 { 00073 uint16_t x, y = 0; 00074 bool touched = false; 00075 00076 if( Eeprom.EepromData.MenuSettings.ScreenCalibrated == false ) 00077 { 00078 Tft.drawString( 5, 5, "Press and hold on cross" ); 00079 Tft.drawString( 5, 25, "until it turns green. " ); 00080 00081 Point displayRefPoint[5]; 00082 Point touchRefPoint[5]; 00083 00084 if( Calibration.getTouchReferencePoints( displayRefPoint, touchRefPoint,\ 00085 Tft.width( ), Tft.height( ) ) ) 00086 { 00087 CalibrationMatrix calibrationMatrix = \ 00088 Calibration.calculateCalibrationMatrix( displayRefPoint, \ 00089 touchRefPoint ); 00090 00091 Touch.setCalibrationMatrix( calibrationMatrix ); 00092 Tft.clearScreen( ); 00093 Eeprom.EepromData.MenuSettings.Calibration.a = calibrationMatrix.a; 00094 Eeprom.EepromData.MenuSettings.Calibration.b = calibrationMatrix.b; 00095 Eeprom.EepromData.MenuSettings.Calibration.c = calibrationMatrix.c; 00096 Eeprom.EepromData.MenuSettings.Calibration.d = calibrationMatrix.d; 00097 Eeprom.EepromData.MenuSettings.Calibration.e = calibrationMatrix.e; 00098 Eeprom.EepromData.MenuSettings.Calibration.f = calibrationMatrix.f; 00099 Eeprom.EepromData.MenuSettings.ScreenCalibrated = true; 00100 EepromSaveSettings( SCREEN_DATA ); 00101 } 00102 else 00103 { 00104 Tft.clearScreen( ); 00105 Tft.drawString( 5, 5, "Calibration failed" ); 00106 Tft.drawString( 5, 25, "Please try again." ); 00107 delay( 2000 ); 00108 Tft.clearScreen( ); 00109 return; 00110 } 00111 } 00112 else 00113 { 00114 Touch.setCalibrationMatrix( Eeprom.EepromData.MenuSettings.Calibration ); 00115 Tft.clearScreen( ); 00116 } 00117 00118 if( Touch.isTouched( ) ) 00119 { 00120 Touch.readTouchData( x, y, touched ); 00121 Calibration.drawCalibPoint( x, y ); 00122 } 00123 } 00124 00125 GraphObjectStatus_t GraphObjectDraw( GraphObject_t* goObject, uint8_t* source, \ 00126 bool doFill, bool activeTouch) 00127 { 00128 GraphObjectStatus_t status = GO_STATUS_NOERR; 00129 uint8_t maxChar; 00130 00131 if( goObject == NULL ) 00132 { 00133 return GO_STATUS_BAD_ARG; 00134 } 00135 if( goObject->Xpos + goObject->Width > SCREEN_WIDTH ) 00136 { 00137 return GO_STATUS_BAD_COORD; 00138 } 00139 if( goObject->Ypos + goObject->Height > SCREEN_HEIGHT ) 00140 { 00141 return GO_STATUS_BAD_COORD; 00142 } 00143 switch( goObject->Type ) 00144 { 00145 case GO_TEXT: 00146 if( source == NULL ) 00147 { 00148 status = GO_STATUS_BAD_ARG; 00149 } 00150 else 00151 { 00152 uint8_t i = 0; 00153 uint8_t j = 0; 00154 // max character in the object string 00155 maxChar = goObject->Width / FONT_WIDTH; 00156 Tft.setTextColor( goObject->BackColor, goObject->FrontColor ); 00157 for( i = 0; i < maxChar; i++) 00158 { 00159 if( *source != 0 ) 00160 { 00161 Tft.drawChar( goObject->Xpos + j, goObject->Ypos, \ 00162 ( char )*( source++ ), false ); 00163 j += FONT_WIDTH; 00164 } 00165 else 00166 { 00167 Tft.drawChar( goObject->Xpos + ( FONT_WIDTH * i ), \ 00168 goObject->Ypos, SPACE_ASCII, false); 00169 } 00170 } 00171 goObject->TouchActive = activeTouch; 00172 } 00173 break; 00174 00175 case GO_RECTANGLE: 00176 Tft.drawRectangle( goObject->Xpos, goObject->Ypos, goObject->Xpos + \ 00177 goObject->Width - 1, goObject->Ypos + \ 00178 goObject->Height - 1, goObject->FrontColor ); 00179 if( doFill ) 00180 { 00181 Tft.fillRectangle( goObject->Xpos + 1, goObject->Ypos + 1, \ 00182 goObject->Xpos + goObject->Width - 2, \ 00183 goObject->Ypos + goObject->Height - 2, \ 00184 goObject->FillColor ); 00185 } 00186 goObject->TouchActive = activeTouch; 00187 break; 00188 00189 case GO_CIRCLE: 00190 Tft.drawCircle( goObject->Xpos, goObject->Ypos, \ 00191 ( goObject->Height < goObject->Width ) ? \ 00192 ( goObject->Height / 2 ) : ( goObject->Width / 2 ), \ 00193 goObject->FrontColor ); 00194 if( doFill ) 00195 { 00196 Tft.fillCircle( goObject->Xpos, goObject->Ypos, \ 00197 ( goObject->Height < goObject->Width ) ? \ 00198 ( goObject->Height / 2 ) - 1 : ( goObject->Width / 2 ) - 1, \ 00199 goObject->FillColor ); 00200 } 00201 goObject->TouchActive = activeTouch; 00202 break; 00203 00204 case GO_TRIANGLE: 00205 status = GO_STATUS_BAD_ARG; 00206 break; 00207 00208 case GO_IMAGE: 00209 if( source == NULL ) 00210 { 00211 status = GO_STATUS_BAD_ARG; 00212 } 00213 else 00214 { 00215 if( BmpReadHeader( goObject->Source ) ) 00216 { 00217 DrawBmpFromFlash( goObject->Source, goObject->Xpos, \ 00218 goObject->Ypos ); 00219 } 00220 else 00221 { 00222 // draw a red rectangle with a line through, to show error 00223 Tft.drawRectangle( goObject->Xpos, goObject->Ypos, \ 00224 goObject->Xpos + goObject->Width - 1, \ 00225 goObject->Ypos + goObject->Height - 1, \ 00226 OBJECT_ERROR ); 00227 Tft.drawLine( goObject->Xpos, goObject->Ypos, goObject->Xpos + \ 00228 goObject->Width - 1, goObject->Ypos + \ 00229 goObject->Height - 1, OBJECT_ERROR ); 00230 } 00231 goObject->TouchActive = activeTouch; 00232 } 00233 break; 00234 00235 case GO_LINE: 00236 Tft.drawLine( goObject->Xpos, goObject->Ypos, goObject->Xpos + \ 00237 goObject->Width - 1, goObject->Ypos + \ 00238 goObject->Height - 1, goObject->FrontColor ); 00239 break; 00240 00241 default: 00242 status = GO_STATUS_BAD_ARG; 00243 } 00244 return status; 00245 } 00246 00247 GraphObjectStatus_t GraphObjectClear( GraphObject_t* goObject, bool doFill ) 00248 { 00249 GraphObjectStatus_t status = GO_STATUS_NOERR; 00250 uint8_t maxChar; 00251 00252 if( goObject == NULL ) 00253 { 00254 return GO_STATUS_BAD_ARG; 00255 } 00256 if( goObject->Xpos + goObject->Width > SCREEN_WIDTH ) 00257 { 00258 return GO_STATUS_BAD_COORD; 00259 } 00260 if( goObject->Ypos + goObject->Height > SCREEN_HEIGHT ) 00261 { 00262 return GO_STATUS_BAD_COORD; 00263 } 00264 switch( goObject->Type ) 00265 { 00266 case GO_TEXT: 00267 // max character in the object string 00268 maxChar = goObject->Width / FONT_WIDTH; 00269 GoTmpString[maxChar] = NULL; 00270 Tft.setTextColor( goObject->BackColor, goObject->FrontColor ); 00271 Tft.drawString( goObject->Xpos, goObject->Ypos, GoTmpString ); 00272 GoTmpString[maxChar] = SPACE_ASCII; 00273 goObject->TouchActive = false; 00274 break; 00275 00276 case GO_RECTANGLE: 00277 case GO_IMAGE: 00278 if( doFill ) 00279 { 00280 Tft.fillRectangle( goObject->Xpos, goObject->Ypos, \ 00281 goObject->Xpos + goObject->Width - 1, \ 00282 goObject->Ypos + goObject->Height - 1, \ 00283 goObject->BackColor ); 00284 } 00285 else 00286 { 00287 Tft.drawRectangle( goObject->Xpos, goObject->Ypos, goObject->Xpos + \ 00288 goObject->Width - 1, goObject->Ypos + \ 00289 goObject->Height - 1, goObject->BackColor ); 00290 } 00291 goObject->TouchActive = false; 00292 break; 00293 00294 case GO_CIRCLE: 00295 if( doFill ) 00296 { 00297 Tft.fillCircle( goObject->Xpos, goObject->Ypos, \ 00298 ( goObject->Height < goObject->Width ) ? \ 00299 ( goObject->Height / 2 ) : ( goObject->Width / 2 ), \ 00300 goObject->BackColor ); 00301 } 00302 else 00303 { 00304 Tft.drawCircle( goObject->Xpos, goObject->Ypos, \ 00305 ( goObject->Height < goObject->Width ) ? \ 00306 ( goObject->Height / 2 ) : ( goObject->Width / 2 ), \ 00307 goObject->BackColor ); 00308 } 00309 goObject->TouchActive = false; 00310 break; 00311 00312 case GO_TRIANGLE: 00313 status = GO_STATUS_BAD_ARG; 00314 goObject->TouchActive = false; 00315 break; 00316 00317 case GO_LINE: 00318 Tft.drawLine( goObject->Xpos, goObject->Ypos, goObject->Xpos + \ 00319 goObject->Width - 1, goObject->Ypos + \ 00320 goObject->Height - 1, goObject->BackColor ); 00321 goObject->TouchActive = false; 00322 break; 00323 00324 default: 00325 status = GO_STATUS_BAD_ARG; 00326 } 00327 return status; 00328 } 00329 00330 void DisplayDriverDrawLogo( uint8_t *thisBmp, uint8_t xPos, uint8_t yPos ) 00331 { 00332 if( BmpReadHeader( thisBmp ) ) 00333 { 00334 DrawBmpFromFlash( thisBmp, xPos, yPos ); 00335 } 00336 } 00337 00338 GraphObjectStatus_t GraphObjectTouched( GraphObject_t* objects, \ 00339 uint8_t objectsCount, \ 00340 uint8_t* touchedObject) 00341 { 00342 uint8_t objScan; 00343 uint16_t x, y = 0; 00344 bool touched = false; 00345 GraphObjectStatus_t status = GO_STATUS_BAD_COORD; 00346 00347 DebugPin = 1; 00348 00349 if( Touch.isTouched( ) ) 00350 { 00351 Touch.readTouchData( x, y, touched ); 00352 00353 if( touched == true ) 00354 { 00355 for( objScan = 0; objScan < objectsCount; objScan++) 00356 { 00357 if( objects[objScan].TouchActive == true ) 00358 { 00359 if( ( y >= objects[objScan].Ypos ) && ( y <= ( objects[objScan].Ypos + objects[objScan].Height - 1 ) ) ) 00360 { 00361 if( ( x >= objects[objScan].Xpos ) && ( x <= ( objects[objScan].Xpos + objects[objScan].Width - 1 ) ) ) 00362 { 00363 *touchedObject = objects[objScan].Id; 00364 status = GO_STATUS_NOERR; 00365 break; // return the first object match and no scan of other following objects 00366 } 00367 } 00368 } 00369 } 00370 } 00371 } 00372 00373 DebugPin = 0; 00374 return status; 00375 } 00376 00377 static bool BmpReadHeader( uint8_t *thisBmp ) 00378 { 00379 uint16_t pos = 0; 00380 00381 Read16( thisBmp ); 00382 if( Read16( thisBmp ) != 0x4D42 ) 00383 { // read magic byte 00384 return false; 00385 } 00386 pos += 2; 00387 00388 // read file size 00389 pos += 4; 00390 pos += 4; // Skip creator bytes 00391 BmpImageoffset = Read32( thisBmp + pos ); 00392 pos += 4; 00393 // read DIB header 00394 pos +=4; 00395 BmpWidth = Read32( thisBmp + pos ); 00396 pos += 4; 00397 BmpHeight = Read32( thisBmp + pos ); 00398 pos += 4; 00399 if( Read16( thisBmp + pos ) != 1 ) 00400 { 00401 // number of color planes must be 1 00402 return false; 00403 } 00404 pos += 2; 00405 pos += 2; 00406 if( Read16( thisBmp + pos ) != 0 ) 00407 { 00408 return false; // compression not supported! 00409 } 00410 pos += 2; // Should really be 2?? 00411 return true; 00412 } 00413 00414 // LITTLE ENDIAN! 00415 static uint16_t Read16( uint8_t *src ) 00416 { 00417 uint16_t d; 00418 uint8_t b; 00419 b = *src; 00420 d = *( src + 1 ); 00421 d <<= 8; 00422 d |= b; 00423 return d; 00424 } 00425 00426 // LITTLE ENDIAN! 00427 static uint32_t Read32( uint8_t *src ) 00428 { 00429 uint32_t d; 00430 uint16_t b; 00431 00432 b = Read16( src ); 00433 d = Read16( src + 2 ); 00434 d <<= 16; 00435 d |= b; 00436 return d; 00437 } 00438 00439 static void DrawBmpFromFlash( uint8_t *thisBmp, int xPos, int yPos ) 00440 { 00441 uint16_t pos = BmpImageoffset; 00442 uint16_t p; // pixel 00443 uint8_t g; 00444 uint8_t b; 00445 int i, j; // line, column 00446 00447 for( i = BmpHeight; i > 0; i-- ) 00448 { 00449 for( j = 0; j < BmpWidth; j++ ) 00450 { 00451 b = *( thisBmp + pos++ ); 00452 g = *( thisBmp + pos++ ); 00453 p = *( thisBmp + pos++ ); 00454 00455 p >>= 3; 00456 p <<= 6; 00457 00458 g >>= 2; 00459 p |= g; 00460 p <<= 5; 00461 00462 b >>= 3; 00463 p |= b; 00464 00465 // write out the 16 bits of color 00466 Tft.setPixel( j + xPos, i + yPos, p ); 00467 } 00468 pos += 1; 00469 } 00470 }
Generated on Tue Jul 12 2022 15:49:22 by
![doxygen](doxygen.png)