Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Hexi_OLED_TextImage_Example Hexi_OLED_Text_Example Hexi_OLED_Image_Example security-console-app ... more
Revision 1:3b5be0ee5f0c, committed 2016-08-18
- Comitter:
- khuang
- Date:
- Thu Aug 18 23:01:06 2016 +0000
- Parent:
- 0:06f42dd3eab3
- Child:
- 2:fc06b5b5bf6a
- Commit message:
- Hexiwear OLED Display Driver enabled.; Allow images and text to be displayed.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexi_OLED_SSD1351.cpp Thu Aug 18 23:01:06 2016 +0000
@@ -0,0 +1,1531 @@
+#include "OLED_types.h"
+#include "OLED_info.h"
+#include "mbed.h"
+#include "Hexi_OLED_SSD1351.h"
+#include "OLED_fonts.h"
+
+/* oled_init arrays*/
+const uint32_t oled_init_cmd[] = {
+ OLED_CMD_SET_CMD_LOCK,
+ OLED_UNLOCK,
+ OLED_CMD_SET_CMD_LOCK,
+ OLED_ACC_TO_CMD_YES,
+ OLED_CMD_DISPLAYOFF,
+ OLED_CMD_SET_OSC_FREQ_AND_CLOCKDIV,
+ 0xF1,
+ OLED_CMD_SET_MUX_RATIO,
+ 0x5F,
+ OLED_CMD_SET_REMAP,
+ OLED_REMAP_SETTINGS,
+ OLED_CMD_SET_COLUMN,
+ 0x00,
+ 0x5F,
+ OLED_CMD_SET_ROW,
+ 0x00,
+ 0x5F,
+ OLED_CMD_STARTLINE,
+ 0x80,
+ OLED_CMD_DISPLAYOFFSET,
+ 0x60,
+ OLED_CMD_PRECHARGE,
+ 0x32,
+ OLED_CMD_VCOMH,
+ 0x05,
+ OLED_CMD_NORMALDISPLAY,
+ OLED_CMD_CONTRASTABC,
+ 0x8A,
+ 0x51,
+ 0x8A,
+ OLED_CMD_CONTRASTMASTER,
+ 0xCF,
+ OLED_CMD_SETVSL,
+ 0xA0,
+ 0xB5,
+ 0x55,
+ OLED_CMD_PRECHARGE2,
+ 0x01,
+ OLED_CMD_DISPLAYON };
+
+
+const uint8_t oled_init_isFirst[] = {
+ FIRST_BYTE,
+ OTHER_BYTE,
+ FIRST_BYTE,
+ OTHER_BYTE,
+ FIRST_BYTE,
+ FIRST_BYTE,
+ OTHER_BYTE,
+ FIRST_BYTE,
+ OTHER_BYTE,
+ FIRST_BYTE,
+ OTHER_BYTE,
+ FIRST_BYTE,
+ OTHER_BYTE,
+ OTHER_BYTE,
+ FIRST_BYTE,
+ OTHER_BYTE,
+ OTHER_BYTE,
+ FIRST_BYTE,
+ OTHER_BYTE,
+ FIRST_BYTE,
+ OTHER_BYTE,
+ FIRST_BYTE,
+ FIRST_BYTE,
+ FIRST_BYTE,
+ FIRST_BYTE,
+ FIRST_BYTE,
+ FIRST_BYTE,
+ OTHER_BYTE,
+ OTHER_BYTE,
+ OTHER_BYTE,
+ FIRST_BYTE,
+ OTHER_BYTE,
+ FIRST_BYTE,
+ OTHER_BYTE,
+ OTHER_BYTE,
+ OTHER_BYTE,
+ FIRST_BYTE,
+ OTHER_BYTE,
+ FIRST_BYTE};
+
+
+
+
+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)
+{
+
+ spi.frequency(8000000);
+
+
+ dc =0;
+ PowerOFF();
+ wait_ms(1);
+ rst = 0 ;
+ wait_ms(1);
+ rst = 1 ;
+ wait_ms(1);
+ PowerON();
+
+ isFontInitialized = 0 ;
+ currentChar_width = 0,
+ currentChar_height = 0;
+ colorMask = COLOR_WHITE;
+
+ oled_text_properties.alignParam = OLED_TEXT_ALIGN_CENTER;
+ oled_text_properties.background = NULL;
+ oled_text_properties.font = oledFont_Tahoma_8_Regular;
+ oled_text_properties.fontColor = COLOR_RED;
+
+ oled_dynamic_area.areaBuffer = NULL;
+ oled_dynamic_area.height = 0;
+ oled_dynamic_area.width = 0;
+ oled_dynamic_area.xCrd = 0;
+ oled_dynamic_area.yCrd = 0;
+
+
+
+ for (int i=0;i<39;i++)
+ {
+ SendCmd(oled_init_cmd[i],oled_init_isFirst[i]);
+ }
+
+
+
+}
+
+
+SSD1351::~SSD1351(void)
+{
+
+ //Run Free and zero pointers.
+}
+
+
+
+
+void SSD1351::SendCmd(uint32_t cmd,
+ uint8_t isFirst)
+{
+
+
+
+ uint8_t
+ txSize = 1,
+ txBuf[4];
+
+ memcpy((void*)txBuf, (void*)&cmd, txSize );
+
+ if (isFirst )
+ {
+ dc = 0;
+ }
+ else
+ {
+ dc = 1;
+ }
+
+ cs = 0;
+ spi.write(*txBuf);
+ cs = 1;
+
+}
+
+
+
+void SSD1351::SendData ( const uint8_t* dataToSend,
+ uint32_t dataSize)
+
+{
+
+
+ uint16_t* arrayPtr = (uint16_t*)dataToSend;
+
+ for( uint32_t i = 0; i < dataSize/2; i++ )
+ {
+ arrayPtr[i] &= colorMask;
+ }
+
+
+ this->SendCmd( OLED_CMD_WRITERAM, FIRST_BYTE );
+
+
+ // sending data -> set DC pin
+
+ dc = 1;
+ cs = 0 ;
+
+
+ const uint8_t*
+ // traversing pointer
+ bufPtr = dataToSend;
+
+
+ for ( uint32_t i = 0; i < dataSize; i++)
+ {
+ spi.write(*bufPtr);
+ bufPtr += 1;
+ }
+
+
+ cs = 1;
+
+}
+
+
+oled_status_t SSD1351::DrawBox (
+ uint16_t xCrd,
+ uint16_t yCrd,
+ uint16_t width,
+ uint16_t height,
+ uint16_t color
+ )
+{
+
+ oled_status_t status;
+ oled_dynamic_area_t boxArea;
+
+ boxArea.xCrd = xCrd;
+ boxArea.yCrd = yCrd;
+ boxArea.width = width;
+ boxArea.height = height;
+
+ uint32_t
+ boxSize = width*height;
+
+ SetDynamicArea( &boxArea );
+
+ // helper pointer
+ uint8_t*
+ boxBuf = (uint8_t*)oled_dynamic_area.areaBuffer;
+
+ if ( NULL == boxBuf )
+ {
+
+ return OLED_STATUS_ERROR;
+ }
+
+ // check the bounds
+ if AreCoordsNotValid( xCrd, yCrd, width, height )
+ {
+ status = OLED_STATUS_INIT_ERROR;
+ }
+
+ else
+ {
+ /** fill the buffer with color */
+
+ for ( uint16_t i = 0; i < boxSize; i++ )
+ {
+ boxBuf[ 2*i ] = color >> 8;
+ boxBuf[ 2*i + 1 ] = color;
+ }
+
+ /** set the locations */
+
+ // adjust for the offset
+ OLED_AdjustColumnOffset(xCrd);
+ OLED_AdjustRowOffset(yCrd);
+
+ SendCmd( OLED_CMD_SET_COLUMN, FIRST_BYTE);
+ SendCmd( xCrd, OTHER_BYTE );
+ SendCmd( xCrd + (width-1), OTHER_BYTE );
+ SendCmd( OLED_CMD_SET_ROW, FIRST_BYTE );
+ SendCmd( yCrd, OTHER_BYTE );
+ SendCmd( yCrd + (height-1), OTHER_BYTE );
+
+
+ // fill the GRAM
+ SendData( (uint8_t*)boxBuf, boxSize*OLED_BYTES_PER_PIXEL );
+
+ DestroyDynamicArea();
+
+ }
+
+ return status;
+}
+
+/**
+ * fill the entire screen
+ * @param color color to fill with
+ * @return status flag
+ */
+void SSD1351::FillScreen( uint16_t color )
+{
+ /** fill the screen buffer with color */
+ for ( uint16_t i = 0; i < ( OLED_SCREEN_WIDTH * OLED_SCREEN_HEIGHT ); i++ )
+ {
+ screenBuf[ 2*i ] = color >> 8;
+ screenBuf[ 2*i + 1 ] = color;
+ }
+
+ /** set the locations */
+ SetBorders( 0, 0, OLED_SCREEN_WIDTH, OLED_SCREEN_HEIGHT );
+
+ /** fill GRAM */
+ SendData( (uint8_t*)screenBuf, OLED_SCREEN_WIDTH * OLED_SCREEN_HEIGHT * OLED_BYTES_PER_PIXEL );
+
+}
+
+
+
+oled_status_t SSD1351::DrawPixel (
+ int16_t xCrd,
+ int16_t yCrd,
+ uint16_t color
+ )
+{
+ // check the bounds
+ if AreCoordsNotValid( xCrd, yCrd, 1, 1 )
+ {
+ return OLED_STATUS_INIT_ERROR;
+ }
+
+ else
+ {
+ // set directions
+ SetBorders( xCrd, yCrd, OLED_SCREEN_WIDTH, OLED_SCREEN_HEIGHT);
+
+ uint16_t
+ // swap bytes
+ dot = color;
+
+ OLED_SwapMe(dot);
+
+ // fill the GRAM
+ SendData( (uint8_t*)&dot, 2 );
+
+ return OLED_STATUS_SUCCESS;
+ }
+}
+
+
+oled_status_t SSD1351::DrawScreen (
+ const uint8_t* image,
+ uint8_t xCrd,
+ uint8_t yCrd,
+ uint8_t width,
+ uint8_t height,
+ oled_transition_t transition
+ )
+{
+ oled_status_t
+ status = OLED_STATUS_SUCCESS;
+
+ if AreCoordsNotValid( xCrd, yCrd, width, height )
+ {
+ return OLED_STATUS_INIT_ERROR;
+ }
+
+ switch ( transition )
+ {
+ case OLED_TRANSITION_NONE: {
+ /** set the locations */
+ SetBorders( xCrd, yCrd, width, height);
+
+ // fill the GRAM
+ SendData( (const uint8_t*)image, width * height * OLED_BYTES_PER_PIXEL );
+ break;
+ }
+
+ case OLED_TRANSITION_TOP_DOWN: {
+ TopDown( image, xCrd, yCrd, width, height );
+ break;
+ }
+
+ case OLED_TRANSITION_DOWN_TOP: {
+ DownTop( image, xCrd, yCrd, width, height );
+ break;
+ }
+
+ case OLED_TRANSITION_LEFT_RIGHT: {
+ LeftRight( image, xCrd, yCrd, width, height );
+ break;
+ }
+
+ case OLED_TRANSITION_RIGHT_LEFT: {
+ RightLeft( image, xCrd, yCrd, width, height );
+ break;
+ }
+
+ default: {}
+ }
+
+ return status;
+}
+
+
+oled_status_t SSD1351::SetFont(
+ const uint8_t* newFont,
+ uint16_t newColor
+ )
+{
+ /** save the new values in intern variables */
+
+ selectedFont = newFont;
+ // selectedFont_firstChar = newFont[2] + (newFont[3] << 8);
+ selectedFont_firstChar = newFont[2] | ( (uint16_t)newFont[3] << 8 );
+ // selectedFont_lastChar = newFont[4] + (newFont[5] << 8);
+ selectedFont_lastChar = newFont[4] | ( (uint16_t)newFont[5] << 8 );
+ selectedFont_height = newFont[6];
+ selectedFont_color = newColor;
+
+ OLED_SwapMe( selectedFont_color );
+
+ isFontInitialized = 1;
+ return OLED_STATUS_SUCCESS;
+}
+
+
+void SSD1351::SetDynamicArea(oled_dynamic_area_t *dynamic_area)
+{
+
+ if( NULL == oled_dynamic_area.areaBuffer )
+ {
+ oled_dynamic_area.areaBuffer = (oled_pixel_t)AllocateDynamicArea( dynamic_area->width * dynamic_area->height );
+ }
+ else if(
+ ( dynamic_area->height != oled_dynamic_area.height ) ||
+ ( dynamic_area->width != oled_dynamic_area.width )
+ )
+ {
+ DestroyDynamicArea();
+ oled_dynamic_area.areaBuffer = (oled_pixel_t)AllocateDynamicArea( dynamic_area->width * dynamic_area->height );
+ }
+
+ oled_dynamic_area.xCrd = dynamic_area->xCrd;
+ oled_dynamic_area.yCrd = dynamic_area->yCrd;
+ oled_dynamic_area.width = dynamic_area->width;
+ oled_dynamic_area.height = dynamic_area->height;
+}
+
+
+void SSD1351::DestroyDynamicArea()
+{
+ if ( NULL != oled_dynamic_area.areaBuffer )
+ {
+ DestroyDynamicArea( oled_dynamic_area.areaBuffer );
+ oled_dynamic_area.areaBuffer = NULL;
+ }
+}
+
+
+void SSD1351::SetTextProperties(oled_text_properties_t *textProperties)
+{
+ oled_text_properties.font = textProperties->font;
+ oled_text_properties.fontColor = textProperties->fontColor;
+ oled_text_properties.alignParam = textProperties->alignParam;
+ oled_text_properties.background = textProperties->background;
+
+ SetFont( oled_text_properties.font, oled_text_properties.fontColor );
+}
+
+
+
+
+uint8_t SSD1351::GetTextWidth(const uint8_t* text)
+{
+ uint8_t chrCnt = 0;
+ uint8_t text_width = 0;
+
+ while ( 0 != text[chrCnt] )
+ {
+ text_width += *( selectedFont + 8 + (uint16_t)( ( text[chrCnt++] - selectedFont_firstChar ) << 2 ) );
+ // make 1px space between chars
+ text_width++;
+ }
+ // remove the final space
+ text_width--;
+
+ return text_width;
+}
+
+
+
+uint8_t SSD1351::CharCount(uint8_t width, const uint8_t* font, const uint8_t* text, uint8_t length)
+{
+ uint8_t chrCnt = 0;
+ uint8_t text_width = 0;
+ uint16_t firstChar;
+
+ firstChar = font[2] | ( (uint16_t)font[3] << 8 );
+
+ while ( chrCnt < length )
+ {
+ text_width += *( font + 8 + (uint16_t)( ( text[chrCnt++] - firstChar ) << 2 ) );
+ if(text_width > width)
+ {
+ chrCnt--;
+ break;
+ }
+ // make 1px space between chars
+ text_width++;
+ }
+
+ return chrCnt;
+}
+
+
+
+
+oled_status_t SSD1351::AddText( const uint8_t* text,uint8_t xCrd, uint8_t yCrd )
+{
+ uint16_t
+ chrCnt = 0;
+ oled_pixel_t
+ chrBuf = NULL;
+
+ uint8_t
+ currentChar_x = 0,
+ currentChar_y = 0;
+
+ uint8_t
+ text_height = 0,
+ text_width = 0;
+
+ text_width = GetTextWidth(text);
+
+ /**
+ * set default values, if necessary
+ */
+
+ text_height = selectedFont_height;
+ oled_dynamic_area_t textArea;
+
+
+ textArea.width = text_width;
+ textArea.height = text_height;
+ textArea.xCrd = xCrd;
+ textArea.yCrd = yCrd;
+ SetDynamicArea(&textArea);
+
+
+ currentChar_y = ( oled_dynamic_area.height - text_height ) >> 1;
+
+ switch ( oled_text_properties.alignParam & OLED_TEXT_HALIGN_MASK )
+ {
+ case OLED_TEXT_ALIGN_LEFT:
+ {
+ currentChar_x = 0;
+ break;
+ }
+
+ case OLED_TEXT_ALIGN_RIGHT:
+ {
+ currentChar_x = ( oled_dynamic_area.width - text_width );
+ break;
+ }
+
+ case OLED_TEXT_ALIGN_CENTER:
+ {
+ currentChar_x += ( oled_dynamic_area.width - text_width ) >> 1 ;
+ break;
+ }
+
+ case OLED_TEXT_ALIGN_NONE:
+ {
+ break;
+ }
+
+ default: {}
+ }
+
+ if ( CreateTextBackground() != OLED_STATUS_SUCCESS )
+ {
+ return OLED_STATUS_ERROR;
+ }
+
+ /**
+ * write the characters into designated space, one by one
+ */
+
+ chrCnt = 0;
+ while ( 0 != text[chrCnt] )
+ {
+ WriteCharToBuf( text[chrCnt++], &chrBuf );
+
+ if ( NULL == chrBuf )
+ {
+ return OLED_STATUS_INIT_ERROR;
+ }
+
+ else
+ {
+ if (
+ ( ( currentChar_x + currentChar_width ) > oled_dynamic_area.width )
+ || ( ( currentChar_y + currentChar_height ) > oled_dynamic_area.height )
+ )
+ {
+ DestroyDynamicArea( chrBuf );
+ chrBuf = NULL;
+ return OLED_STATUS_ERROR;
+ }
+
+ // copy data
+ oled_pixel_t
+ copyAddr = oled_dynamic_area.areaBuffer + ( currentChar_y * oled_dynamic_area.width + currentChar_x );
+
+ AddCharToTextArea( chrBuf, currentChar_width, currentChar_height, copyAddr, oled_dynamic_area.width );
+
+ currentChar_x += ( currentChar_width+1 );
+ currentChar_y += 0;
+
+ DestroyDynamicArea( chrBuf );
+ chrBuf = NULL;
+ }
+ }
+
+ UpdateBuffer(
+ oled_dynamic_area.xCrd,
+ oled_dynamic_area.yCrd,
+ oled_dynamic_area.width,
+ oled_dynamic_area.height,
+ (const uint8_t*)oled_dynamic_area.areaBuffer
+ );
+
+ return OLED_STATUS_SUCCESS;
+}
+
+
+oled_status_t SSD1351::AddText( const uint8_t* text)
+{
+ uint16_t
+ chrCnt = 0;
+ oled_pixel_t
+ chrBuf = NULL;
+
+ uint8_t
+ currentChar_x = 0,
+ currentChar_y = 0;
+
+ uint8_t
+ text_height = 0,
+ text_width = 0;
+
+ text_width = GetTextWidth(text);
+
+ /**
+ * set default values, if necessary
+ */
+
+ text_height = selectedFont_height;
+
+
+ if (( oled_dynamic_area.width < text_width )||( oled_dynamic_area.height < text_height ))
+ {
+ oled_dynamic_area_t textArea;
+ textArea.width = text_width;
+ textArea.height = text_height;
+ SetDynamicArea(&textArea);
+ }
+
+ currentChar_y = ( oled_dynamic_area.height - text_height ) >> 1;
+
+ switch ( oled_text_properties.alignParam & OLED_TEXT_HALIGN_MASK )
+ {
+ case OLED_TEXT_ALIGN_LEFT:
+ {
+ currentChar_x = 0;
+ break;
+ }
+
+ case OLED_TEXT_ALIGN_RIGHT:
+ {
+ currentChar_x = ( oled_dynamic_area.width - text_width );
+ break;
+ }
+
+ case OLED_TEXT_ALIGN_CENTER:
+ {
+ currentChar_x += ( oled_dynamic_area.width - text_width ) >> 1 ;
+ break;
+ }
+
+ case OLED_TEXT_ALIGN_NONE:
+ {
+ break;
+ }
+
+ default: {}
+ }
+
+ if ( CreateTextBackground() != OLED_STATUS_SUCCESS )
+ {
+ return OLED_STATUS_ERROR;
+ }
+
+ /**
+ * write the characters into designated space, one by one
+ */
+
+ chrCnt = 0;
+ while ( 0 != text[chrCnt] )
+ {
+ WriteCharToBuf( text[chrCnt++], &chrBuf );
+
+ if ( NULL == chrBuf )
+ {
+ return OLED_STATUS_INIT_ERROR;
+ }
+
+ else
+ {
+ if (
+ ( ( currentChar_x + currentChar_width ) > oled_dynamic_area.width )
+ || ( ( currentChar_y + currentChar_height ) > oled_dynamic_area.height )
+ )
+ {
+ DestroyDynamicArea( chrBuf );
+ chrBuf = NULL;
+ return OLED_STATUS_ERROR;
+ }
+
+ // copy data
+ oled_pixel_t
+ copyAddr = oled_dynamic_area.areaBuffer + ( currentChar_y * oled_dynamic_area.width + currentChar_x );
+
+ AddCharToTextArea( chrBuf, currentChar_width, currentChar_height, copyAddr, oled_dynamic_area.width );
+
+ currentChar_x += ( currentChar_width+1 );
+ currentChar_y += 0;
+
+ DestroyDynamicArea( chrBuf );
+ chrBuf = NULL;
+ }
+ }
+
+ UpdateBuffer(
+ oled_dynamic_area.xCrd,
+ oled_dynamic_area.yCrd,
+ oled_dynamic_area.width,
+ oled_dynamic_area.height,
+ (const uint8_t*)oled_dynamic_area.areaBuffer
+ );
+
+ return OLED_STATUS_SUCCESS;
+}
+
+
+
+oled_status_t SSD1351::DrawText ( const uint8_t* text,uint8_t xCrd, uint8_t yCrd )
+{
+
+ if ( NULL == text )
+ {
+ return OLED_STATUS_ERROR;
+ }
+
+ AddText(text,xCrd,yCrd);
+
+ // set the locations
+ SetBorders( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height );
+
+ // fill the GRAM
+ SendData( (const uint8_t*)oled_dynamic_area.areaBuffer, oled_dynamic_area.width * oled_dynamic_area.height * OLED_BYTES_PER_PIXEL );
+
+
+// free( currentTextAreaImage );
+ return OLED_STATUS_SUCCESS;
+}
+
+
+oled_status_t SSD1351::DrawText( const uint8_t* text)
+{
+
+ if ( NULL == text )
+ {
+ return OLED_STATUS_ERROR;
+ }
+
+ AddText(text);
+ // set the locations
+ SetBorders( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height );
+ // fill the GRAM
+ SendData( (const uint8_t*)oled_dynamic_area.areaBuffer, oled_dynamic_area.width * oled_dynamic_area.height * OLED_BYTES_PER_PIXEL );
+
+// free( currentTextAreaImage );
+ return OLED_STATUS_SUCCESS;
+}
+
+
+
+
+
+
+
+
+void SSD1351::GetImageDimensions(uint8_t *width, uint8_t *height, const uint8_t* image)
+{
+ *height = image[2] + (image[3] << 8);
+ *width = image[4] + (image[5] << 8);
+}
+
+
+oled_status_t SSD1351::AddImage ( const uint8_t* image )
+{
+ oled_status_t
+ status = OLED_STATUS_SUCCESS;
+
+ // check the bounds
+ if AreCoordsNotValid( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height )
+ {
+ status = OLED_STATUS_INIT_ERROR;
+ }
+
+ else
+ {
+ Swap( (oled_pixel_t)oled_dynamic_area.areaBuffer, BMP_SkipHeader(image), oled_dynamic_area.width*oled_dynamic_area.height );
+
+ // update the main screen buffer
+ UpdateBuffer( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height, (const uint8_t *)oled_dynamic_area.areaBuffer );
+ }
+
+ return status;
+}
+
+
+oled_status_t SSD1351::AddImage ( const uint8_t* image, uint8_t xCrd, uint8_t yCrd )
+{
+ oled_status_t
+ status = OLED_STATUS_SUCCESS;
+
+ oled_dynamic_area_t image_dynamicArea;
+
+ image_dynamicArea.xCrd = xCrd;
+ image_dynamicArea.yCrd = yCrd;
+
+ GetImageDimensions(&image_dynamicArea.width, &image_dynamicArea.height, image);
+ SetDynamicArea(&image_dynamicArea);
+
+ // check the bounds
+ if AreCoordsNotValid( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height )
+ {
+ status = OLED_STATUS_INIT_ERROR;
+ }
+
+ else
+ {
+ Swap( (oled_pixel_t)oled_dynamic_area.areaBuffer, BMP_SkipHeader(image), oled_dynamic_area.width*oled_dynamic_area.height );
+
+ // update the main screen buffer
+ UpdateBuffer( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height, (const uint8_t *)oled_dynamic_area.areaBuffer );
+ }
+
+ return status;
+}
+
+
+
+oled_status_t SSD1351::DrawImage ( const uint8_t* image )
+{
+
+ oled_status_t
+ status = OLED_STATUS_SUCCESS;
+
+ status = AddImage( image );
+
+ // set the locations
+ SetBorders( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height );
+
+ // fill the GRAM
+ SendData( (const uint8_t*)oled_dynamic_area.areaBuffer, oled_dynamic_area.width * oled_dynamic_area.height * OLED_BYTES_PER_PIXEL );
+
+
+ return status;
+}
+
+oled_status_t SSD1351::DrawImage ( const uint8_t* image, uint8_t xCrd, uint8_t yCrd )
+{
+
+ oled_status_t
+ status = OLED_STATUS_SUCCESS;
+
+ status = AddImage( image,xCrd,yCrd);
+
+ // set the locations
+ SetBorders( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height );
+
+ // fill the GRAM
+ SendData( (const uint8_t*)oled_dynamic_area.areaBuffer, oled_dynamic_area.width * oled_dynamic_area.height * OLED_BYTES_PER_PIXEL );
+
+
+ return status;
+}
+
+
+
+void SSD1351::DimScreenON()
+{
+ for ( int i = 0; i < 16; i++ )
+ {
+ SendCmd( OLED_CMD_CONTRASTMASTER, FIRST_BYTE );
+ SendCmd( 0xC0 | (0xF-i), OTHER_BYTE );
+ wait_ms(20);
+ //OSA_TimeDelay( 20 );
+ }
+}
+
+
+void SSD1351::DimScreenOFF()
+{
+ SendCmd( OLED_CMD_CONTRASTMASTER, FIRST_BYTE );
+ SendCmd( 0xC0 | 0xF, OTHER_BYTE );
+}
+
+
+
+void SSD1351::Swap(
+ oled_pixel_t imgDst,
+ const uint8_t* imgSrc,
+ uint16_t imgSize
+ )
+{
+ for ( int var = 0; var < imgSize; var++ )
+ {
+ *imgDst = *imgSrc << 8;
+ imgSrc++;
+ *imgDst |= *imgSrc;
+ imgDst++;
+ imgSrc++;
+ }
+}
+
+
+void SSD1351::PowerON()
+{
+ power = 1;
+}
+
+void SSD1351::PowerOFF()
+{
+ power = 0;
+}
+
+
+
+ //Formerly Known as GuiDriver_UpdateScreen
+void SSD1351::UpdateBuffer (
+ uint8_t xCrd,
+ uint8_t yCrd,
+ uint8_t width,
+ uint8_t height,
+ const uint8_t* image
+ )
+{
+ // copy data
+ oled_pixel_t
+ copyAddr = (oled_pixel_t)screenBuf + ( yCrd*OLED_SCREEN_WIDTH + xCrd );
+
+ for ( uint8_t i = 0; i < height; i++ )
+ {
+ memcpy( (void*)copyAddr, (void*)image, width*OLED_BYTES_PER_PIXEL );
+ copyAddr += OLED_SCREEN_WIDTH;
+ image += width*OLED_BYTES_PER_PIXEL;
+ }
+}
+
+/* Internal Functions */
+
+/**
+ * [transpose description]
+ * @param transImage Transposed Image
+ * @param image Source Image
+ * @param width Width to Transpose
+ * @param height Height to Transpose
+ */
+void SSD1351::Transpose(
+ oled_pixel_t transImage,
+ const oled_pixel_t image,
+ uint8_t width,
+ uint8_t height
+ )
+{
+ for ( uint8_t i = 0; i < height; i++ )
+ {
+ for ( uint8_t j = 0; j < width ; j++ )
+ {
+ transImage[ j*height + i ] = image[ i*width + j ];
+ }
+ }
+}
+
+
+
+/**
+ * TopDown Transition Effect for Image
+ * @param image image to be transitioned
+ * @param xCrd x coordinate of image
+ * @param yCrd y coordinate of image
+ * @param width width of image
+ * @param height height of image
+ * @return status flag
+ */
+oled_status_t SSD1351::TopDown(
+ const uint8_t* image,
+ uint8_t xCrd,
+ uint8_t yCrd,
+ uint8_t width,
+ uint8_t height
+ )
+{
+ uint16_t
+ transStep = OLED_TRANSITION_STEP;
+
+ uint16_t
+ partImgSize = width*transStep;
+
+ oled_status_t
+ status = OLED_STATUS_SUCCESS;
+
+ uint8_t*
+ partImgPtr = (uint8_t*)image + ( height - transStep ) * ( width * OLED_BYTES_PER_PIXEL );
+
+ /**
+ * set locations
+ */
+
+ while (1)
+ {
+ SetBorders( xCrd, yCrd, width, height );
+
+ if ( partImgSize > width*height )
+ {
+ SendData( (const uint8_t*)image, width*height*OLED_BYTES_PER_PIXEL );
+ break;
+ }
+ else
+ {
+ SendData( (const uint8_t*)partImgPtr, partImgSize * OLED_BYTES_PER_PIXEL );
+ }
+
+
+ /**
+ * update variables
+ */
+
+ partImgPtr -= ( width * transStep ) * OLED_BYTES_PER_PIXEL;
+ partImgSize += ( width * transStep );
+ transStep++;
+ }
+
+ return status;
+}
+
+/**
+ * DownTop Transition Effect for Image
+ * @param image image to be transitioned
+ * @param xCrd x coordinate of image
+ * @param yCrd y coordinate of image
+ * @param width width of image
+ * @param height height of image
+ * @return status flag
+ */
+
+oled_status_t SSD1351::DownTop(
+ const uint8_t* image,
+ uint8_t xCrd,
+ uint8_t yCrd,
+ uint8_t width,
+ uint8_t height
+ )
+{
+ uint16_t
+ transStep = OLED_TRANSITION_STEP;
+
+ uint16_t
+ partImgSize = width*transStep;
+
+ oled_status_t
+ status = OLED_STATUS_SUCCESS;
+
+ uint8_t*
+ partImgPtr = (uint8_t*)image;
+
+ uint8_t
+ yCrd_moving = ( yCrd + height ) - 1;
+
+ /**
+ * set locations
+ */
+
+ while (1)
+ {
+ if (
+ ( partImgSize > OLED_SCREEN_SIZE )
+ || ( yCrd_moving < yCrd )
+ )
+ {
+ // draw full image
+ SetBorders( xCrd, yCrd, width, height );
+ SendData( (const uint8_t*)image, width * height * OLED_BYTES_PER_PIXEL );
+ break;
+ }
+
+ else
+ {
+ SetBorders( xCrd, yCrd_moving, width, ( yCrd + height ) - yCrd_moving );
+ SendData( (const uint8_t*)partImgPtr, partImgSize * OLED_BYTES_PER_PIXEL );
+ }
+
+ /**
+ * update variables
+ */
+
+ yCrd_moving -= transStep;
+ partImgSize += ( width * transStep );
+ transStep++;
+ }
+
+ return status;
+}
+
+
+/**
+ * LeftRight Transition Effect for Image
+ * @param image image to be transitioned
+ * @param xCrd x coordinate of image
+ * @param yCrd y coordinate of image
+ * @param width width of image
+ * @param height height of image
+ * @return status flag
+ */
+
+oled_status_t SSD1351::LeftRight(
+ const uint8_t* image,
+ uint8_t xCrd,
+ uint8_t yCrd,
+ uint8_t width,
+ uint8_t height
+ )
+{
+ oled_status_t
+ status = OLED_STATUS_SUCCESS;
+
+ oled_dynamic_area_t
+ transImageArea =
+ {
+ .xCrd = 0,
+ .yCrd = 0,
+
+ .width = 96,
+ .height= 96
+ };
+
+ SetDynamicArea( &transImageArea );
+
+ // helper pointer
+ oled_pixel_t
+ transImage = (oled_pixel_t)oled_dynamic_area.areaBuffer;
+
+ if ( NULL == transImage )
+ {
+ return OLED_STATUS_INIT_ERROR;
+ }
+
+ Transpose( (oled_pixel_t)transImage, (const oled_pixel_t)image, width, height );
+
+ SendCmd( OLED_CMD_SET_REMAP, FIRST_BYTE );
+ SendCmd( OLED_REMAP_SETTINGS | REMAP_VERTICAL_INCREMENT, OTHER_BYTE );
+
+ uint16_t
+ transStep = OLED_TRANSITION_STEP;
+
+ uint16_t
+ partImgSize = height*transStep;
+
+ uint8_t*
+ partImgPtr = (uint8_t*)transImage + ( width - transStep ) * ( height * OLED_BYTES_PER_PIXEL );
+
+ /**
+ * set locations
+ */
+
+ while (1)
+ {
+ SetBorders( xCrd, yCrd, width, height );
+
+ if ( partImgSize > width*height )
+ {
+ SendData((const uint8_t*)transImage, width * height * OLED_BYTES_PER_PIXEL );
+ break;
+ }
+ else
+ {
+ SendData( (const uint8_t*)partImgPtr, partImgSize * OLED_BYTES_PER_PIXEL );
+ }
+
+
+ partImgPtr -= ( transStep * height ) * OLED_BYTES_PER_PIXEL;
+ partImgSize += ( transStep * height );
+ transStep++;
+
+ }
+
+ SendCmd( OLED_CMD_SET_REMAP, FIRST_BYTE );
+ SendCmd( OLED_REMAP_SETTINGS, OTHER_BYTE );
+
+ DestroyDynamicArea();
+ return status;
+}
+
+
+/**
+ * RightLeft Transition Effect for Image
+ * @param image image to be transitioned
+ * @param xCrd x coordinate of image
+ * @param yCrd y coordinate of image
+ * @param width width of image
+ * @param height height of image
+ * @return status flag
+ */
+oled_status_t SSD1351::RightLeft(
+ const uint8_t* image,
+ uint8_t xCrd,
+ uint8_t yCrd,
+ uint8_t width,
+ uint8_t height
+ )
+{
+ oled_dynamic_area_t
+ transImageArea =
+ {
+ .xCrd = 0,
+ .yCrd = 0,
+
+ .width = 96,
+ .height= 96
+ };
+
+ SetDynamicArea( &transImageArea );
+
+ // helper pointer
+ oled_pixel_t
+ transImage = oled_dynamic_area.areaBuffer;
+
+ if ( NULL == transImage )
+ {
+ return OLED_STATUS_INIT_ERROR;
+ }
+
+ Transpose( (oled_pixel_t)transImage, (const oled_pixel_t)image, width, height );
+
+ SendCmd( OLED_CMD_SET_REMAP, FIRST_BYTE );
+ SendCmd( OLED_REMAP_SETTINGS | REMAP_VERTICAL_INCREMENT, OTHER_BYTE );
+
+
+ uint16_t
+ transStep = OLED_TRANSITION_STEP;
+
+ uint16_t
+ partImgSize = height * transStep;
+
+ uint8_t*
+ partImgPtr = (uint8_t*)transImage;
+
+ uint8_t
+ xCrd_moving = ( xCrd + width ) - 1;
+
+ /** set locations */
+
+ while (1)
+ {
+ if (( partImgSize > width*height )|| ( xCrd_moving < xCrd ))
+ {
+ SetBorders( xCrd, yCrd, width, height );
+ SendData( (const uint8_t*)transImage, height * width * OLED_BYTES_PER_PIXEL );
+ break;
+ }
+ else
+ {
+ SetBorders( xCrd_moving, yCrd, ( xCrd + width ) - xCrd_moving, height );
+ SendData( (const uint8_t*)partImgPtr, partImgSize * OLED_BYTES_PER_PIXEL );
+ }
+
+ /** update variables*/
+
+ xCrd_moving -= transStep;
+ partImgSize += ( height * transStep );
+ transStep++;
+ }
+
+ SendCmd( OLED_CMD_SET_REMAP, FIRST_BYTE );
+ SendCmd( OLED_REMAP_SETTINGS, OTHER_BYTE );
+
+ DestroyDynamicArea();
+
+ return OLED_STATUS_SUCCESS;
+}
+
+
+/**
+ * [setDirection description]
+ * @param self [description]
+ * @param xCrd [description]
+ * @param yCrd [description]
+ * @return [description]
+ */
+void SSD1351::SetBorders(
+ uint8_t xCrd,
+ uint8_t yCrd,
+ uint8_t width,
+ uint8_t height
+ )
+{
+
+ // adjust for the offset
+ OLED_AdjustColumnOffset(xCrd);
+ OLED_AdjustRowOffset(yCrd);
+
+ SendCmd( OLED_CMD_SET_COLUMN, FIRST_BYTE );
+ SendCmd( xCrd, OTHER_BYTE );
+ SendCmd( xCrd + (width-1), OTHER_BYTE );
+ SendCmd( OLED_CMD_SET_ROW, FIRST_BYTE );
+ SendCmd( yCrd, OTHER_BYTE );
+ SendCmd( yCrd + (height-1), OTHER_BYTE );
+
+}
+
+/**
+ * create the buffer for a partial image
+ * @param imgBuf [description]
+ * @param width [description]
+ * @param height [description]
+ * @return [description]
+ */
+oled_status_t SSD1351::CreateTextBackground()
+{
+ uint8_t
+ xCrd = oled_dynamic_area.xCrd,
+ yCrd = oled_dynamic_area.yCrd,
+ width = oled_dynamic_area.width,
+ height = oled_dynamic_area.height;
+
+ oled_pixel_t
+ imgBuf = oled_dynamic_area.areaBuffer,
+ copyAddr;
+
+ const uint8_t*
+ background = oled_text_properties.background;
+
+ /** copy data */
+
+ if (
+ ( NULL == imgBuf )
+ || ( ( xCrd + width ) > OLED_SCREEN_WIDTH )
+ || ( ( yCrd + height ) > OLED_SCREEN_HEIGHT )
+ )
+ {
+ return OLED_STATUS_INIT_ERROR;
+ }
+
+ if ( NULL == background )
+ {
+ for ( uint8_t i = 0; i < height; i++ )
+ {
+ memset( (void*)imgBuf, 0, width*OLED_BYTES_PER_PIXEL );
+ imgBuf += width;
+ }
+ }
+
+ else
+ {
+ copyAddr = (oled_pixel_t)( BMP_SkipHeader( background ) ) + ( yCrd*OLED_SCREEN_WIDTH + xCrd );
+ for ( uint8_t i = 0; i < height; i++ )
+ {
+ Swap( (oled_pixel_t)imgBuf, (const uint8_t*)copyAddr, width );
+ imgBuf += width;
+ copyAddr += OLED_SCREEN_WIDTH;
+ }
+ }
+
+ return OLED_STATUS_SUCCESS;
+}
+
+
+/**
+ * Write the character to Buffer
+ * @param charToWrite character to be written
+ * @param chrBuf given pointer for buffer for the character
+ */
+void SSD1351::WriteCharToBuf(
+ uint16_t charToWrite,
+ oled_pixel_t* chrBuf
+ )
+{
+ uint8_t
+ foo = 0,
+ mask;
+
+ const uint8_t*
+ pChTable = selectedFont + 8 + (uint16_t)( ( charToWrite - selectedFont_firstChar ) << 2 );
+
+ currentChar_width = *pChTable,
+ currentChar_height = selectedFont_height;
+
+ uint32_t
+ offset = (uint32_t)pChTable[1]
+ | ( (uint32_t)pChTable[2] << 8 )
+ | ( (uint32_t)pChTable[3] << 16 );
+
+ const uint8_t*
+ pChBitMap = selectedFont + offset;
+
+ if ( 0 == isFontInitialized )
+ {
+ // default font
+ SetFont( oledFont_Tahoma_8_Regular, COLOR_WHITE );
+ }
+
+ // allocate space for char image
+ *chrBuf = (oled_pixel_t)AllocateDynamicArea( currentChar_height * currentChar_width );
+
+ if ( NULL == *chrBuf )
+ {
+ return;
+ }
+
+ for ( uint8_t yCnt = 0; yCnt < currentChar_height; yCnt++ )
+ {
+ mask = 0;
+
+ for ( uint8_t xCnt = 0; xCnt < currentChar_width; xCnt++ )
+ {
+ if ( 0 == mask )
+ {
+ mask = 1;
+ foo = *pChBitMap++;
+ }
+
+ if ( 0 != ( foo & mask ) )
+ {
+ *( *chrBuf + yCnt*currentChar_width + xCnt ) = selectedFont_color;
+ }
+
+ else
+ {
+ *( *chrBuf + yCnt*currentChar_width + xCnt ) = 0;
+ }
+
+ mask <<= 1;
+ }
+ }
+}
+
+
+
+/**
+ * Add subimage/character to the active image buffer
+ * @param xOffset offset for the x-coordinate
+ * @param yOffset offset for the y-coordinate
+ * @param width desired width
+ * @param height desired height
+ * @return status flag
+ */
+oled_status_t SSD1351::AddCharToTextArea(
+ oled_pixel_t chrPtr,
+ uint8_t chrWidth,
+ uint8_t chrHeight,
+ oled_pixel_t copyAddr,
+ uint8_t imgWidth
+ )
+{
+ if ( NULL == copyAddr )
+ {
+ return OLED_STATUS_INIT_ERROR;
+ }
+
+ for ( uint8_t i = 0; i < chrHeight; i++ )
+ {
+ for ( uint8_t j = 0; j < chrWidth; j++ )
+ {
+ if ( 0 != chrPtr[j] )
+ {
+ copyAddr[j] = chrPtr[j];
+ }
+ }
+ copyAddr += imgWidth;
+ chrPtr += chrWidth;
+ }
+ return OLED_STATUS_SUCCESS;
+}
+
+
+/**
+ * Allocate memory for the desired image/character
+ * @param area desired area dimensions
+ */
+void* SSD1351::AllocateDynamicArea( uint32_t area )
+{
+ void*
+ ptr = malloc( area * OLED_BYTES_PER_PIXEL );
+
+ if ( NULL == ptr )
+ {
+ return NULL;
+ }
+
+ return ptr;
+}
+
+
+/**
+ * Deallocate current area
+ * @param area pointer to current area
+ */
+oled_status_t SSD1351::DestroyDynamicArea( void* ptr )
+{
+ if ( NULL == ptr )
+ {
+ return OLED_STATUS_INIT_ERROR;
+ }
+
+ free(ptr);
+
+ return OLED_STATUS_SUCCESS;
+}
+
+
+
+
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexi_OLED_SSD1351.h Thu Aug 18 23:01:06 2016 +0000
@@ -0,0 +1,313 @@
+#ifndef HG_OLED_DRIVER
+#define HG_OLED_DRIVER
+
+#include "mbed.h"
+#include "OLED_types.h"
+#include "OLED_info.h"
+
+
+
+class SSD1351{
+
+public:
+
+
+ SSD1351(PinName mosi,PinName sclk,PinName pwr, PinName cs,PinName rst, PinName dc);
+
+ ~SSD1351();
+
+ /**
+ * Send the command to OLED
+ * @param self OLED handle
+ * @param cmd OLED command from the datasheet
+ * @param isFirst designate if this is the first byte in the command
+ */
+ void SendCmd(uint32_t cmd,
+ uint8_t isFirst);
+
+
+ /**
+ * Send data to OLED
+ * @param dataToSend data to send to OLED
+ * @param dataSize data-size
+ */
+ void SendData ( const uint8_t* dataToSend,
+ uint32_t dataSize);
+
+ /**
+ * draw box on OLED
+ * @param xCrd x-coordinate for box's uper left corner
+ * @param yCrd y-coordinate for box's uper left corner
+ * @param width box's width
+ * @param height box's height
+ * @param color color of the box
+ * @return status flag
+ */
+ oled_status_t DrawBox (
+ uint16_t xCrd,
+ uint16_t yCrd,
+ uint16_t width,
+ uint16_t height,
+ uint16_t color
+ );
+
+ /**
+ * Fill the entire screen with specified color
+ * @param color color to fill with
+ */
+ void FillScreen( uint16_t color );
+
+
+
+ /**
+ * Draw a single pixel
+ * @param xCrd pixel's x coordinate
+ * @param yCrd pixel's y coordinate
+ * @param color pixel's color
+ * @return status flag
+ */
+ oled_status_t DrawPixel (
+ int16_t xCrd,
+ int16_t yCrd,
+ uint16_t color
+ );
+
+
+ /**
+ * Draw the whole screen
+ * @param image image to draw
+ * @param xCrd image x-coordinate
+ * @param yCrd image y-coordinate
+ * @param width image width
+ * @param height image height
+ * @param transition transition style for the new image arrival
+ * @return status flag
+ */
+ oled_status_t DrawScreen (
+ const uint8_t* image,
+ uint8_t xCrd,
+ uint8_t yCrd,
+ uint8_t width,
+ uint8_t height,
+ oled_transition_t transition
+ );
+
+
+ /**
+ * Set the font to use
+ * @param newFont desired font
+ * @param newColor desired color
+ * @return status flag
+ */
+ oled_status_t SetFont(
+ const uint8_t* newFont,
+ uint16_t newColor
+ );
+
+
+ /**
+ * Set OLED dynamic area
+ * @param dynamic_area data-structure with desired values
+ */
+ void SetDynamicArea(oled_dynamic_area_t *dynamic_area);
+
+ /**
+ * Destroy current OLED dynamic area
+ */
+ void DestroyDynamicArea();
+
+
+ /**
+ * Set OLED text properties
+ * @param textProperties data-structure with desired properties
+ */
+ void SetTextProperties(oled_text_properties_t *textProperties);
+
+
+ /**
+ * Return the width in [px] required for the given string to be displayed
+ * @param text desired string
+ * @return required text width in [px]
+ */
+ uint8_t GetTextWidth(const uint8_t* text);
+
+
+ /**
+ * Count the characters
+ * @param width text width
+ * @param font text font
+ * @param text given text string
+ * @param length text length
+ * @return character count
+ */
+ uint8_t CharCount(uint8_t width, const uint8_t* font, const uint8_t* text, uint8_t length);
+
+ /**
+ * Add text to the main screen buffer at position x,y.
+ * @param text text to add
+ * @param xCrd x-coordinate for the given text
+ * @param yCrd y-coordinate for the given text
+ * @return status flag
+ */
+ oled_status_t AddText( const uint8_t* text,uint8_t xCrd, uint8_t yCrd );
+ /**
+ * Add text to the main screen buffer. Used with SetDynamicArea() Function.
+ * @param text text to add
+ * @return status flag
+ */
+ oled_status_t AddText( const uint8_t* text);
+
+ /**
+ * Write text on OLED at position x,y.
+ * @param text desired text
+ * @param xCrd x-coordinate for the given text
+ * @param yCrd y-coordinate for the given text
+ */
+
+ oled_status_t DrawText ( const uint8_t* text,uint8_t xCrd, uint8_t yCrd );
+
+ /**
+ * Write text on OLED at position set in Dynamic Area Field. Used with SetDynamicArea() Function.
+ * @param text desired text
+ * @param x x-coordinate for the given text, set through dynamicArea_t variable
+ * @param y y-coordinate for the given text, set through dynamicArea_t variable
+ *
+ */
+ oled_status_t DrawText ( const uint8_t* text);
+
+ /**
+ * Return the dimensions of image
+ * @param width given image's width
+ * @param height given image's height
+ * @param image desired image
+ */
+ void GetImageDimensions(uint8_t *width, uint8_t *height, const uint8_t* image);
+
+
+
+ /**
+ * Add image to the main screen buffer.Used with SetDynamicArea() Function.
+ * @param image desired image
+ * @return status flag
+ */
+ oled_status_t AddImage ( const uint8_t* image );
+
+ /**
+ * Add image to the main screen buffer at position x,y
+ * @param image desired image
+ * @return status flag
+ */
+ oled_status_t AddImage ( const uint8_t* image, uint8_t xCrd, uint8_t yCrd );
+
+ /**
+ * Draw image, i.e. send image to OLED GRAM.Used with SetDynamicArea() Function.
+ * @param image desired image
+ * @param transition desired transition style for the new image
+ * @return status flag
+ */
+ oled_status_t DrawImage ( const uint8_t* image );
+ /**
+ * Draw image, i.e. send image to OLED GRAM at position x,y.
+ * @param image desired image
+ * @param transition desired transition style for the new image
+ * @return status flag
+ */
+ oled_status_t DrawImage ( const uint8_t* image, uint8_t xCrd, uint8_t yCrd );
+
+ /**
+ * Dim OLED screen on
+ */
+ void DimScreenON();
+
+ /**
+ * Return OLED back to full contrast
+ */
+ void DimScreenOFF();
+
+ /**
+ * Swap image's bytes per pixel to obtain the correct color format
+ * @param imgDst desired image
+ * @param imgSrc original image
+ * @param imgSize image's size
+ */
+ void Swap(
+ oled_pixel_t imgDst,
+ const uint8_t* imgSrc,
+ uint16_t imgSize
+ );
+
+
+ /**
+ * Turn on Power for OLED Display
+ */
+ void PowerON();
+
+ /**
+ * Turn off Power for OLED Display
+ */
+ void PowerOFF();
+
+ /**
+ * update the main screen buffer
+ * with the given image
+
+ * @param xCrd image x-coordinate
+ * @param yCrd image y-coordinate
+ * @param width image width
+ * @param height image height
+ * @param image image for buffer
+ */
+ void UpdateBuffer (
+ uint8_t xCrd,
+ uint8_t yCrd,
+ uint8_t width,
+ uint8_t height,
+ const uint8_t* image
+ );
+
+
+
+private:
+
+ SPI spi;
+ DigitalOut power;
+ DigitalOut cs;
+ DigitalOut rst;
+ DigitalOut dc;
+
+
+ const uint8_t* selectedFont;
+
+ uint8_t
+ isFontInitialized,
+ currentChar_width,
+ currentChar_height,
+ screenBuf[OLED_GRAM_SIZE];
+
+ uint16_t
+ selectedFont_color,
+ selectedFont_firstChar, // first character in the font table
+ selectedFont_lastChar, // last character in the font table
+ selectedFont_height,
+ colorMask;
+
+ oled_dynamic_area_t oled_dynamic_area;
+ oled_text_properties_t oled_text_properties;
+
+
+ //Internal Functions
+ void Transpose( oled_pixel_t transImage, const oled_pixel_t image, uint8_t width, uint8_t height );
+ oled_status_t TopDown ( const uint8_t* image, uint8_t xCrd, uint8_t yCrd, uint8_t width, uint8_t height );
+ oled_status_t DownTop ( const uint8_t* image, uint8_t xCrd, uint8_t yCrd, uint8_t width, uint8_t height );
+ oled_status_t LeftRight ( const uint8_t* image, uint8_t xCrd, uint8_t yCrd, uint8_t width, uint8_t height );
+ oled_status_t RightLeft ( const uint8_t* image, uint8_t xCrd, uint8_t yCrd, uint8_t width, uint8_t height );
+ void SetBorders( uint8_t xCrd, uint8_t yCrd, uint8_t width, uint8_t height );
+ oled_status_t CreateTextBackground();
+ void WriteCharToBuf( uint16_t charToWrite, oled_pixel_t* chrBuf );
+ oled_status_t AddCharToTextArea( oled_pixel_t chrPtr, uint8_t chrWidth, uint8_t chrHeight, oled_pixel_t copyAddr, uint8_t imgWidth );
+ void* AllocateDynamicArea( uint32_t area );
+ oled_status_t DestroyDynamicArea(void * ptr);
+
+};
+
+#endif
--- a/OLED_driver.cpp Wed Aug 17 22:08:40 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1348 +0,0 @@
-#include "OLED_types.h"
-#include "OLED_info.h"
-#include "mbed.h"
-#include "OLED_driver.h"
-#include "OLED_fonts.h"
-
-
-/* oled_init arrays*/
-const uint32_t oled_init_cmd[] = {
- OLED_CMD_SET_CMD_LOCK,
- OLED_UNLOCK,
- OLED_CMD_SET_CMD_LOCK,
- OLED_ACC_TO_CMD_YES,
- OLED_CMD_DISPLAYOFF,
- OLED_CMD_SET_OSC_FREQ_AND_CLOCKDIV,
- 0xF1,
- OLED_CMD_SET_MUX_RATIO,
- 0x5F,
- OLED_CMD_SET_REMAP,
- OLED_REMAP_SETTINGS,
- OLED_CMD_SET_COLUMN,
- 0x00,
- 0x5F,
- OLED_CMD_SET_ROW,
- 0x00,
- 0x5F,
- OLED_CMD_STARTLINE,
- 0x80,
- OLED_CMD_DISPLAYOFFSET,
- 0x60,
- OLED_CMD_PRECHARGE,
- 0x32,
- OLED_CMD_VCOMH,
- 0x05,
- OLED_CMD_NORMALDISPLAY,
- OLED_CMD_CONTRASTABC,
- 0x8A,
- 0x51,
- 0x8A,
- OLED_CMD_CONTRASTMASTER,
- 0xCF,
- OLED_CMD_SETVSL,
- 0xA0,
- 0xB5,
- 0x55,
- OLED_CMD_PRECHARGE2,
- 0x01,
- OLED_CMD_DISPLAYON };
-
-
-const uint8_t oled_init_isFirst[] = {
- FIRST_BYTE,
- OTHER_BYTE,
- FIRST_BYTE,
- OTHER_BYTE,
- FIRST_BYTE,
- FIRST_BYTE,
- OTHER_BYTE,
- FIRST_BYTE,
- OTHER_BYTE,
- FIRST_BYTE,
- OTHER_BYTE,
- FIRST_BYTE,
- OTHER_BYTE,
- OTHER_BYTE,
- FIRST_BYTE,
- OTHER_BYTE,
- OTHER_BYTE,
- FIRST_BYTE,
- OTHER_BYTE,
- FIRST_BYTE,
- OTHER_BYTE,
- FIRST_BYTE,
- FIRST_BYTE,
- FIRST_BYTE,
- FIRST_BYTE,
- FIRST_BYTE,
- FIRST_BYTE,
- OTHER_BYTE,
- OTHER_BYTE,
- OTHER_BYTE,
- FIRST_BYTE,
- OTHER_BYTE,
- FIRST_BYTE,
- OTHER_BYTE,
- OTHER_BYTE,
- OTHER_BYTE,
- FIRST_BYTE,
- OTHER_BYTE,
- FIRST_BYTE};
-
-
-
-
-OLED::OLED(PinName mosi,PinName sclk,PinName pwr, PinName cs,PinName rst, PinName dc): oled_SPI(mosi,NC,sclk) , oled_POWER(pwr), oled_CS(cs),oled_RST(rst),oled_DC(dc)
-{
-
- oled_SPI.frequency(8000000);
-
-
- oled_DC =0;
- OLED_PowerOFF();
- wait_ms(1);
- oled_RST = 0 ;
- wait_ms(1);
- oled_RST = 1 ;
- wait_ms(1);
- OLED_PowerON();
-
- isFontInitialized = 0 ;
- currentChar_width = 0,
- currentChar_height = 0;
- colorMask = COLOR_WHITE;
-
- oled_text_properties.alignParam = OLED_TEXT_ALIGN_CENTER;
- oled_text_properties.background = NULL;
- oled_text_properties.font = oledFont_Tahoma_8_Regular;
- oled_text_properties.fontColor = COLOR_RED;
-
- oled_dynamic_area.areaBuffer = NULL;
- oled_dynamic_area.height = 0;
- oled_dynamic_area.width = 0;
-
-
-
- for (int i=0;i<39;i++)
- {
- OLED_SendCmd(oled_init_cmd[i],oled_init_isFirst[i]);
- }
-
-
-
-}
-
-
-OLED::~OLED(void)
-{
-
- //Run Free and zero pointers.
-}
-
-
-
-
-void OLED::OLED_SendCmd(uint32_t cmd,
- uint8_t isFirst)
-{
-
-
-
- uint8_t
- txSize = 1,
- txBuf[4];
-
- memcpy((void*)txBuf, (void*)&cmd, txSize );
-
- if (isFirst )
- {
- oled_DC = 0;
- }
- else
- {
- oled_DC = 1;
- }
-
- oled_CS = 0;
- oled_SPI.write(*txBuf);
- oled_CS = 1;
-
-}
-
-
-
-void OLED::OLED_SendData ( const uint8_t* dataToSend,
- uint32_t dataSize)
-
-{
-
-
- uint16_t* arrayPtr = (uint16_t*)dataToSend;
-
- for( uint32_t i = 0; i < dataSize/2; i++ )
- {
- arrayPtr[i] &= colorMask;
- }
-
-
- this->OLED_SendCmd( OLED_CMD_WRITERAM, FIRST_BYTE );
-
-
- // sending data -> set DC pin
-
- oled_DC = 1;
- oled_CS = 0 ;
-
-
- const uint8_t*
- // traversing pointer
- bufPtr = dataToSend;
-
-
- for ( uint32_t i = 0; i < dataSize; i++)
- {
- oled_SPI.write(*bufPtr);
- bufPtr += 1;
- }
-
-
- oled_CS = 1;
-
-}
-
-
-oled_status_t OLED::OLED_DrawBox (
- uint16_t xCrd,
- uint16_t yCrd,
- uint16_t width,
- uint16_t height,
- uint16_t color
- )
-{
-
- oled_status_t status;
- oled_dynamic_area_t boxArea;
-
- boxArea.xCrd = xCrd;
- boxArea.yCrd = yCrd;
- boxArea.width = width;
- boxArea.height = height;
-
- uint32_t
- boxSize = width*height;
-
- OLED_SetDynamicArea( &boxArea );
-
- // helper pointer
- uint8_t*
- boxBuf = (uint8_t*)oled_dynamic_area.areaBuffer;
-
- if ( NULL == boxBuf )
- {
-
- return OLED_STATUS_ERROR;
- }
-
- // check the bounds
- if AreCoordsNotValid( xCrd, yCrd, width, height )
- {
- status = OLED_STATUS_INIT_ERROR;
- }
-
- else
- {
- /** fill the buffer with color */
-
- for ( uint16_t i = 0; i < boxSize; i++ )
- {
- boxBuf[ 2*i ] = color >> 8;
- boxBuf[ 2*i + 1 ] = color;
- }
-
- /** set the locations */
-
- // adjust for the offset
- OLED_AdjustColumnOffset(xCrd);
- OLED_AdjustRowOffset(yCrd);
-
- OLED_SendCmd( OLED_CMD_SET_COLUMN, FIRST_BYTE);
- OLED_SendCmd( xCrd, OTHER_BYTE );
- OLED_SendCmd( xCrd + (width-1), OTHER_BYTE );
- OLED_SendCmd( OLED_CMD_SET_ROW, FIRST_BYTE );
- OLED_SendCmd( yCrd, OTHER_BYTE );
- OLED_SendCmd( yCrd + (height-1), OTHER_BYTE );
-
-
- // fill the GRAM
- OLED_SendData( (uint8_t*)boxBuf, boxSize*OLED_BYTES_PER_PIXEL );
-
- OLED_DestroyDynamicArea();
-
- }
-
- return status;
-}
-
-/**
- * fill the entire screen
- * @param color color to fill with
- * @return status flag
- */
-void OLED::OLED_FillScreen( uint16_t color )
-{
- /** fill the screen buffer with color */
- for ( uint16_t i = 0; i < ( OLED_SCREEN_WIDTH * OLED_SCREEN_HEIGHT ); i++ )
- {
- screenBuf[ 2*i ] = color >> 8;
- screenBuf[ 2*i + 1 ] = color;
- }
-
- /** set the locations */
- SetBorders( 0, 0, OLED_SCREEN_WIDTH, OLED_SCREEN_HEIGHT );
-
- /** fill GRAM */
- OLED_SendData( (uint8_t*)screenBuf, OLED_SCREEN_WIDTH * OLED_SCREEN_HEIGHT * OLED_BYTES_PER_PIXEL );
-
-}
-
-
-
-oled_status_t OLED::OLED_DrawPixel (
- int16_t xCrd,
- int16_t yCrd,
- uint16_t color
- )
-{
- // check the bounds
- if AreCoordsNotValid( xCrd, yCrd, 1, 1 )
- {
- return OLED_STATUS_INIT_ERROR;
- }
-
- else
- {
- // set directions
- SetBorders( xCrd, yCrd, OLED_SCREEN_WIDTH, OLED_SCREEN_HEIGHT);
-
- uint16_t
- // swap bytes
- dot = color;
-
- OLED_SwapMe(dot);
-
- // fill the GRAM
- OLED_SendData( (uint8_t*)&dot, 2 );
-
- return OLED_STATUS_SUCCESS;
- }
-}
-
-
-oled_status_t OLED::OLED_DrawScreen (
- const uint8_t* image,
- uint8_t xCrd,
- uint8_t yCrd,
- uint8_t width,
- uint8_t height,
- oled_transition_t transition
- )
-{
- oled_status_t
- status = OLED_STATUS_SUCCESS;
-
- if AreCoordsNotValid( xCrd, yCrd, width, height )
- {
- return OLED_STATUS_INIT_ERROR;
- }
-
- switch ( transition )
- {
- case OLED_TRANSITION_NONE: {
- /** set the locations */
- SetBorders( xCrd, yCrd, width, height);
-
- // fill the GRAM
- OLED_SendData( (const uint8_t*)image, width * height * OLED_BYTES_PER_PIXEL );
- break;
- }
-
- case OLED_TRANSITION_TOP_DOWN: {
- TopDown( image, xCrd, yCrd, width, height );
- break;
- }
-
- case OLED_TRANSITION_DOWN_TOP: {
- DownTop( image, xCrd, yCrd, width, height );
- break;
- }
-
- case OLED_TRANSITION_LEFT_RIGHT: {
- LeftRight( image, xCrd, yCrd, width, height );
- break;
- }
-
- case OLED_TRANSITION_RIGHT_LEFT: {
- RightLeft( image, xCrd, yCrd, width, height );
- break;
- }
-
- default: {}
- }
-
- return status;
-}
-
-
-oled_status_t OLED::OLED_SetFont(
- const uint8_t* newFont,
- uint16_t newColor
- )
-{
- /** save the new values in intern variables */
-
- selectedFont = newFont;
- // selectedFont_firstChar = newFont[2] + (newFont[3] << 8);
- selectedFont_firstChar = newFont[2] | ( (uint16_t)newFont[3] << 8 );
- // selectedFont_lastChar = newFont[4] + (newFont[5] << 8);
- selectedFont_lastChar = newFont[4] | ( (uint16_t)newFont[5] << 8 );
- selectedFont_height = newFont[6];
- selectedFont_color = newColor;
-
- OLED_SwapMe( selectedFont_color );
-
- isFontInitialized = 1;
- return OLED_STATUS_SUCCESS;
-}
-
-
-void OLED::OLED_SetDynamicArea(oled_dynamic_area_t *dynamic_area)
-{
-
- if( NULL == oled_dynamic_area.areaBuffer )
- {
- oled_dynamic_area.areaBuffer = (oled_pixel_t)AllocateDynamicArea( dynamic_area->width * dynamic_area->height );
- }
- else if(
- ( dynamic_area->height != oled_dynamic_area.height ) ||
- ( dynamic_area->width != oled_dynamic_area.width )
- )
- {
- OLED_DestroyDynamicArea();
- oled_dynamic_area.areaBuffer = (oled_pixel_t)AllocateDynamicArea( dynamic_area->width * dynamic_area->height );
- }
-
- oled_dynamic_area.xCrd = dynamic_area->xCrd;
- oled_dynamic_area.yCrd = dynamic_area->yCrd;
- oled_dynamic_area.width = dynamic_area->width;
- oled_dynamic_area.height = dynamic_area->height;
-}
-
-
-void OLED::OLED_DestroyDynamicArea()
-{
- if ( NULL != oled_dynamic_area.areaBuffer )
- {
- DestroyDynamicArea( oled_dynamic_area.areaBuffer );
- oled_dynamic_area.areaBuffer = NULL;
- }
-}
-
-
-void OLED::OLED_SetTextProperties(oled_text_properties_t *textProperties)
-{
- oled_text_properties.font = textProperties->font;
- oled_text_properties.fontColor = textProperties->fontColor;
- oled_text_properties.alignParam = textProperties->alignParam;
- oled_text_properties.background = textProperties->background;
-
- OLED_SetFont( oled_text_properties.font, oled_text_properties.fontColor );
-}
-
-
-
-
-uint8_t OLED::OLED_GetTextWidth(const uint8_t* text)
-{
- uint8_t chrCnt = 0;
- uint8_t text_width = 0;
-
- while ( 0 != text[chrCnt] )
- {
- text_width += *( selectedFont + 8 + (uint16_t)( ( text[chrCnt++] - selectedFont_firstChar ) << 2 ) );
- // make 1px space between chars
- text_width++;
- }
- // remove the final space
- text_width--;
-
- return text_width;
-}
-
-
-
-uint8_t OLED::OLED_CharCount(uint8_t width, const uint8_t* font, const uint8_t* text, uint8_t length)
-{
- uint8_t chrCnt = 0;
- uint8_t text_width = 0;
- uint16_t firstChar;
-
- firstChar = font[2] | ( (uint16_t)font[3] << 8 );
-
- while ( chrCnt < length )
- {
- text_width += *( font + 8 + (uint16_t)( ( text[chrCnt++] - firstChar ) << 2 ) );
- if(text_width > width)
- {
- chrCnt--;
- break;
- }
- // make 1px space between chars
- text_width++;
- }
-
- return chrCnt;
-}
-
-
-oled_status_t OLED::OLED_AddText( const uint8_t* text )
-{
- uint16_t
- chrCnt = 0;
- oled_pixel_t
- chrBuf = NULL;
-
- uint8_t
- currentChar_x = 0,
- currentChar_y = 0;
-
- uint8_t
- text_height = 0,
- text_width = 0;
-
- text_width = OLED_GetTextWidth(text);
-
- /**
- * set default values, if necessary
- */
-
- text_height = selectedFont_height;
-
- if (( oled_dynamic_area.width < text_width )||( oled_dynamic_area.height < text_height ))
- {
- oled_dynamic_area_t
- textArea;
-
- textArea.width = text_width;
- textArea.height = text_height;
- OLED_SetDynamicArea( &textArea );
- }
-
- // oled_dynamic_area.width = text_width;
- // oled_dynamic_area.height = text_height;
- // // malloc new text space
- // OLED_DestroyDynamicArea();
- // oled_dynamic_area.areaBuffer = (oled_pixel_t)AllocateDynamicArea( oled_dynamic_area.width * oled_dynamic_area.height );
-
- // if ( NULL == oled_dynamic_area.areaBuffer )
- // {
- // return OLED_STATUS_INIT_ERROR;
- // }
-
- currentChar_y = ( oled_dynamic_area.height - text_height ) >> 1;
-
- switch ( oled_text_properties.alignParam & OLED_TEXT_HALIGN_MASK )
- {
- case OLED_TEXT_ALIGN_LEFT:
- {
- currentChar_x = 0;
- break;
- }
-
- case OLED_TEXT_ALIGN_RIGHT:
- {
- currentChar_x = ( oled_dynamic_area.width - text_width );
- break;
- }
-
- case OLED_TEXT_ALIGN_CENTER:
- {
- currentChar_x += ( oled_dynamic_area.width - text_width ) >> 1 ;
- break;
- }
-
- case OLED_TEXT_ALIGN_NONE:
- {
- break;
- }
-
- default: {}
- }
-
- if ( CreateTextBackground() != OLED_STATUS_SUCCESS )
- {
- return OLED_STATUS_ERROR;
- }
-
- /**
- * write the characters into designated space, one by one
- */
-
- chrCnt = 0;
- while ( 0 != text[chrCnt] )
- {
- WriteCharToBuf( text[chrCnt++], &chrBuf );
-
- if ( NULL == chrBuf )
- {
- return OLED_STATUS_INIT_ERROR;
- }
-
- else
- {
- if (
- ( ( currentChar_x + currentChar_width ) > oled_dynamic_area.width )
- || ( ( currentChar_y + currentChar_height ) > oled_dynamic_area.height )
- )
- {
- DestroyDynamicArea( chrBuf );
- chrBuf = NULL;
- return OLED_STATUS_ERROR;
- }
-
- // copy data
- oled_pixel_t
- copyAddr = oled_dynamic_area.areaBuffer + ( currentChar_y * oled_dynamic_area.width + currentChar_x );
-
- AddCharToTextArea( chrBuf, currentChar_width, currentChar_height, copyAddr, oled_dynamic_area.width );
-
- currentChar_x += ( currentChar_width+1 );
- currentChar_y += 0;
-
- DestroyDynamicArea( chrBuf );
- chrBuf = NULL;
- }
- }
-
- OLED_UpdateBuffer(
- oled_dynamic_area.xCrd,
- oled_dynamic_area.yCrd,
- oled_dynamic_area.width,
- oled_dynamic_area.height,
- (const uint8_t*)oled_dynamic_area.areaBuffer
- );
-
- return OLED_STATUS_SUCCESS;
-}
-
-
-
-
-oled_status_t OLED::OLED_DrawText ( const uint8_t* text )
-{
-
- if ( NULL == text )
- {
- return OLED_STATUS_ERROR;
- }
-
- OLED_AddText( text );
-
- // set the locations
- SetBorders( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height );
-
- // fill the GRAM
- OLED_SendData( (const uint8_t*)oled_dynamic_area.areaBuffer, oled_dynamic_area.width * oled_dynamic_area.height * OLED_BYTES_PER_PIXEL );
-
-
-// free( currentTextAreaImage );
- return OLED_STATUS_SUCCESS;
-}
-
-
-void OLED::OLED_GetImageDimensions(uint8_t *width, uint8_t *height, const uint8_t* image)
-{
- *height = image[2] + (image[3] << 8);
- *width = image[4] + (image[5] << 8);
-}
-
-
-
-oled_status_t OLED::OLED_AddImage ( const uint8_t* image )
-{
- oled_status_t
- status = OLED_STATUS_SUCCESS;
-
- // check the bounds
- if AreCoordsNotValid( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height )
- {
- status = OLED_STATUS_INIT_ERROR;
- }
-
- else
- {
- OLED_Swap( (oled_pixel_t)oled_dynamic_area.areaBuffer, BMP_SkipHeader(image), oled_dynamic_area.width*oled_dynamic_area.height );
-
- // update the main screen buffer
- OLED_UpdateBuffer( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height, (const uint8_t *)oled_dynamic_area.areaBuffer );
- }
-
- return status;
-}
-
-
-
-oled_status_t OLED::OLED_DrawImage ( const uint8_t* image )
-{
-
- oled_status_t
- status = OLED_STATUS_SUCCESS;
-
- status = OLED_AddImage( image );
-
- // set the locations
- SetBorders( oled_dynamic_area.xCrd, oled_dynamic_area.yCrd, oled_dynamic_area.width, oled_dynamic_area.height );
-
- // fill the GRAM
- OLED_SendData( (const uint8_t*)oled_dynamic_area.areaBuffer, oled_dynamic_area.width * oled_dynamic_area.height * OLED_BYTES_PER_PIXEL );
-
-
- return status;
-}
-
-
-
-void OLED::OLED_DimScreenON()
-{
- for ( int i = 0; i < 16; i++ )
- {
- OLED_SendCmd( OLED_CMD_CONTRASTMASTER, FIRST_BYTE );
- OLED_SendCmd( 0xC0 | (0xF-i), OTHER_BYTE );
- wait_ms(20);
- //OSA_TimeDelay( 20 );
- }
-}
-
-
-void OLED::OLED_DimScreenOFF()
-{
- OLED_SendCmd( OLED_CMD_CONTRASTMASTER, FIRST_BYTE );
- OLED_SendCmd( 0xC0 | 0xF, OTHER_BYTE );
-}
-
-
-
-void OLED::OLED_Swap(
- oled_pixel_t imgDst,
- const uint8_t* imgSrc,
- uint16_t imgSize
- )
-{
- for ( int var = 0; var < imgSize; var++ )
- {
- *imgDst = *imgSrc << 8;
- imgSrc++;
- *imgDst |= *imgSrc;
- imgDst++;
- imgSrc++;
- }
-}
-
-
-void OLED::OLED_PowerON()
-{
- oled_POWER = 1;
-}
-
-void OLED::OLED_PowerOFF()
-{
- oled_POWER = 0;
-}
-
-
-
- //Formerly Known as GuiDriver_UpdateScreen
-void OLED::OLED_UpdateBuffer (
- uint8_t xCrd,
- uint8_t yCrd,
- uint8_t width,
- uint8_t height,
- const uint8_t* image
- )
-{
- // copy data
- oled_pixel_t
- copyAddr = (oled_pixel_t)screenBuf + ( yCrd*OLED_SCREEN_WIDTH + xCrd );
-
- for ( uint8_t i = 0; i < height; i++ )
- {
- memcpy( (void*)copyAddr, (void*)image, width*OLED_BYTES_PER_PIXEL );
- copyAddr += OLED_SCREEN_WIDTH;
- image += width*OLED_BYTES_PER_PIXEL;
- }
-}
-
-/* Internal Functions */
-
-/**
- * [transpose description]
- * @param transImage Transposed Image
- * @param image Source Image
- * @param width Width to Transpose
- * @param height Height to Transpose
- */
-void OLED::Transpose(
- oled_pixel_t transImage,
- const oled_pixel_t image,
- uint8_t width,
- uint8_t height
- )
-{
- for ( uint8_t i = 0; i < height; i++ )
- {
- for ( uint8_t j = 0; j < width ; j++ )
- {
- transImage[ j*height + i ] = image[ i*width + j ];
- }
- }
-}
-
-
-
-/**
- * TopDown Transition Effect for Image
- * @param image image to be transitioned
- * @param xCrd x coordinate of image
- * @param yCrd y coordinate of image
- * @param width width of image
- * @param height height of image
- * @return status flag
- */
-oled_status_t OLED::TopDown(
- const uint8_t* image,
- uint8_t xCrd,
- uint8_t yCrd,
- uint8_t width,
- uint8_t height
- )
-{
- uint16_t
- transStep = OLED_TRANSITION_STEP;
-
- uint16_t
- partImgSize = width*transStep;
-
- oled_status_t
- status = OLED_STATUS_SUCCESS;
-
- uint8_t*
- partImgPtr = (uint8_t*)image + ( height - transStep ) * ( width * OLED_BYTES_PER_PIXEL );
-
- /**
- * set locations
- */
-
- while (1)
- {
- SetBorders( xCrd, yCrd, width, height );
-
- if ( partImgSize > width*height )
- {
- OLED_SendData( (const uint8_t*)image, width*height*OLED_BYTES_PER_PIXEL );
- break;
- }
- else
- {
- OLED_SendData( (const uint8_t*)partImgPtr, partImgSize * OLED_BYTES_PER_PIXEL );
- }
-
-
- /**
- * update variables
- */
-
- partImgPtr -= ( width * transStep ) * OLED_BYTES_PER_PIXEL;
- partImgSize += ( width * transStep );
- transStep++;
- }
-
- return status;
-}
-
-/**
- * DownTop Transition Effect for Image
- * @param image image to be transitioned
- * @param xCrd x coordinate of image
- * @param yCrd y coordinate of image
- * @param width width of image
- * @param height height of image
- * @return status flag
- */
-
-oled_status_t OLED::DownTop(
- const uint8_t* image,
- uint8_t xCrd,
- uint8_t yCrd,
- uint8_t width,
- uint8_t height
- )
-{
- uint16_t
- transStep = OLED_TRANSITION_STEP;
-
- uint16_t
- partImgSize = width*transStep;
-
- oled_status_t
- status = OLED_STATUS_SUCCESS;
-
- uint8_t*
- partImgPtr = (uint8_t*)image;
-
- uint8_t
- yCrd_moving = ( yCrd + height ) - 1;
-
- /**
- * set locations
- */
-
- while (1)
- {
- if (
- ( partImgSize > OLED_SCREEN_SIZE )
- || ( yCrd_moving < yCrd )
- )
- {
- // draw full image
- SetBorders( xCrd, yCrd, width, height );
- OLED_SendData( (const uint8_t*)image, width * height * OLED_BYTES_PER_PIXEL );
- break;
- }
-
- else
- {
- SetBorders( xCrd, yCrd_moving, width, ( yCrd + height ) - yCrd_moving );
- OLED_SendData( (const uint8_t*)partImgPtr, partImgSize * OLED_BYTES_PER_PIXEL );
- }
-
- /**
- * update variables
- */
-
- yCrd_moving -= transStep;
- partImgSize += ( width * transStep );
- transStep++;
- }
-
- return status;
-}
-
-
-/**
- * LeftRight Transition Effect for Image
- * @param image image to be transitioned
- * @param xCrd x coordinate of image
- * @param yCrd y coordinate of image
- * @param width width of image
- * @param height height of image
- * @return status flag
- */
-
-oled_status_t OLED::LeftRight(
- const uint8_t* image,
- uint8_t xCrd,
- uint8_t yCrd,
- uint8_t width,
- uint8_t height
- )
-{
- oled_status_t
- status = OLED_STATUS_SUCCESS;
-
- oled_dynamic_area_t
- transImageArea =
- {
- .xCrd = 0,
- .yCrd = 0,
-
- .width = 96,
- .height= 96
- };
-
- OLED_SetDynamicArea( &transImageArea );
-
- // helper pointer
- oled_pixel_t
- transImage = (oled_pixel_t)oled_dynamic_area.areaBuffer;
-
- if ( NULL == transImage )
- {
- return OLED_STATUS_INIT_ERROR;
- }
-
- Transpose( (oled_pixel_t)transImage, (const oled_pixel_t)image, width, height );
-
- OLED_SendCmd( OLED_CMD_SET_REMAP, FIRST_BYTE );
- OLED_SendCmd( OLED_REMAP_SETTINGS | REMAP_VERTICAL_INCREMENT, OTHER_BYTE );
-
- uint16_t
- transStep = OLED_TRANSITION_STEP;
-
- uint16_t
- partImgSize = height*transStep;
-
- uint8_t*
- partImgPtr = (uint8_t*)transImage + ( width - transStep ) * ( height * OLED_BYTES_PER_PIXEL );
-
- /**
- * set locations
- */
-
- while (1)
- {
- SetBorders( xCrd, yCrd, width, height );
-
- if ( partImgSize > width*height )
- {
- OLED_SendData((const uint8_t*)transImage, width * height * OLED_BYTES_PER_PIXEL );
- break;
- }
- else
- {
- OLED_SendData( (const uint8_t*)partImgPtr, partImgSize * OLED_BYTES_PER_PIXEL );
- }
-
-
- partImgPtr -= ( transStep * height ) * OLED_BYTES_PER_PIXEL;
- partImgSize += ( transStep * height );
- transStep++;
-
- }
-
- OLED_SendCmd( OLED_CMD_SET_REMAP, FIRST_BYTE );
- OLED_SendCmd( OLED_REMAP_SETTINGS, OTHER_BYTE );
-
- OLED_DestroyDynamicArea();
- return status;
-}
-
-
-/**
- * RightLeft Transition Effect for Image
- * @param image image to be transitioned
- * @param xCrd x coordinate of image
- * @param yCrd y coordinate of image
- * @param width width of image
- * @param height height of image
- * @return status flag
- */
-oled_status_t OLED::RightLeft(
- const uint8_t* image,
- uint8_t xCrd,
- uint8_t yCrd,
- uint8_t width,
- uint8_t height
- )
-{
- oled_dynamic_area_t
- transImageArea =
- {
- .xCrd = 0,
- .yCrd = 0,
-
- .width = 96,
- .height= 96
- };
-
- OLED_SetDynamicArea( &transImageArea );
-
- // helper pointer
- oled_pixel_t
- transImage = oled_dynamic_area.areaBuffer;
-
- if ( NULL == transImage )
- {
- return OLED_STATUS_INIT_ERROR;
- }
-
- Transpose( (oled_pixel_t)transImage, (const oled_pixel_t)image, width, height );
-
- OLED_SendCmd( OLED_CMD_SET_REMAP, FIRST_BYTE );
- OLED_SendCmd( OLED_REMAP_SETTINGS | REMAP_VERTICAL_INCREMENT, OTHER_BYTE );
-
-
- uint16_t
- transStep = OLED_TRANSITION_STEP;
-
- uint16_t
- partImgSize = height * transStep;
-
- uint8_t*
- partImgPtr = (uint8_t*)transImage;
-
- uint8_t
- xCrd_moving = ( xCrd + width ) - 1;
-
- /** set locations */
-
- while (1)
- {
- if (( partImgSize > width*height )|| ( xCrd_moving < xCrd ))
- {
- SetBorders( xCrd, yCrd, width, height );
- OLED_SendData( (const uint8_t*)transImage, height * width * OLED_BYTES_PER_PIXEL );
- break;
- }
- else
- {
- SetBorders( xCrd_moving, yCrd, ( xCrd + width ) - xCrd_moving, height );
- OLED_SendData( (const uint8_t*)partImgPtr, partImgSize * OLED_BYTES_PER_PIXEL );
- }
-
- /** update variables*/
-
- xCrd_moving -= transStep;
- partImgSize += ( height * transStep );
- transStep++;
- }
-
- OLED_SendCmd( OLED_CMD_SET_REMAP, FIRST_BYTE );
- OLED_SendCmd( OLED_REMAP_SETTINGS, OTHER_BYTE );
-
- OLED_DestroyDynamicArea();
-
- return OLED_STATUS_SUCCESS;
-}
-
-
-/**
- * [setDirection description]
- * @param self [description]
- * @param xCrd [description]
- * @param yCrd [description]
- * @return [description]
- */
-void OLED::SetBorders(
- uint8_t xCrd,
- uint8_t yCrd,
- uint8_t width,
- uint8_t height
- )
-{
-
- // adjust for the offset
- OLED_AdjustColumnOffset(xCrd);
- OLED_AdjustRowOffset(yCrd);
-
- OLED_SendCmd( OLED_CMD_SET_COLUMN, FIRST_BYTE );
- OLED_SendCmd( xCrd, OTHER_BYTE );
- OLED_SendCmd( xCrd + (width-1), OTHER_BYTE );
- OLED_SendCmd( OLED_CMD_SET_ROW, FIRST_BYTE );
- OLED_SendCmd( yCrd, OTHER_BYTE );
- OLED_SendCmd( yCrd + (height-1), OTHER_BYTE );
-
-}
-
-/**
- * create the buffer for a partial image
- * @param imgBuf [description]
- * @param width [description]
- * @param height [description]
- * @return [description]
- */
-oled_status_t OLED::CreateTextBackground()
-{
- uint8_t
- xCrd = oled_dynamic_area.xCrd,
- yCrd = oled_dynamic_area.yCrd,
- width = oled_dynamic_area.width,
- height = oled_dynamic_area.height;
-
- oled_pixel_t
- imgBuf = oled_dynamic_area.areaBuffer,
- copyAddr;
-
- const uint8_t*
- background = oled_text_properties.background;
-
- /** copy data */
-
- if (
- ( NULL == imgBuf )
- || ( ( xCrd + width ) > OLED_SCREEN_WIDTH )
- || ( ( yCrd + height ) > OLED_SCREEN_HEIGHT )
- )
- {
- return OLED_STATUS_INIT_ERROR;
- }
-
- if ( NULL == background )
- {
- for ( uint8_t i = 0; i < height; i++ )
- {
- memset( (void*)imgBuf, 0, width*OLED_BYTES_PER_PIXEL );
- imgBuf += width;
- }
- }
-
- else
- {
- copyAddr = (oled_pixel_t)( BMP_SkipHeader( background ) ) + ( yCrd*OLED_SCREEN_WIDTH + xCrd );
- for ( uint8_t i = 0; i < height; i++ )
- {
- OLED_Swap( (oled_pixel_t)imgBuf, (const uint8_t*)copyAddr, width );
- imgBuf += width;
- copyAddr += OLED_SCREEN_WIDTH;
- }
- }
-
- return OLED_STATUS_SUCCESS;
-}
-
-
-/**
- * Write the character to Buffer
- * @param charToWrite character to be written
- * @param chrBuf given pointer for buffer for the character
- */
-void OLED::WriteCharToBuf(
- uint16_t charToWrite,
- oled_pixel_t* chrBuf
- )
-{
- uint8_t
- foo = 0,
- mask;
-
- const uint8_t*
- pChTable = selectedFont + 8 + (uint16_t)( ( charToWrite - selectedFont_firstChar ) << 2 );
-
- currentChar_width = *pChTable,
- currentChar_height = selectedFont_height;
-
- uint32_t
- offset = (uint32_t)pChTable[1]
- | ( (uint32_t)pChTable[2] << 8 )
- | ( (uint32_t)pChTable[3] << 16 );
-
- const uint8_t*
- pChBitMap = selectedFont + offset;
-
- if ( 0 == isFontInitialized )
- {
- // default font
- OLED_SetFont( oledFont_Tahoma_8_Regular, COLOR_WHITE );
- }
-
- // allocate space for char image
- *chrBuf = (oled_pixel_t)AllocateDynamicArea( currentChar_height * currentChar_width );
-
- if ( NULL == *chrBuf )
- {
- return;
- }
-
- for ( uint8_t yCnt = 0; yCnt < currentChar_height; yCnt++ )
- {
- mask = 0;
-
- for ( uint8_t xCnt = 0; xCnt < currentChar_width; xCnt++ )
- {
- if ( 0 == mask )
- {
- mask = 1;
- foo = *pChBitMap++;
- }
-
- if ( 0 != ( foo & mask ) )
- {
- *( *chrBuf + yCnt*currentChar_width + xCnt ) = selectedFont_color;
- }
-
- else
- {
- *( *chrBuf + yCnt*currentChar_width + xCnt ) = 0;
- }
-
- mask <<= 1;
- }
- }
-}
-
-
-
-/**
- * Add subimage/character to the active image buffer
- * @param xOffset offset for the x-coordinate
- * @param yOffset offset for the y-coordinate
- * @param width desired width
- * @param height desired height
- * @return status flag
- */
-oled_status_t OLED::AddCharToTextArea(
- oled_pixel_t chrPtr,
- uint8_t chrWidth,
- uint8_t chrHeight,
- oled_pixel_t copyAddr,
- uint8_t imgWidth
- )
-{
- if ( NULL == copyAddr )
- {
- return OLED_STATUS_INIT_ERROR;
- }
-
- for ( uint8_t i = 0; i < chrHeight; i++ )
- {
- for ( uint8_t j = 0; j < chrWidth; j++ )
- {
- if ( 0 != chrPtr[j] )
- {
- copyAddr[j] = chrPtr[j];
- }
- }
- copyAddr += imgWidth;
- chrPtr += chrWidth;
- }
- return OLED_STATUS_SUCCESS;
-}
-
-
-/**
- * Allocate memory for the desired image/character
- * @param area desired area dimensions
- */
-void* OLED::AllocateDynamicArea( uint32_t area )
-{
- void*
- ptr = malloc( area * OLED_BYTES_PER_PIXEL );
-
- if ( NULL == ptr )
- {
- return NULL;
- }
-
- return ptr;
-}
-
-
-/**
- * Deallocate current area
- * @param area pointer to current area
- */
-oled_status_t OLED::DestroyDynamicArea( void* ptr )
-{
- if ( NULL == ptr )
- {
- return OLED_STATUS_INIT_ERROR;
- }
-
- free(ptr);
-
- return OLED_STATUS_SUCCESS;
-}
-
-
-
-
-
-
--- a/OLED_driver.h Wed Aug 17 22:08:40 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,282 +0,0 @@
-#ifndef HG_OLED_DRIVER
-#define HG_OLED_DRIVER
-
-#include "mbed.h"
-#include "OLED_types.h"
-#include "OLED_info.h"
-
-
-
-class OLED{
-
-public:
-
-
- OLED(PinName mosi,PinName sclk,PinName pwr, PinName cs,PinName rst, PinName dc);
-
- ~OLED();
-
- /**
- * Send the command to OLED
- * @param self OLED handle
- * @param cmd OLED command from the datasheet
- * @param isFirst designate if this is the first byte in the command
- */
- void OLED_SendCmd(uint32_t cmd,
- uint8_t isFirst);
-
-
- /**
- * Send data to OLED
- * @param dataToSend data to send to OLED
- * @param dataSize data-size
- */
- void OLED_SendData ( const uint8_t* dataToSend,
- uint32_t dataSize);
-
- /**
- * draw box on OLED
- * @param xCrd x-coordinate for box's uper left corner
- * @param yCrd y-coordinate for box's uper left corner
- * @param width box's width
- * @param height box's height
- * @param color color of the box
- * @return status flag
- */
- oled_status_t OLED_DrawBox (
- uint16_t xCrd,
- uint16_t yCrd,
- uint16_t width,
- uint16_t height,
- uint16_t color
- );
-
- /**
- * Fill the entire screen with specified color
- * @param color color to fill with
- */
- void OLED_FillScreen( uint16_t color );
-
-
-
- /**
- * Draw a single pixel
- * @param xCrd pixel's x coordinate
- * @param yCrd pixel's y coordinate
- * @param color pixel's color
- * @return status flag
- */
- oled_status_t OLED_DrawPixel (
- int16_t xCrd,
- int16_t yCrd,
- uint16_t color
- );
-
-
- /**
- * Draw the whole screen
- * @param image image to draw
- * @param xCrd image x-coordinate
- * @param yCrd image y-coordinate
- * @param width image width
- * @param height image height
- * @param transition transition style for the new image arrival
- * @return status flag
- */
- oled_status_t OLED_DrawScreen (
- const uint8_t* image,
- uint8_t xCrd,
- uint8_t yCrd,
- uint8_t width,
- uint8_t height,
- oled_transition_t transition
- );
-
-
- /**
- * Set the font to use
- * @param newFont desired font
- * @param newColor desired color
- * @return status flag
- */
- oled_status_t OLED_SetFont(
- const uint8_t* newFont,
- uint16_t newColor
- );
-
-
- /**
- * Set OLED dynamic area
- * @param dynamic_area data-structure with desired values
- */
- void OLED_SetDynamicArea(oled_dynamic_area_t *dynamic_area);
-
- /**
- * Destroy current OLED dynamic area
- */
- void OLED_DestroyDynamicArea();
-
-
- /**
- * Set OLED text properties
- * @param textProperties data-structure with desired properties
- */
- void OLED_SetTextProperties(oled_text_properties_t *textProperties);
-
-
- /**
- * Return the width in [px] required for the given string to be displayed
- * @param text desired string
- * @return required text width in [px]
- */
- uint8_t OLED_GetTextWidth(const uint8_t* text);
-
-
- /**
- * Count the characters
- * @param width text width
- * @param font text font
- * @param text given text string
- * @param length text length
- * @return character count
- */
- uint8_t OLED_CharCount(uint8_t width, const uint8_t* font, const uint8_t* text, uint8_t length);
-
- /**
- * Add text to the main screen buffer
- * @param text text to add
- * @return status flag
- */
- oled_status_t OLED_AddText( const uint8_t* text );
-
- /**
- * Write text on OLED at position set in Dynamic Area Field
- * @param text desired text
- * @param x x-coordinate for the given text, set through .dynamicArea variable
- * @param y y-coordinate for the given text, set through .dynamicArea variable
- */
- oled_status_t OLED_DrawText ( const uint8_t* text );
-
-
- /**
- * Return the dimensions of image
- * @param width given image's width
- * @param height given image's height
- * @param image desired image
- */
- void OLED_GetImageDimensions(uint8_t *width, uint8_t *height, const uint8_t* image);
-
-
-
- /**
- * Add image to the main screen buffer
- * @param image desired image
- * @return status flag
- */
- oled_status_t OLED_AddImage ( const uint8_t* image );
-
- /**
- * Draw image, i.e. send image to OLED GRAM
- * @param image desired image
- * @param transition desired transition style for the new image
- * @return status flag
- */
- oled_status_t OLED_DrawImage ( const uint8_t* image );
-
- /**
- * Dim OLED screen on
- */
- void OLED_DimScreenON();
-
- /**
- * Return OLED back to full contrast
- */
- void OLED_DimScreenOFF();
-
- /**
- * Swap image's bytes per pixel to obtain the correct color format
- * @param imgDst desired image
- * @param imgSrc original image
- * @param imgSize image's size
- */
- void OLED_Swap(
- oled_pixel_t imgDst,
- const uint8_t* imgSrc,
- uint16_t imgSize
- );
-
-
- /**
- * Turn on Power for OLED Display
- */
- void OLED_PowerON();
-
- /**
- * Turn off Power for OLED Display
- */
- void OLED_PowerOFF();
-
- /**
- * update the main screen buffer
- * with the given image
-
- * @param xCrd image x-coordinate
- * @param yCrd image y-coordinate
- * @param width image width
- * @param height image height
- * @param image image for buffer
- */
- void OLED_UpdateBuffer (
- uint8_t xCrd,
- uint8_t yCrd,
- uint8_t width,
- uint8_t height,
- const uint8_t* image
- );
-
-
-
-private:
-
- SPI oled_SPI;
- DigitalOut oled_POWER;
- DigitalOut oled_CS;
- DigitalOut oled_RST;
- DigitalOut oled_DC;
-
-
- const uint8_t* selectedFont;
-
- uint8_t
- isFontInitialized,
- currentChar_width,
- currentChar_height,
- screenBuf[OLED_GRAM_SIZE];
-
- uint16_t
- selectedFont_color,
- selectedFont_firstChar, // first character in the font table
- selectedFont_lastChar, // last character in the font table
- selectedFont_height,
- colorMask;
-
- oled_dynamic_area_t oled_dynamic_area;
- oled_text_properties_t oled_text_properties;
-
-
- //Internal Functions
- void Transpose( oled_pixel_t transImage, const oled_pixel_t image, uint8_t width, uint8_t height );
- oled_status_t TopDown ( const uint8_t* image, uint8_t xCrd, uint8_t yCrd, uint8_t width, uint8_t height );
- oled_status_t DownTop ( const uint8_t* image, uint8_t xCrd, uint8_t yCrd, uint8_t width, uint8_t height );
- oled_status_t LeftRight ( const uint8_t* image, uint8_t xCrd, uint8_t yCrd, uint8_t width, uint8_t height );
- oled_status_t RightLeft ( const uint8_t* image, uint8_t xCrd, uint8_t yCrd, uint8_t width, uint8_t height );
- void SetBorders( uint8_t xCrd, uint8_t yCrd, uint8_t width, uint8_t height );
- oled_status_t CreateTextBackground();
- void WriteCharToBuf( uint16_t charToWrite, oled_pixel_t* chrBuf );
- oled_status_t AddCharToTextArea( oled_pixel_t chrPtr, uint8_t chrWidth, uint8_t chrHeight, oled_pixel_t copyAddr, uint8_t imgWidth );
- void* AllocateDynamicArea( uint32_t area );
- oled_status_t DestroyDynamicArea(void * ptr);
-
-};
-
-#endif
\ No newline at end of file
--- a/OLED_fonts.c Wed Aug 17 22:08:40 2016 +0000
+++ b/OLED_fonts.c Thu Aug 18 23:01:06 2016 +0000
@@ -2359,3 +2359,4 @@
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x04,0x72,0x06,0xC3,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Code for char num 126
0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0F,0x00,0x00,0x00,0x00,0x00,0x00 // Code for char num 127
};
+
--- a/OLED_fonts.h Wed Aug 17 22:08:40 2016 +0000 +++ b/OLED_fonts.h Thu Aug 18 23:01:06 2016 +0000 @@ -16,3 +16,4 @@ extern const uint8_t oledFont_Exo_2_Condensed21x32_Regular[]; #endif +
--- a/OLED_info.h Wed Aug 17 22:08:40 2016 +0000 +++ b/OLED_info.h Thu Aug 18 23:01:06 2016 +0000 @@ -255,3 +255,4 @@ #define OLED_CMD_STARTSCROLL (0x9F) #endif +
--- a/OLED_types.h Wed Aug 17 22:08:40 2016 +0000 +++ b/OLED_types.h Thu Aug 18 23:01:06 2016 +0000 @@ -105,3 +105,4 @@ #endif +