#include "OLED.h" static struct { struct { uint16_t uiStartPageIndex; uint16_t uiStartColumnIndex; uint16_t uiEndPageIndex; uint16_t uiEndColumnIndex; }stUpdateArea; uint16_t auiDisplayCache[LCD_SIZE_PAGES][LCD_SIZE_WIDTH]; }s_stLCDBuffer; static void OLED_SetPosition(uint8_t uiPosPage, uint8_t uiPosColumn); static void OLED_UpdateChangedBufferAreaRecord(uint8_t uiPageIndex, uint8_t uiColumnIndex); static void OLED_ClearDisplayBuffer(void); /*************************************************************************/ /** Function Name: OLED_SetPosition **/ /** Purpose: Set current position referring page and column. **/ /** Resources: None. **/ /** Params: **/ /** @ ui_PosColumn: Set column of position. **/ /** @ ui_PosPage: Set page of position. **/ /** Return: None. **/ /** Limitation: None. **/ /*************************************************************************/ void OLED_SetPosition(uint8_t uiPosPage, uint8_t uiPosColumn) { /* Page position check */ if((LCD_SIZE_WIDTH > uiPosColumn) && (LCD_SIZE_PAGES > uiPosPage)) { SSD1306_SPI_SetPosition(uiPosColumn, uiPosPage); } } /*************************************************************************/ /** Function Name: OLED_UpdateChangedBufferAreaRecord **/ /** Purpose: Check changed area recodr and update. **/ /** Resources: None. **/ /** Params: **/ /** @ uiPageIndex: Operated page index. **/ /** @ uiColumnIndex: Operated column index. **/ /** Return: None. **/ /** Limitation: None. **/ /*************************************************************************/ void OLED_UpdateChangedBufferAreaRecord(uint8_t uiPageIndex, uint8_t uiColumnIndex) { // Check and set page and column index. if(uiPageIndex < s_stLCDBuffer.stUpdateArea.uiStartPageIndex) { s_stLCDBuffer.stUpdateArea.uiStartPageIndex = uiPageIndex; } if(uiPageIndex > s_stLCDBuffer.stUpdateArea.uiEndPageIndex) { s_stLCDBuffer.stUpdateArea.uiEndPageIndex = uiPageIndex; } if(uiColumnIndex < s_stLCDBuffer.stUpdateArea.uiStartColumnIndex) { s_stLCDBuffer.stUpdateArea.uiStartColumnIndex = uiColumnIndex; } if(uiColumnIndex > s_stLCDBuffer.stUpdateArea.uiEndColumnIndex) { s_stLCDBuffer.stUpdateArea.uiEndColumnIndex = uiColumnIndex; } } /*************************************************************************/ /** Function Name: LCD_ClearDisplayBuffer **/ /** Purpose: Clean display buffer. **/ /** Resources: None. **/ /** Params: None. **/ /** Return: None. **/ /** Limitation: None. **/ /*************************************************************************/ void OLED_ClearDisplayBuffer(void) { uint16_t uiCurrentPageIndex, uiCurrentColumnIndex; for(uiCurrentPageIndex = 0; uiCurrentPageIndex < LCD_SIZE_PAGES; uiCurrentPageIndex++) { for(uiCurrentColumnIndex = 0; uiCurrentColumnIndex < LCD_SIZE_WIDTH; uiCurrentColumnIndex++) { s_stLCDBuffer.auiDisplayCache[uiCurrentPageIndex][uiCurrentColumnIndex] = 0x00; } } s_stLCDBuffer.stUpdateArea.uiStartPageIndex = 0; s_stLCDBuffer.stUpdateArea.uiEndPageIndex = LCD_SIZE_PAGES - 1; s_stLCDBuffer.stUpdateArea.uiStartColumnIndex = 0; s_stLCDBuffer.stUpdateArea.uiEndColumnIndex = LCD_SIZE_WIDTH - 1; } /*************************************************************************/ /** Function Name: OLED_SetPixel **/ /** Purpose: Set a pixel color or draw a point. **/ /** Resources: None. **/ /** Params: **/ /** @ iPosX: X location of point by pixels. **/ /** @ iPosY: Y location of point by pixels. **/ /** @ iColor: Point color, 0 is white, Nonzero is Black. **/ /** Return: None. **/ /** Limitation: None. **/ /*************************************************************************/ void OLED_SetPixel(int iPosX, int iPosY, int iColor) { // Operating position check. if((iPosX < LCD_SIZE_WIDTH) && (iPosY < LCD_SIZE_HEIGHT)) { // Check and set page and column index. OLED_UpdateChangedBufferAreaRecord(iPosX, iPosX); // Set point data. if(OLED_COLOR_FRG == iColor) { SET_PAGE_BIT(s_stLCDBuffer.auiDisplayCache[iPosY/8][iPosX], iPosY%8); } else { CLR_PAGE_BIT(s_stLCDBuffer.auiDisplayCache[iPosY/8][iPosX], iPosY%8); } } } /*************************************************************************/ /** Function Name: OLED_GetPixel **/ /** Purpose: Get a pixel from buffer. **/ /** Resources: None. **/ /** Params: **/ /** @ iPosX: X location of point by pixels. **/ /** @ iPosY: Y location of point by pixels. **/ /** Return: None. **/ /** Limitation: None. **/ /*************************************************************************/ int OLED_GetPixel(int iPosX, int iPosY) { // Operating position check. if((iPosX < LCD_SIZE_WIDTH) && (iPosY < LCD_SIZE_HEIGHT)) { return GET_PAGE_BIT(s_stLCDBuffer.auiDisplayCache[iPosY/8][iPosX], iPosY%8); } else { return 0; } } /*************************************************************************/ /** Function Name: OLED_Initialize **/ /** Purpose: Simple delay function for KS0108 controler. **/ /** Resources: None. **/ /** Params: None. **/ /** Return: None. **/ /** Limitation: None. **/ /*************************************************************************/ void OLED_Initialize(void) { SSD1306_SPI_Initialize(); OLED_ClearDisplayBuffer(); } /*************************************************************************/ /** Function Name: LCD_RefreshScreen **/ /** Purpose: Update Screen with cache data. **/ /** Resources: None. **/ /** Params: None. **/ /** Return: None. **/ /** Limitation: None. **/ /*************************************************************************/ void OLED_RefreshScreen(void) { uint8_t uiChangedPageIndex, uiChangedColumnIndex; if(s_stLCDBuffer.stUpdateArea.uiEndColumnIndex > LCD_SIZE_WIDTH-1) { s_stLCDBuffer.stUpdateArea.uiEndColumnIndex = LCD_SIZE_WIDTH-1; } if(s_stLCDBuffer.stUpdateArea.uiEndPageIndex > (LCD_SIZE_HEIGHT/8)-1) { s_stLCDBuffer.stUpdateArea.uiEndPageIndex = (LCD_SIZE_HEIGHT/8)-1; } uiChangedPageIndex = s_stLCDBuffer.stUpdateArea.uiStartPageIndex; // Loop for each changed page. while(uiChangedPageIndex <= s_stLCDBuffer.stUpdateArea.uiEndPageIndex) { uiChangedColumnIndex = s_stLCDBuffer.stUpdateArea.uiStartColumnIndex; OLED_SetPosition(uiChangedPageIndex, s_stLCDBuffer.stUpdateArea.uiStartColumnIndex); // Loop for each changed column data in current page. while(uiChangedColumnIndex <= s_stLCDBuffer.stUpdateArea.uiEndColumnIndex) { // Write data to screen controler. SSD1306_SPI_WriteData(s_stLCDBuffer.auiDisplayCache[uiChangedPageIndex][uiChangedColumnIndex]); uiChangedColumnIndex++; } uiChangedPageIndex++; } // Reset global variable. s_stLCDBuffer.stUpdateArea.uiStartPageIndex = 0; s_stLCDBuffer.stUpdateArea.uiEndPageIndex = (LCD_SIZE_HEIGHT/8) - 1; s_stLCDBuffer.stUpdateArea.uiStartColumnIndex = 0; s_stLCDBuffer.stUpdateArea.uiEndColumnIndex = LCD_SIZE_WIDTH - 1; } /*************************************************************************/ /** Function Name: OLED_ClearDisplay **/ /** Purpose: Clean display buffer. **/ /** Resources: None. **/ /** Params: None. **/ /** Return: None. **/ /** Limitation: None. **/ /*************************************************************************/ void OLED_ClearDisplay(void) { OLED_ClearDisplayBuffer(); SSD1306_SPI_Clear(); }