#include "ssd1306_spi.h" #include "screen.h" static struct { struct { uint16_t uiStartPageIndex; uint16_t uiStartColumnIndex; uint16_t uiEndPageIndex; uint16_t uiEndColumnIndex; }stUpdateArea; uint16_t auiDisplayCache[LCD_SIZE_WIDTH][LCD_SIZE_PAGES]; }s_stLCDBuffer; static void SCREEN_UpdateChangedBufferAreaRecord(uint8_t uiPageIndex, uint8_t uiColumnIndex); static void SCREEN_ClearDisplayBuffer(void); /*************************************************************************/ /** Function Name: SCREEN_UpdateChangedBufferAreaRecord **/ /** Purpose: Check changed area recodr and update. **/ /** Resources: None. **/ /** Params: **/ /** @ uiPageIndex: Operated page index. **/ /** @ uiColumnIndex: Operated column index. **/ /** Return: None. **/ /** Limitation: None. **/ /*************************************************************************/ void SCREEN_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 SCREEN_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[uiCurrentColumnIndex][uiCurrentPageIndex] = 0x00; } } s_stLCDBuffer.stUpdateArea.uiStartPageIndex = (LCD_SIZE_HEIGHT/8) - 1; s_stLCDBuffer.stUpdateArea.uiEndPageIndex = 0; s_stLCDBuffer.stUpdateArea.uiStartColumnIndex = LCD_SIZE_WIDTH - 1; s_stLCDBuffer.stUpdateArea.uiEndColumnIndex = 0; } /*************************************************************************/ /** Function Name: SCREEN_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 SCREEN_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. SCREEN_UpdateChangedBufferAreaRecord(iPosY/8, iPosX); // Set point data. if(SCREEN_COLOR_FRG == iColor) { SET_PAGE_BIT(s_stLCDBuffer.auiDisplayCache[iPosX][iPosY/8], iPosY%8); } else { CLR_PAGE_BIT(s_stLCDBuffer.auiDisplayCache[iPosX][iPosY/8], iPosY%8); } } } /*************************************************************************/ /** Function Name: SCREEN_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 SCREEN_GetPixel(int iPosX, int iPosY) { // Operating position check. if((iPosX < LCD_SIZE_WIDTH) && (iPosY < LCD_SIZE_HEIGHT)) { return GET_PAGE_BIT(s_stLCDBuffer.auiDisplayCache[iPosX][iPosY/8], iPosY%8); } else { return 0; } } /*************************************************************************/ /** Function Name: SCREEN_Initialize **/ /** Purpose: Simple delay function for KS0108 controler. **/ /** Resources: None. **/ /** Params: None. **/ /** Return: None. **/ /** Limitation: None. **/ /*************************************************************************/ int SCREEN_Initialize(void) { SSD1306_Initialize(); SCREEN_ClearDisplayBuffer(); return 0; } /*************************************************************************/ /** Function Name: LCD_RefreshScreen **/ /** Purpose: Update Screen with cache data. **/ /** Resources: None. **/ /** Params: None. **/ /** Return: None. **/ /** Limitation: None. **/ /*************************************************************************/ void SCREEN_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; SSD1306_SetPosition(s_stLCDBuffer.stUpdateArea.uiStartColumnIndex, uiChangedPageIndex); // Loop for each changed column data in current page. while(uiChangedColumnIndex <= s_stLCDBuffer.stUpdateArea.uiEndColumnIndex) { // Write data to screen controler. SSD1306_WriteData(s_stLCDBuffer.auiDisplayCache[uiChangedColumnIndex][uiChangedPageIndex]); uiChangedColumnIndex++; } uiChangedPageIndex++; } // Reset global variable. s_stLCDBuffer.stUpdateArea.uiStartPageIndex = (LCD_SIZE_HEIGHT/8) - 1; s_stLCDBuffer.stUpdateArea.uiEndPageIndex = 0; s_stLCDBuffer.stUpdateArea.uiStartColumnIndex = LCD_SIZE_WIDTH - 1; s_stLCDBuffer.stUpdateArea.uiEndColumnIndex = 0; } /*************************************************************************/ /** Function Name: SCREEN_ClearDisplay **/ /** Purpose: Clean display buffer. **/ /** Resources: None. **/ /** Params: None. **/ /** Return: None. **/ /** Limitation: None. **/ /*************************************************************************/ void SCREEN_ClearDisplay(void) { SCREEN_ClearDisplayBuffer(); SSD1306_Fill(0x00); }