Hexiwear OLED Display Driver
Dependents: Hexi_OLED_TextImage_Example Hexi_OLED_Text_Example Hexi_OLED_Image_Example security-console-app ... more
Hexi_OLED_SSD1351.cpp
00001 /** OLED Display Driver for Hexiwear 00002 * This file contains OLED driver functionality for drawing images and text 00003 * 00004 * Redistribution and use in source and binary forms, with or without modification, 00005 * are permitted provided that the following conditions are met: 00006 * 00007 * Redistributions of source code must retain the above copyright notice, this list 00008 * of conditions and the following disclaimer. 00009 * 00010 * Redistributions in binary form must reproduce the above copyright notice, this 00011 * list of conditions and the following disclaimer in the documentation and/or 00012 * other materials provided with the distribution. 00013 * 00014 * Neither the name of NXP, nor the names of its 00015 * contributors may be used to endorse or promote products derived from this 00016 * software without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00019 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00020 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00021 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00022 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00023 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00024 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00025 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00026 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00027 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00028 * 00029 * visit: http://www.mikroe.com and http://www.nxp.com 00030 * 00031 * get support at: http://www.mikroe.com/forum and https://community.nxp.com 00032 * 00033 * Project HEXIWEAR, 2015 00034 */ 00035 00036 #include "OLED_types.h" 00037 #include "OLED_info.h" 00038 #include "mbed.h" 00039 #include "Hexi_OLED_SSD1351.h" 00040 #include "OpenSans_Font.h" 00041 00042 const init_cmd_t seq[] = { 00043 OLED_CMD_SET_CMD_LOCK, CMD_BYTE, 00044 OLED_UNLOCK, DATA_BYTE, 00045 OLED_CMD_SET_CMD_LOCK, CMD_BYTE, 00046 OLED_ACC_TO_CMD_YES, DATA_BYTE, 00047 OLED_CMD_DISPLAYOFF, CMD_BYTE, 00048 OLED_CMD_SET_OSC_FREQ_AND_CLOCKDIV, CMD_BYTE, 00049 0xF1, DATA_BYTE, 00050 OLED_CMD_SET_MUX_RATIO, CMD_BYTE, 00051 0x5F, DATA_BYTE, 00052 OLED_CMD_SET_REMAP, CMD_BYTE, 00053 OLED_REMAP_SETTINGS, DATA_BYTE, 00054 OLED_CMD_SET_COLUMN, CMD_BYTE, 00055 0x00, DATA_BYTE, 00056 0x5F, DATA_BYTE, 00057 OLED_CMD_SET_ROW, CMD_BYTE, 00058 0x00, DATA_BYTE, 00059 0x5F, DATA_BYTE, 00060 OLED_CMD_STARTLINE, CMD_BYTE, 00061 0x80, DATA_BYTE, 00062 OLED_CMD_DISPLAYOFFSET, CMD_BYTE, 00063 0x60, DATA_BYTE, 00064 OLED_CMD_PRECHARGE, CMD_BYTE, 00065 0x32, CMD_BYTE, 00066 OLED_CMD_VCOMH, CMD_BYTE, 00067 0x05, CMD_BYTE, 00068 OLED_CMD_NORMALDISPLAY, CMD_BYTE, 00069 OLED_CMD_CONTRASTABC, CMD_BYTE, 00070 0x8A, DATA_BYTE, 00071 0x51, DATA_BYTE, 00072 0x8A, DATA_BYTE, 00073 OLED_CMD_CONTRASTMASTER, CMD_BYTE, 00074 0xCF, DATA_BYTE, 00075 OLED_CMD_SETVSL, CMD_BYTE, 00076 0xA0, DATA_BYTE, 00077 0xB5, DATA_BYTE, 00078 0x55, DATA_BYTE, 00079 OLED_CMD_PRECHARGE2, CMD_BYTE, 00080 0x01, DATA_BYTE, 00081 OLED_CMD_DISPLAYON, CMD_BYTE 00082 }; 00083 00084 00085 00086 SSD1351::SSD1351(PinName mosiPin,PinName sclkPin,PinName pwrPin, PinName csPin,PinName rstPin, PinName dcPin): spi(mosiPin,NC,sclkPin) , power(pwrPin), cs(csPin),rst(rstPin),dc(dcPin) 00087 { 00088 00089 spi.frequency(8000000); 00090 00091 00092 dc =0; 00093 PowerOFF(); 00094 wait_ms(1); 00095 rst = 0 ; 00096 wait_ms(1); 00097 rst = 1 ; 00098 wait_ms(1); 00099 PowerON(); 00100 00101 currentChar_width = 0, 00102 currentChar_height = 0; 00103 colorMask = COLOR_WHITE; 00104 00105 oled_text_properties.alignParam = OLED_TEXT_ALIGN_CENTER; 00106 oled_text_properties.background = NULL; 00107 oled_text_properties.font = OpenSans_10x15_Regular; 00108 oled_text_properties.fontColor = COLOR_WHITE; 00109 SetTextProperties(&oled_text_properties); 00110 00111 oled_dynamic_area.areaBuffer = NULL; 00112 oled_dynamic_area.height = 0; 00113 oled_dynamic_area.width = 0; 00114 oled_dynamic_area.xCrd = 0; 00115 oled_dynamic_area.yCrd = 0; 00116 00117 00118 for (int i=0;i<39;i++) 00119 { 00120 SendCmd(seq[i].cmd, seq[i].type); 00121 } 00122 00123 00124 00125 } 00126 00127 00128 SSD1351::~SSD1351(void) 00129 { 00130 //TO_DO 00131 //Run Free and zero pointers. 00132 00133 } 00134 00135 00136 00137 00138 void SSD1351::SendCmd(uint32_t cmd, 00139 uint8_t isFirst) 00140 { 00141 00142 00143 00144 uint8_t 00145 txSize = 1, 00146 txBuf[4]; 00147 00148 memcpy((void*)txBuf, (void*)&cmd, txSize ); 00149 00150 if (isFirst ) 00151 { 00152 dc = 0; 00153 } 00154 else 00155 { 00156 dc = 1; 00157 } 00158 00159 cs = 0; 00160 spi.write(*txBuf); 00161 cs = 1; 00162 00163 } 00164 00165 00166 00167 void SSD1351::SendData ( const uint8_t* dataToSend, 00168 uint32_t dataSize) 00169 00170 { 00171 00172 00173 uint16_t* arrayPtr = (uint16_t*)dataToSend; 00174 00175 for( uint32_t i = 0; i < dataSize/2; i++ ) 00176 { 00177 arrayPtr[i] &= colorMask; 00178 } 00179 00180 00181 SendCmd( OLED_CMD_WRITERAM, CMD_BYTE ); 00182 00183 /* sending data -> set DC pin */ 00184 dc = 1; 00185 cs = 0 ; 00186 00187 const uint8_t* 00188 /* traversing pointer */ 00189 bufPtr = dataToSend; 00190 00191 00192 for ( uint32_t i = 0; i < dataSize; i++) 00193 { 00194 spi.write(*bufPtr); 00195 bufPtr += 1; 00196 } 00197 00198 cs = 1; 00199 00200 } 00201 00202 00203 oled_status_t SSD1351::DrawBox ( 00204 int8_t xCrd, 00205 int8_t yCrd, 00206 uint8_t width, 00207 uint8_t height, 00208 uint16_t color 00209 ) 00210 { 00211 00212 oled_status_t status; 00213 oled_dynamic_area_t boxArea; 00214 00215 boxArea.xCrd = xCrd; 00216 boxArea.yCrd = yCrd; 00217 boxArea.width = width; 00218 boxArea.height = height; 00219 00220 uint32_t 00221 boxSize = width*height; 00222 00223 SetDynamicArea( &boxArea ); 00224 00225 /* helper pointer */ 00226 uint8_t* 00227 boxBuf = (uint8_t*)oled_dynamic_area.areaBuffer; 00228 00229 if ( NULL == boxBuf ) 00230 { 00231 00232 return OLED_STATUS_ERROR; 00233 } 00234 00235 /* check the bounds */ 00236 if AreCoordsNotValid( xCrd, yCrd, width, height ) 00237 { 00238 status = OLED_STATUS_INIT_ERROR; 00239 } 00240 00241 else 00242 { 00243 /* fill the buffer with color */ 00244 00245 for ( uint16_t i = 0; i < boxSize; i++ ) 00246 { 00247 boxBuf[ 2*i ] = color >> 8; 00248 boxBuf[ 2*i + 1 ] = color; 00249 } 00250 00251 /* set the locations */ 00252 00253 /* adjust for the offset */ 00254 OLED_AdjustColumnOffset(xCrd); 00255 OLED_AdjustRowOffset(yCrd); 00256 00257 SendCmd( OLED_CMD_SET_COLUMN, CMD_BYTE); 00258 SendCmd( xCrd, DATA_BYTE ); 00259 SendCmd( xCrd + (width-1), DATA_BYTE ); 00260 SendCmd( OLED_CMD_SET_ROW, CMD_BYTE ); 00261 SendCmd( yCrd, DATA_BYTE ); 00262 SendCmd( yCrd + (height-1), DATA_BYTE ); 00263 00264 /* fill the GRAM */ 00265 SendData( (uint8_t*)boxBuf, boxSize*OLED_BYTES_PER_PIXEL ); 00266 DestroyDynamicArea(); 00267 00268 } 00269 00270 return status; 00271 } 00272 00273 /** 00274 * fill the entire screen 00275 * @param color color to fill with 00276 * @return status flag 00277 */ 00278 void SSD1351::FillScreen( uint16_t color ) 00279 { 00280 /* fill the screen buffer with color */ 00281 for ( uint16_t i = 0; i < ( OLED_SCREEN_WIDTH * OLED_SCREEN_HEIGHT ); i++ ) 00282 { 00283 screenBuf[ 2*i ] = color >> 8; 00284 screenBuf[ 2*i + 1 ] = color; 00285 } 00286 00287 /* set the locations */ 00288 SetBorders( 0, 0, OLED_SCREEN_WIDTH, OLED_SCREEN_HEIGHT ); 00289 00290 /* fill GRAM */ 00291 SendData( (uint8_t*)screenBuf, OLED_SCREEN_WIDTH * OLED_SCREEN_HEIGHT * OLED_BYTES_PER_PIXEL ); 00292 00293 } 00294 00295 00296 00297 oled_status_t SSD1351::DrawPixel ( 00298 int8_t xCrd, 00299 int8_t yCrd, 00300 uint16_t color 00301 ) 00302 { 00303 /* check the bounds */ 00304 if AreCoordsNotValid( xCrd, yCrd, 1, 1 ) 00305 { 00306 return OLED_STATUS_INIT_ERROR; 00307 } 00308 00309 else 00310 { 00311 /* set directions */ 00312 SetBorders( xCrd, yCrd, OLED_SCREEN_WIDTH, OLED_SCREEN_HEIGHT); 00313 00314 uint16_t 00315 /* swap bytes */ 00316 dot = color; 00317 00318 OLED_SwapMe(dot); 00319 00320 /* fill the GRAM */ 00321 SendData( (uint8_t*)&dot, 2 ); 00322 00323 return OLED_STATUS_SUCCESS; 00324 } 00325 } 00326 00327 00328 oled_status_t SSD1351::DrawScreen ( 00329 const uint8_t* image, 00330 int8_t xCrd, 00331 int8_t yCrd, 00332 uint8_t width, 00333 uint8_t height, 00334 oled_transition_t transition 00335 ) 00336 { 00337 oled_status_t 00338 status = OLED_STATUS_SUCCESS; 00339 00340 if AreCoordsNotValid( xCrd, yCrd, width, height ) 00341 { 00342 return OLED_STATUS_INIT_ERROR; 00343 } 00344 00345 switch ( transition ) 00346 { 00347 case OLED_TRANSITION_NONE: { 00348 /* set the locations */ 00349 SetBorders( xCrd, yCrd, width, height); 00350 00351 /* fill the GRAM */ 00352 SendData( (const uint8_t*)image, width * height * OLED_BYTES_PER_PIXEL ); 00353 break; 00354 } 00355 00356 case OLED_TRANSITION_TOP_DOWN: { 00357 TopDown( image, xCrd, yCrd, width, height ); 00358 break; 00359 } 00360 00361 case OLED_TRANSITION_DOWN_TOP: { 00362 DownTop( image, xCrd, yCrd, width, height ); 00363 break; 00364 } 00365 00366 case OLED_TRANSITION_LEFT_RIGHT: { 00367 LeftRight( image, xCrd, yCrd, width, height ); 00368 break; 00369 } 00370 00371 case OLED_TRANSITION_RIGHT_LEFT: { 00372 RightLeft( image, xCrd, yCrd, width, height ); 00373 break; 00374 } 00375 00376 default: {} 00377 } 00378 00379 return status; 00380 } 00381 00382 00383 oled_status_t SSD1351::SetFont( 00384 const uint8_t* newFont, 00385 uint16_t newColor 00386 ) 00387 { 00388 /* save the new values in intern variables */ 00389 00390 selectedFont = newFont; 00391 selectedFont_firstChar = newFont[2] | ( (uint16_t)newFont[3] << 8 ); 00392 selectedFont_lastChar = newFont[4] | ( (uint16_t)newFont[5] << 8 ); 00393 selectedFont_height = newFont[6]; 00394 selectedFont_color = newColor; 00395 00396 OLED_SwapMe( selectedFont_color ); 00397 00398 return OLED_STATUS_SUCCESS; 00399 } 00400 00401 00402 void SSD1351::SetDynamicArea(oled_dynamic_area_t *dynamic_area) 00403 { 00404 00405 if( NULL == oled_dynamic_area.areaBuffer ) 00406 { 00407 oled_dynamic_area.areaBuffer = (oled_pixel_t)AllocateDynamicArea( dynamic_area->width * dynamic_area->height ); 00408 } 00409 else if( 00410 ( dynamic_area->height != oled_dynamic_area.height ) || 00411 ( dynamic_area->width != oled_dynamic_area.width ) 00412 ) 00413 { 00414 DestroyDynamicArea(); 00415 oled_dynamic_area.areaBuffer = (oled_pixel_t)AllocateDynamicArea( dynamic_area->width * dynamic_area->height ); 00416 } 00417 00418 oled_dynamic_area.xCrd = dynamic_area->xCrd; 00419 oled_dynamic_area.yCrd = dynamic_area->yCrd; 00420 oled_dynamic_area.width = dynamic_area->width; 00421 oled_dynamic_area.height = dynamic_area->height; 00422 } 00423 00424 00425 void SSD1351::DestroyDynamicArea() 00426 { 00427 if ( NULL != oled_dynamic_area.areaBuffer ) 00428 { 00429 DestroyDynamicArea( oled_dynamic_area.areaBuffer ); 00430 oled_dynamic_area.areaBuffer = NULL; 00431 } 00432 } 00433 00434 00435 void SSD1351::SetTextProperties(oled_text_properties_t *textProperties) 00436 { 00437 oled_text_properties.font = textProperties->font; 00438 oled_text_properties.fontColor = textProperties->fontColor; 00439 oled_text_properties.alignParam = textProperties->alignParam; 00440 oled_text_properties.background = textProperties->background; 00441 00442 SetFont( oled_text_properties.font, oled_text_properties.fontColor ); 00443 } 00444 00445 void SSD1351::GetTextProperties(oled_text_properties_t *textProperties) 00446 { 00447 textProperties->font = oled_text_properties.font; 00448 textProperties->fontColor = oled_text_properties.fontColor; 00449 textProperties->alignParam = oled_text_properties.alignParam; 00450 textProperties->background = oled_text_properties.background; 00451 } 00452 00453 uint8_t SSD1351::GetTextWidth(const uint8_t* text) 00454 { 00455 uint8_t chrCnt = 0; 00456 uint8_t text_width = 0; 00457 00458 while ( 0 != text[chrCnt] ) 00459 { 00460 text_width += *( selectedFont + 8 + (uint16_t)( ( text[chrCnt++] - selectedFont_firstChar ) << 2 ) ); 00461 /* make 1px space between chars */ 00462 text_width++; 00463 } 00464 /* remove the final space */ 00465 text_width--; 00466 00467 return text_width; 00468 } 00469 00470 00471 00472 uint8_t SSD1351::CharCount(uint8_t width, const uint8_t* font, const uint8_t* text, uint8_t length) 00473 { 00474 uint8_t chrCnt = 0; 00475 uint8_t text_width = 0; 00476 uint16_t firstChar; 00477 00478 firstChar = font[2] | ( (uint16_t)font[3] << 8 ); 00479 00480 while ( chrCnt < length ) 00481 { 00482 text_width += *( font + 8 + (uint16_t)( ( text[chrCnt++] - firstChar ) << 2 ) ); 00483 if(text_width > width) 00484 { 00485 chrCnt--; 00486 break; 00487 } 00488 /* make 1px space between chars */ 00489 text_width++; 00490 } 00491 00492 return chrCnt; 00493 } 00494 00495 00496 00497 00498 oled_status_t SSD1351::AddText( const uint8_t* text,int8_t xCrd, int8_t yCrd ) 00499 { 00500 uint16_t 00501 chrCnt = 0; 00502 oled_pixel_t 00503 chrBuf = NULL; 00504 00505 uint8_t 00506 currentChar_x = 0, 00507 currentChar_y = 0; 00508 00509 uint8_t 00510 text_height = 0, 00511 text_width = 0; 00512 00513 text_width = GetTextWidth(text); 00514 00515 /* 00516 * set default values, if necessary 00517 */ 00518 00519 text_height = selectedFont_height; 00520 oled_dynamic_area_t textArea; 00521 00522 textArea.width = text_width; 00523 textArea.height = text_height; 00524 textArea.xCrd = xCrd; 00525 textArea.yCrd = yCrd; 00526 SetDynamicArea(&textArea); 00527 00528 currentChar_y = ( oled_dynamic_area.height - text_height ) >> 1; 00529 00530 switch ( oled_text_properties.alignParam & OLED_TEXT_HALIGN_MASK ) 00531 { 00532 case OLED_TEXT_ALIGN_LEFT: 00533 { 00534 currentChar_x = 0; 00535 break; 00536 } 00537 00538 case OLED_TEXT_ALIGN_RIGHT: 00539 { 00540 currentChar_x = ( oled_dynamic_area.width - text_width ); 00541 break; 00542 } 00543 00544 case OLED_TEXT_ALIGN_CENTER: 00545 { 00546 currentChar_x += ( oled_dynamic_area.width - text_width ) >> 1 ; 00547 break; 00548 } 00549 00550 case OLED_TEXT_ALIGN_NONE: 00551 { 00552 break; 00553 } 00554 00555 default: {} 00556 } 00557 00558 if ( CreateTextBackground() != OLED_STATUS_SUCCESS ) 00559 { 00560 return OLED_STATUS_ERROR; 00561 } 00562 00563 /* 00564 * write the characters into designated space, one by one 00565 */ 00566 00567 chrCnt = 0; 00568 while ( 0 != text[chrCnt] ) 00569 { 00570 WriteCharToBuf( text[chrCnt++], &chrBuf ); 00571 00572 if ( NULL == chrBuf ) 00573 { 00574 return OLED_STATUS_INIT_ERROR; 00575 } 00576 00577 else 00578 { 00579 if ( 00580 ( ( currentChar_x + currentChar_width ) > oled_dynamic_area.width ) 00581 || ( ( currentChar_y + currentChar_height ) > oled_dynamic_area.height ) 00582 ) 00583 { 00584 DestroyDynamicArea( chrBuf ); 00585 chrBuf = NULL; 00586 return OLED_STATUS_ERROR; 00587 } 00588 00589 /* copy data */ 00590 oled_pixel_t 00591 copyAddr = oled_dynamic_area.areaBuffer + ( currentChar_y * oled_dynamic_area.width + currentChar_x ); 00592 00593 AddCharToTextArea( chrBuf, currentChar_width, currentChar_height, copyAddr, oled_dynamic_area.width ); 00594 00595 currentChar_x += ( currentChar_width+1 ); 00596 currentChar_y += 0; 00597 00598 DestroyDynamicArea( chrBuf ); 00599 chrBuf = NULL; 00600 } 00601 } 00602 00603 UpdateBuffer( 00604 oled_dynamic_area.xCrd, 00605 oled_dynamic_area.yCrd, 00606 oled_dynamic_area.width, 00607 oled_dynamic_area.height, 00608 (const uint8_t*)oled_dynamic_area.areaBuffer 00609 ); 00610 00611 return OLED_STATUS_SUCCESS; 00612 } 00613 00614 00615 oled_status_t SSD1351::AddText( const uint8_t* text) 00616 { 00617 uint16_t 00618 chrCnt = 0; 00619 oled_pixel_t 00620 chrBuf = NULL; 00621 00622 uint8_t 00623 currentChar_x = 0, 00624 currentChar_y = 0; 00625 00626 uint8_t 00627 text_height = 0, 00628 text_width = 0; 00629 00630 text_width = GetTextWidth(text); 00631 00632 /** 00633 * set default values, if necessary 00634 */ 00635 00636 text_height = selectedFont_height; 00637 00638 /* Disable this for now.Generated Fontwidth supposedly a lot wider than it really is*/ 00639 #if 0 00640 if (( oled_dynamic_area.width < text_width )||( oled_dynamic_area.height < text_height )) 00641 { 00642 oled_dynamic_area_t textArea; 00643 textArea.width = text_width; 00644 textArea.height = text_height; 00645 SetDynamicArea(&textArea); 00646 } 00647 #endif 00648 00649 currentChar_y = ( oled_dynamic_area.height - text_height ) >> 1; 00650 00651 switch ( oled_text_properties.alignParam & OLED_TEXT_HALIGN_MASK ) 00652 { 00653 case OLED_TEXT_ALIGN_LEFT: 00654 { 00655 currentChar_x = 0; 00656 break; 00657 } 00658 00659 case OLED_TEXT_ALIGN_RIGHT: 00660 { 00661 currentChar_x = ( oled_dynamic_area.width - text_width ); 00662 break; 00663 } 00664 00665 case OLED_TEXT_ALIGN_CENTER: 00666 { 00667 currentChar_x += ( oled_dynamic_area.width - text_width ) >> 1 ; 00668 break; 00669 } 00670 00671 case OLED_TEXT_ALIGN_NONE: 00672 { 00673 break; 00674 } 00675 00676 default: {} 00677 } 00678 00679 if ( CreateTextBackground() != OLED_STATUS_SUCCESS ) 00680 { 00681 return OLED_STATUS_ERROR; 00682 } 00683 00684 /** 00685 * write the characters into designated space, one by one 00686 */ 00687 00688 chrCnt = 0; 00689 while ( 0 != text[chrCnt] ) 00690 { 00691 WriteCharToBuf( text[chrCnt++], &chrBuf ); 00692 00693 if ( NULL == chrBuf ) 00694 { 00695 return OLED_STATUS_INIT_ERROR; 00696 } 00697 00698 else 00699 { 00700 if ( 00701 ( ( currentChar_x + currentChar_width ) > oled_dynamic_area.width ) 00702 || ( ( currentChar_y + currentChar_height ) > oled_dynamic_area.height ) 00703 ) 00704 { 00705 DestroyDynamicArea( chrBuf ); 00706 chrBuf = NULL; 00707 return OLED_STATUS_ERROR; 00708 } 00709 00710 /* copy data */ 00711 oled_pixel_t 00712 copyAddr = oled_dynamic_area.areaBuffer + ( currentChar_y * oled_dynamic_area.width + currentChar_x ); 00713 00714 AddCharToTextArea( chrBuf, currentChar_width, currentChar_height, copyAddr, oled_dynamic_area.width ); 00715 00716 currentChar_x += ( currentChar_width+1 ); 00717 currentChar_y += 0; 00718 00719 DestroyDynamicArea( chrBuf ); 00720 chrBuf = NULL; 00721 } 00722 } 00723 00724 UpdateBuffer( 00725 oled_dynamic_area.xCrd, 00726 oled_dynamic_area.yCrd, 00727 oled_dynamic_area.width, 00728 oled_dynamic_area.height, 00729 (const uint8_t*)oled_dynamic_area.areaBuffer 00730 ); 00731 00732 return OLED_STATUS_SUCCESS; 00733 } 00734 00735 00736 00737 oled_status_t SSD1351::DrawText( const uint8_t* text) 00738 { 00739 00740 if ( NULL == text ) 00741 { 00742 return OLED_STATUS_ERROR; 00743 } 00744 00745 AddText(text); 00746 /* set the locations */ 00747 SetBorders( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height ); 00748 /* fill the GRAM */ 00749 SendData( (const uint8_t*)oled_dynamic_area.areaBuffer, oled_dynamic_area.width * oled_dynamic_area.height * OLED_BYTES_PER_PIXEL ); 00750 00751 //free( currentTextAreaImage ); 00752 return OLED_STATUS_SUCCESS; 00753 } 00754 00755 00756 void SSD1351::GetImageDimensions(uint8_t *width, uint8_t *height, const uint8_t* image) 00757 { 00758 *height = image[2] + (image[3] << 8); 00759 *width = image[4] + (image[5] << 8); 00760 } 00761 00762 00763 oled_status_t SSD1351::AddImage ( const uint8_t* image ) 00764 { 00765 oled_status_t 00766 status = OLED_STATUS_SUCCESS; 00767 00768 /* check the bounds */ 00769 if AreCoordsNotValid( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height ) 00770 { 00771 status = OLED_STATUS_INIT_ERROR; 00772 } 00773 00774 else 00775 { 00776 Swap( (oled_pixel_t)oled_dynamic_area.areaBuffer, BMP_SkipHeader(image), oled_dynamic_area.width*oled_dynamic_area.height ); 00777 00778 /* update the main screen buffer */ 00779 UpdateBuffer( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height, (const uint8_t *)oled_dynamic_area.areaBuffer ); 00780 } 00781 00782 return status; 00783 } 00784 00785 00786 oled_status_t SSD1351::AddImage ( const uint8_t* image, int8_t xCrd, int8_t yCrd ) 00787 { 00788 oled_status_t 00789 status = OLED_STATUS_SUCCESS; 00790 00791 oled_dynamic_area_t image_dynamicArea; 00792 00793 image_dynamicArea.xCrd = xCrd; 00794 image_dynamicArea.yCrd = yCrd; 00795 00796 GetImageDimensions(&image_dynamicArea.width, &image_dynamicArea.height, image); 00797 SetDynamicArea(&image_dynamicArea); 00798 00799 /* check the bounds */ 00800 if AreCoordsNotValid( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height ) 00801 { 00802 status = OLED_STATUS_INIT_ERROR; 00803 } 00804 00805 else 00806 { 00807 Swap( (oled_pixel_t)oled_dynamic_area.areaBuffer, BMP_SkipHeader(image), oled_dynamic_area.width*oled_dynamic_area.height ); 00808 00809 /* update the main screen buffer */ 00810 UpdateBuffer( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height, (const uint8_t *)oled_dynamic_area.areaBuffer ); 00811 } 00812 00813 return status; 00814 } 00815 00816 00817 00818 oled_status_t SSD1351::DrawImage ( const uint8_t* image ) 00819 { 00820 00821 oled_status_t 00822 status = OLED_STATUS_SUCCESS; 00823 00824 status = AddImage( image ); 00825 00826 /* set the locations */ 00827 SetBorders( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height ); 00828 00829 /* fill the GRAM */ 00830 SendData( (const uint8_t*)oled_dynamic_area.areaBuffer, oled_dynamic_area.width * oled_dynamic_area.height * OLED_BYTES_PER_PIXEL ); 00831 00832 00833 return status; 00834 } 00835 00836 oled_status_t SSD1351::DrawImage ( const uint8_t* image, int8_t xCrd, int8_t yCrd ) 00837 { 00838 00839 oled_status_t 00840 status = OLED_STATUS_SUCCESS; 00841 00842 status = AddImage( image,xCrd,yCrd); 00843 00844 /* set the locations */ 00845 SetBorders( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height ); 00846 00847 /* fill the GRAM */ 00848 SendData( (const uint8_t*)oled_dynamic_area.areaBuffer, oled_dynamic_area.width * oled_dynamic_area.height * OLED_BYTES_PER_PIXEL ); 00849 00850 00851 return status; 00852 } 00853 00854 00855 00856 void SSD1351::DimScreenON() 00857 { 00858 for ( int i = 0; i < 16; i++ ) 00859 { 00860 SendCmd( OLED_CMD_CONTRASTMASTER, CMD_BYTE ); 00861 SendCmd( 0xC0 | (0xF-i), DATA_BYTE ); 00862 wait_ms(20); 00863 // OSA_TimeDelay( 20 ); 00864 } 00865 } 00866 00867 00868 void SSD1351::DimScreenOFF() 00869 { 00870 SendCmd( OLED_CMD_CONTRASTMASTER, CMD_BYTE ); 00871 SendCmd( 0xC0 | 0xF, DATA_BYTE ); 00872 } 00873 00874 00875 00876 void SSD1351::Swap( 00877 oled_pixel_t imgDst, 00878 const uint8_t* imgSrc, 00879 uint16_t imgSize 00880 ) 00881 { 00882 for ( int var = 0; var < imgSize; var++ ) 00883 { 00884 *imgDst = *imgSrc << 8; 00885 imgSrc++; 00886 *imgDst |= *imgSrc; 00887 imgDst++; 00888 imgSrc++; 00889 } 00890 } 00891 00892 00893 void SSD1351::PowerON() 00894 { 00895 power = 1; 00896 } 00897 00898 void SSD1351::PowerOFF() 00899 { 00900 power = 0; 00901 } 00902 00903 00904 00905 /* Formerly Known as GuiDriver_UpdateScreen */ 00906 void SSD1351::UpdateBuffer ( 00907 int8_t xCrd, 00908 int8_t yCrd, 00909 uint8_t width, 00910 uint8_t height, 00911 const uint8_t* image 00912 ) 00913 { 00914 /* copy data */ 00915 oled_pixel_t 00916 copyAddr = (oled_pixel_t)screenBuf + ( yCrd*OLED_SCREEN_WIDTH + xCrd ); 00917 00918 for ( uint8_t i = 0; i < height; i++ ) 00919 { 00920 memcpy( (void*)copyAddr, (void*)image, width*OLED_BYTES_PER_PIXEL ); 00921 copyAddr += OLED_SCREEN_WIDTH; 00922 image += width*OLED_BYTES_PER_PIXEL; 00923 } 00924 } 00925 00926 00927 oled_status_t SSD1351::Label ( const uint8_t* text,int8_t xCrd, int8_t yCrd ) 00928 { 00929 00930 if ( NULL == text ) 00931 { 00932 return OLED_STATUS_ERROR; 00933 } 00934 00935 AddText(text,xCrd,yCrd); 00936 00937 /* set the locations */ 00938 SetBorders( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height ); 00939 00940 /* fill the GRAM */ 00941 SendData( (const uint8_t*)oled_dynamic_area.areaBuffer, oled_dynamic_area.width * oled_dynamic_area.height * OLED_BYTES_PER_PIXEL ); 00942 00943 //free( currentTextAreaImage ); 00944 return OLED_STATUS_SUCCESS; 00945 } 00946 00947 00948 oled_status_t SSD1351::TextBox(const uint8_t* text, int8_t xCrd, int8_t yCrd,uint8_t width,uint8_t height) 00949 { 00950 00951 if ( NULL == text ) 00952 { 00953 return OLED_STATUS_ERROR; 00954 } 00955 00956 oled_dynamic_area_t textArea; 00957 textArea.width = width; 00958 textArea.height = height; 00959 textArea.xCrd = xCrd; 00960 textArea.yCrd = yCrd; 00961 00962 SetDynamicArea(&textArea); 00963 DrawText(text); 00964 00965 return OLED_STATUS_SUCCESS; 00966 00967 } 00968 00969 00970 /* Internal Functions */ 00971 00972 /** 00973 * [transpose description] 00974 * @param transImage Transposed Image 00975 * @param image Source Image 00976 * @param width Width to Transpose 00977 * @param height Height to Transpose 00978 */ 00979 void SSD1351::Transpose( 00980 oled_pixel_t transImage, 00981 const oled_pixel_t image, 00982 uint8_t width, 00983 uint8_t height 00984 ) 00985 { 00986 for ( uint8_t i = 0; i < height; i++ ) 00987 { 00988 for ( uint8_t j = 0; j < width ; j++ ) 00989 { 00990 transImage[ j*height + i ] = image[ i*width + j ]; 00991 } 00992 } 00993 } 00994 00995 00996 00997 /** 00998 * TopDown Transition Effect for Image 00999 * @param image image to be transitioned 01000 * @param xCrd x coordinate of image 01001 * @param yCrd y coordinate of image 01002 * @param width width of image 01003 * @param height height of image 01004 * @return status flag 01005 */ 01006 oled_status_t SSD1351::TopDown( 01007 const uint8_t* image, 01008 int8_t xCrd, 01009 int8_t yCrd, 01010 uint8_t width, 01011 uint8_t height 01012 ) 01013 { 01014 uint16_t 01015 transStep = OLED_TRANSITION_STEP; 01016 01017 uint16_t 01018 partImgSize = width*transStep; 01019 01020 oled_status_t 01021 status = OLED_STATUS_SUCCESS; 01022 01023 uint8_t* 01024 partImgPtr = (uint8_t*)image + ( height - transStep ) * ( width * OLED_BYTES_PER_PIXEL ); 01025 01026 /** 01027 * set locations 01028 */ 01029 01030 while (1) 01031 { 01032 SetBorders( xCrd, yCrd, width, height ); 01033 01034 if ( partImgSize > width*height ) 01035 { 01036 SendData( (const uint8_t*)image, width*height*OLED_BYTES_PER_PIXEL ); 01037 break; 01038 } 01039 else 01040 { 01041 SendData( (const uint8_t*)partImgPtr, partImgSize * OLED_BYTES_PER_PIXEL ); 01042 } 01043 01044 01045 /** 01046 * update variables 01047 */ 01048 01049 partImgPtr -= ( width * transStep ) * OLED_BYTES_PER_PIXEL; 01050 partImgSize += ( width * transStep ); 01051 transStep++; 01052 } 01053 01054 return status; 01055 } 01056 01057 /** 01058 * DownTop Transition Effect for Image 01059 * @param image image to be transitioned 01060 * @param xCrd x coordinate of image 01061 * @param yCrd y coordinate of image 01062 * @param width width of image 01063 * @param height height of image 01064 * @return status flag 01065 */ 01066 01067 oled_status_t SSD1351::DownTop( 01068 const uint8_t* image, 01069 int8_t xCrd, 01070 int8_t yCrd, 01071 uint8_t width, 01072 uint8_t height 01073 ) 01074 { 01075 uint16_t 01076 transStep = OLED_TRANSITION_STEP; 01077 01078 uint16_t 01079 partImgSize = width*transStep; 01080 01081 oled_status_t 01082 status = OLED_STATUS_SUCCESS; 01083 01084 uint8_t* 01085 partImgPtr = (uint8_t*)image; 01086 01087 uint8_t 01088 yCrd_moving = ( yCrd + height ) - 1; 01089 01090 /** 01091 * set locations 01092 */ 01093 01094 while (1) 01095 { 01096 if ( 01097 ( partImgSize > OLED_SCREEN_SIZE ) 01098 || ( yCrd_moving < yCrd ) 01099 ) 01100 { 01101 /* draw full image */ 01102 SetBorders( xCrd, yCrd, width, height ); 01103 SendData( (const uint8_t*)image, width * height * OLED_BYTES_PER_PIXEL ); 01104 break; 01105 } 01106 01107 else 01108 { 01109 SetBorders( xCrd, yCrd_moving, width, ( yCrd + height ) - yCrd_moving ); 01110 SendData( (const uint8_t*)partImgPtr, partImgSize * OLED_BYTES_PER_PIXEL ); 01111 } 01112 01113 /** 01114 * update variables 01115 */ 01116 01117 yCrd_moving -= transStep; 01118 partImgSize += ( width * transStep ); 01119 transStep++; 01120 } 01121 01122 return status; 01123 } 01124 01125 01126 /** 01127 * LeftRight Transition Effect for Image 01128 * @param image image to be transitioned 01129 * @param xCrd x coordinate of image 01130 * @param yCrd y coordinate of image 01131 * @param width width of image 01132 * @param height height of image 01133 * @return status flag 01134 */ 01135 01136 oled_status_t SSD1351::LeftRight( 01137 const uint8_t* image, 01138 int8_t xCrd, 01139 int8_t yCrd, 01140 uint8_t width, 01141 uint8_t height 01142 ) 01143 { 01144 oled_status_t 01145 status = OLED_STATUS_SUCCESS; 01146 01147 oled_dynamic_area_t 01148 transImageArea = 01149 { 01150 .xCrd = 0, 01151 .yCrd = 0, 01152 01153 .width = 96, 01154 .height= 96 01155 }; 01156 01157 SetDynamicArea( &transImageArea ); 01158 01159 /* helper pointer */ 01160 oled_pixel_t 01161 transImage = (oled_pixel_t)oled_dynamic_area.areaBuffer; 01162 01163 if ( NULL == transImage ) 01164 { 01165 return OLED_STATUS_INIT_ERROR; 01166 } 01167 01168 Transpose( transImage,(oled_pixel_t)image, width, height ); 01169 01170 SendCmd( OLED_CMD_SET_REMAP, CMD_BYTE ); 01171 SendCmd( OLED_REMAP_SETTINGS | REMAP_VERTICAL_INCREMENT, DATA_BYTE ); 01172 01173 uint16_t 01174 transStep = OLED_TRANSITION_STEP; 01175 01176 uint16_t 01177 partImgSize = height*transStep; 01178 01179 uint8_t* 01180 partImgPtr = (uint8_t*)transImage + ( width - transStep ) * ( height * OLED_BYTES_PER_PIXEL ); 01181 01182 /** 01183 * set locations 01184 */ 01185 01186 while (1) 01187 { 01188 SetBorders( xCrd, yCrd, width, height ); 01189 01190 if ( partImgSize > width*height ) 01191 { 01192 SendData((const uint8_t*)transImage, width * height * OLED_BYTES_PER_PIXEL ); 01193 break; 01194 } 01195 else 01196 { 01197 SendData( (const uint8_t*)partImgPtr, partImgSize * OLED_BYTES_PER_PIXEL ); 01198 } 01199 01200 01201 partImgPtr -= ( transStep * height ) * OLED_BYTES_PER_PIXEL; 01202 partImgSize += ( transStep * height ); 01203 transStep++; 01204 01205 } 01206 01207 SendCmd( OLED_CMD_SET_REMAP, CMD_BYTE ); 01208 SendCmd( OLED_REMAP_SETTINGS, DATA_BYTE ); 01209 DestroyDynamicArea(); 01210 return status; 01211 } 01212 01213 01214 /** 01215 * RightLeft Transition Effect for Image 01216 * @param image image to be transitioned 01217 * @param xCrd x coordinate of image 01218 * @param yCrd y coordinate of image 01219 * @param width width of image 01220 * @param height height of image 01221 * @return status flag 01222 */ 01223 oled_status_t SSD1351::RightLeft( 01224 const uint8_t* image, 01225 int8_t xCrd, 01226 int8_t yCrd, 01227 uint8_t width, 01228 uint8_t height 01229 ) 01230 { 01231 oled_dynamic_area_t 01232 transImageArea = 01233 { 01234 .xCrd = 0, 01235 .yCrd = 0, 01236 01237 .width = 96, 01238 .height= 96 01239 }; 01240 01241 SetDynamicArea( &transImageArea ); 01242 01243 /* helper pointer */ 01244 oled_pixel_t 01245 transImage = oled_dynamic_area.areaBuffer; 01246 01247 if ( NULL == transImage ) 01248 { 01249 return OLED_STATUS_INIT_ERROR; 01250 } 01251 01252 Transpose(transImage, (oled_pixel_t)image, width, height ); 01253 01254 SendCmd( OLED_CMD_SET_REMAP, CMD_BYTE ); 01255 SendCmd( OLED_REMAP_SETTINGS | REMAP_VERTICAL_INCREMENT, DATA_BYTE ); 01256 01257 01258 uint16_t 01259 transStep = OLED_TRANSITION_STEP; 01260 01261 uint16_t 01262 partImgSize = height * transStep; 01263 01264 uint8_t* 01265 partImgPtr = (uint8_t*)transImage; 01266 01267 uint8_t 01268 xCrd_moving = ( xCrd + width ) - 1; 01269 01270 /** set locations */ 01271 01272 while (1) 01273 { 01274 if (( partImgSize > width*height )|| ( xCrd_moving < xCrd )) 01275 { 01276 SetBorders( xCrd, yCrd, width, height ); 01277 SendData( (const uint8_t*)transImage, height * width * OLED_BYTES_PER_PIXEL ); 01278 break; 01279 } 01280 else 01281 { 01282 SetBorders( xCrd_moving, yCrd, ( xCrd + width ) - xCrd_moving, height ); 01283 SendData( (const uint8_t*)partImgPtr, partImgSize * OLED_BYTES_PER_PIXEL ); 01284 } 01285 01286 /** update variables*/ 01287 01288 xCrd_moving -= transStep; 01289 partImgSize += ( height * transStep ); 01290 transStep++; 01291 } 01292 01293 SendCmd( OLED_CMD_SET_REMAP, CMD_BYTE ); 01294 SendCmd( OLED_REMAP_SETTINGS, DATA_BYTE ); 01295 01296 DestroyDynamicArea(); 01297 01298 return OLED_STATUS_SUCCESS; 01299 } 01300 01301 01302 /** 01303 * [setDirection description] 01304 * @param self [description] 01305 * @param xCrd [description] 01306 * @param yCrd [description] 01307 * @return [description] 01308 */ 01309 void SSD1351::SetBorders( 01310 int8_t xCrd, 01311 int8_t yCrd, 01312 uint8_t width, 01313 uint8_t height 01314 ) 01315 { 01316 01317 /* adjust for the offset*/ 01318 OLED_AdjustColumnOffset(xCrd); 01319 OLED_AdjustRowOffset(yCrd); 01320 01321 SendCmd( OLED_CMD_SET_COLUMN, CMD_BYTE ); 01322 SendCmd( xCrd, DATA_BYTE ); 01323 SendCmd( xCrd + (width-1), DATA_BYTE ); 01324 SendCmd( OLED_CMD_SET_ROW, CMD_BYTE ); 01325 SendCmd( yCrd, DATA_BYTE ); 01326 SendCmd( yCrd + (height-1), DATA_BYTE ); 01327 01328 } 01329 01330 /** 01331 * create the buffer for a partial image 01332 * @param imgBuf [description] 01333 * @param width [description] 01334 * @param height [description] 01335 * @return [description] 01336 */ 01337 oled_status_t SSD1351::CreateTextBackground() 01338 { 01339 uint8_t 01340 xCrd = oled_dynamic_area.xCrd, 01341 yCrd = oled_dynamic_area.yCrd, 01342 width = oled_dynamic_area.width, 01343 height = oled_dynamic_area.height; 01344 01345 oled_pixel_t 01346 imgBuf = oled_dynamic_area.areaBuffer, 01347 copyAddr; 01348 01349 const uint8_t* 01350 background = oled_text_properties.background; 01351 01352 /* copy data */ 01353 01354 if ( 01355 ( NULL == imgBuf ) 01356 || ( ( xCrd + width ) > OLED_SCREEN_WIDTH ) 01357 || ( ( yCrd + height ) > OLED_SCREEN_HEIGHT ) 01358 ) 01359 { 01360 return OLED_STATUS_INIT_ERROR; 01361 } 01362 01363 if ( NULL == background ) 01364 { 01365 for ( uint8_t i = 0; i < height; i++ ) 01366 { 01367 memset( (void*)imgBuf, 0, width*OLED_BYTES_PER_PIXEL ); 01368 imgBuf += width; 01369 } 01370 } 01371 01372 else 01373 { 01374 copyAddr = (oled_pixel_t)( BMP_SkipHeader( background ) ) + ( yCrd*OLED_SCREEN_WIDTH + xCrd ); 01375 for ( uint8_t i = 0; i < height; i++ ) 01376 { 01377 Swap( (oled_pixel_t)imgBuf, (const uint8_t*)copyAddr, width ); 01378 imgBuf += width; 01379 copyAddr += OLED_SCREEN_WIDTH; 01380 } 01381 } 01382 01383 return OLED_STATUS_SUCCESS; 01384 } 01385 01386 01387 /** 01388 * Write the character to Buffer 01389 * @param charToWrite character to be written 01390 * @param chrBuf given pointer for buffer for the character 01391 */ 01392 void SSD1351::WriteCharToBuf( 01393 uint16_t charToWrite, 01394 oled_pixel_t* chrBuf 01395 ) 01396 { 01397 uint8_t 01398 foo = 0, 01399 mask; 01400 01401 const uint8_t* 01402 pChTable = selectedFont + 8 + (uint16_t)( ( charToWrite - selectedFont_firstChar ) << 2 ); 01403 01404 currentChar_width = *pChTable, 01405 currentChar_height = selectedFont_height; 01406 01407 uint32_t 01408 offset = (uint32_t)pChTable[1] 01409 | ( (uint32_t)pChTable[2] << 8 ) 01410 | ( (uint32_t)pChTable[3] << 16 ); 01411 01412 const uint8_t* 01413 pChBitMap = selectedFont + offset; 01414 01415 /* allocate space for char image */ 01416 *chrBuf = (oled_pixel_t)AllocateDynamicArea( currentChar_height * currentChar_width ); 01417 01418 if ( NULL == *chrBuf ) 01419 { 01420 return; 01421 } 01422 01423 for ( uint8_t yCnt = 0; yCnt < currentChar_height; yCnt++ ) 01424 { 01425 mask = 0; 01426 01427 for ( uint8_t xCnt = 0; xCnt < currentChar_width; xCnt++ ) 01428 { 01429 if ( 0 == mask ) 01430 { 01431 mask = 1; 01432 foo = *pChBitMap++; 01433 } 01434 01435 if ( 0 != ( foo & mask ) ) 01436 { 01437 *( *chrBuf + yCnt*currentChar_width + xCnt ) = selectedFont_color; 01438 } 01439 01440 else 01441 { 01442 *( *chrBuf + yCnt*currentChar_width + xCnt ) = 0; 01443 } 01444 01445 mask <<= 1; 01446 } 01447 } 01448 } 01449 01450 01451 /** 01452 * Add subimage/character to the active image buffer 01453 * @param xOffset offset for the x-coordinate 01454 * @param yOffset offset for the y-coordinate 01455 * @param width desired width 01456 * @param height desired height 01457 * @return status flag 01458 */ 01459 oled_status_t SSD1351::AddCharToTextArea( 01460 oled_pixel_t chrPtr, 01461 uint8_t chrWidth, 01462 uint8_t chrHeight, 01463 oled_pixel_t copyAddr, 01464 uint8_t imgWidth 01465 ) 01466 { 01467 if ( NULL == copyAddr ) 01468 { 01469 return OLED_STATUS_INIT_ERROR; 01470 } 01471 01472 for ( uint8_t i = 0; i < chrHeight; i++ ) 01473 { 01474 for ( uint8_t j = 0; j < chrWidth; j++ ) 01475 { 01476 if ( 0 != chrPtr[j] ) 01477 { 01478 copyAddr[j] = chrPtr[j]; 01479 } 01480 } 01481 copyAddr += imgWidth; 01482 chrPtr += chrWidth; 01483 } 01484 return OLED_STATUS_SUCCESS; 01485 } 01486 01487 01488 /** 01489 * Allocate memory for the desired image/character 01490 * @param area desired area dimensions 01491 */ 01492 void* SSD1351::AllocateDynamicArea( uint32_t area ) 01493 { 01494 void* 01495 ptr = malloc( area * OLED_BYTES_PER_PIXEL ); 01496 01497 if ( NULL == ptr ) 01498 { 01499 return NULL; 01500 } 01501 01502 return ptr; 01503 } 01504 01505 01506 /** 01507 * Deallocate current area 01508 * @param area pointer to current area 01509 */ 01510 oled_status_t SSD1351::DestroyDynamicArea( void* ptr ) 01511 { 01512 if ( NULL == ptr ) 01513 { 01514 return OLED_STATUS_INIT_ERROR; 01515 } 01516 01517 free(ptr); 01518 01519 return OLED_STATUS_SUCCESS; 01520 }
Generated on Thu Jul 14 2022 13:01:27 by
1.7.2