From 337969f9305219f8357d120b1ea7be267116ea8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n?= Date: Thu, 1 Dec 2022 14:27:53 +0100 Subject: [PATCH 01/11] Testing drawline functions --- lib/ssd1306.c | 229 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 178 insertions(+), 51 deletions(-) diff --git a/lib/ssd1306.c b/lib/ssd1306.c index 4d6ffdc..a2997a9 100644 --- a/lib/ssd1306.c +++ b/lib/ssd1306.c @@ -1,7 +1,7 @@ -/** - * --------------------------------------------------------------------------------------+ +/** + * --------------------------------------------------------------------------------------+ * @desc SSD1306 OLED Driver - * --------------------------------------------------------------------------------------+ + * --------------------------------------------------------------------------------------+ * Copyright (C) 2020 Marian Hrinko. * Written by Marian Hrinko (mato.hrinko@gmail.com) * @@ -13,14 +13,14 @@ * @tested AVR Atmega328p * * @depend font.h, twi.h - * --------------------------------------------------------------------------------------+ + * --------------------------------------------------------------------------------------+ * @descr Version 1.0 -> applicable for 1 display * Version 2.0 -> rebuild to 'cacheMemLcd' array * Version 3.0 -> remove 'cacheMemLcd' approach - * --------------------------------------------------------------------------------------+ + * --------------------------------------------------------------------------------------+ * @usage Basic Setup for OLED Display */ - + #include "ssd1306.h" // +---------------------------+ @@ -107,7 +107,7 @@ const uint8_t INIT_SSD1306[] PROGMEM = { // 0x00 - Horizontal Addressing Mode // 0x01 - Vertical Addressing Mode // 0x02 - Page Addressing Mode (RESET) - 2, SSD1306_SET_COLUMN_ADDR, START_COLUMN_ADDR, END_COLUMN_ADDR, // 0x21 = Set Column Address, 0 - 127 + 2, SSD1306_SET_COLUMN_ADDR, START_COL_ADDR, END_COL_ADDR, // 0x21 = Set Column Address, 0 - 127 2, SSD1306_SET_PAGE_ADDR, START_PAGE_ADDR, END_PAGE_ADDR, // 0x22 = Set Page Address, 0 - 7 0, SSD1306_SET_START_LINE, // 0x40 1, SSD1306_DISPLAY_OFFSET, 0x00, // 0xD3 @@ -125,7 +125,7 @@ const uint8_t INIT_SSD1306[] PROGMEM = { 0, SSD1306_DISPLAY_ON // 0xAF = Set Display ON }; -unsigned short int _indexCol = START_COLUMN_ADDR; // @var global - cache index column +unsigned short int _indexCol = START_COL_ADDR; // @var global - cache index column unsigned short int _indexPage = START_PAGE_ADDR; // @var global - cache index page /** @@ -136,7 +136,7 @@ unsigned short int _indexPage = START_PAGE_ADDR; // @var global * @return uint8_t */ uint8_t SSD1306_Init (void) -{ +{ const uint8_t *commands = INIT_SSD1306; // variables unsigned short int no_of_commands = pgm_read_byte(commands++); // number of commands uint8_t no_of_arguments; // number od arguments @@ -205,7 +205,7 @@ uint8_t SSD1306_Send_StartAndSLAW (uint8_t address) if (SSD1306_SUCCESS != status) { // check status return status; // error } - + return SSD1306_SUCCESS; // success } @@ -221,7 +221,7 @@ uint8_t SSD1306_Send_Command (uint8_t command) uint8_t status = INIT_STATUS; // TWI init status 0xFF // TWI send control byte - // ------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------------------- status = TWI_MT_Send_Data (SSD1306_COMMAND); // send control byte if (SSD1306_SUCCESS != status) { // check status return status; // error @@ -338,7 +338,30 @@ uint8_t SSD1306_ClearScreen (void) * * @return void */ -uint8_t SSD1306_SetPosition (uint8_t x, uint8_t y) +uint8_t SSD1306_SetPosition (uint8_t x, uint8_t y) +{ + uint8_t status = INIT_STATUS; // TWI init status 0xFF + + // Set Window + // ------------------------------------------------------------------------------------- + status = SSD1306_SetWindow (x, END_COL_ADDR, y, END_PAGE_ADDR); + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + return SSD1306_SUCCESS; // success +} + +/** + * @desc SSD1306 Set window + * + * @param uint8_t x1 / column -> 0 ... 127 + * @param uint8_t x2 / column -> 0 ... 127 + * @param uint8_t y1 / page -> 0 ... 7 + * @param uint8_t y2 / page -> 0 ... 7 + * + * @return void + */ +uint8_t SSD1306_SetWindow (uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2) { uint8_t status = INIT_STATUS; // TWI init status 0xFF @@ -349,18 +372,18 @@ uint8_t SSD1306_SetPosition (uint8_t x, uint8_t y) return status; // error } // COLUMN - // ------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------------------- status = SSD1306_Send_Command (SSD1306_SET_COLUMN_ADDR); // 0x21 if (SSD1306_SUCCESS != status) { // check status return status; // error } // start COLUMN - status = SSD1306_Send_Command (x); + status = SSD1306_Send_Command (x1); if (SSD1306_SUCCESS != status) { // check status return status; // error } // end COLUMN - status = SSD1306_Send_Command (END_COLUMN_ADDR); // 127 + status = SSD1306_Send_Command (x2); if (SSD1306_SUCCESS != status) { // check status return status; // error } @@ -374,12 +397,12 @@ uint8_t SSD1306_SetPosition (uint8_t x, uint8_t y) return status; // error } // start PAGE - status = SSD1306_Send_Command (y); + status = SSD1306_Send_Command (y1); if (SSD1306_SUCCESS != status) { // check status return status; // error } // end PAGE - status = SSD1306_Send_Command (END_PAGE_ADDR); // 7 for 128x64 + status = SSD1306_Send_Command (y2); if (SSD1306_SUCCESS != status) { // check status return status; // error } @@ -401,14 +424,14 @@ uint8_t SSD1306_SetPosition (uint8_t x, uint8_t y) * * @return uint8_t */ -uint8_t SSD1306_UpdatePosition (void) +uint8_t SSD1306_UpdatePosition (void) { uint8_t status = INIT_STATUS; // TWI init status 0xFF uint8_t x = _indexCol + CHARS_COLS_LENGTH + 1; // check end col position // check position // ------------------------------------------------------------------------------------- - if (x > END_COLUMN_ADDR) { + if (x > END_COL_ADDR) { // last page not reached // ----------------------------------------------------------------------------------- if (_indexPage < END_PAGE_ADDR) { @@ -422,10 +445,10 @@ uint8_t SSD1306_UpdatePosition (void) // last page reached // ----------------------------------------------------------------------------------- if (_indexPage >= END_PAGE_ADDR) { - return SSD1306_ERROR; // return out of range + return SSD1306_ERROR; // return out of range } } - + return SSD1306_SUCCESS; // success } @@ -474,7 +497,6 @@ uint8_t SSD1306_DrawChar (char ch) if (SSD1306_SUCCESS != status) { // check status return status; // error } - _indexCol = _indexCol + CHARS_COLS_LENGTH + 1; // update global col // TWI stop @@ -496,7 +518,7 @@ uint8_t SSD1306_DrawString (char *str) uint8_t i = 0; // char counter // send characters of string - // ------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------------------- while (str[i] != '\0') { SSD1306_DrawChar (str[i++]); // send char } @@ -514,33 +536,59 @@ uint8_t SSD1306_DrawString (char *str) */ uint8_t SSD1306_DrawPixel (uint8_t x, uint8_t y) { - uint8_t page = 0; // page - uint8_t pixel = 0; // pixel + uint8_t page = y >> 3; // page + uint8_t pixel = 1 << (y - (page << 3)); // pixel uint8_t status = INIT_STATUS; // TWI init status 0xFF - + if ((x > MAX_X) && (y > MAX_Y)) { // if out of range return SSD1306_ERROR; // error } - page = y >> 3; // find page (y / 8) - pixel = 1 << (y - (page << 3)); // which pixel (y % 8) - - // set position - // ------------------------------------------------------------------------------------- - status = SSD1306_SetPosition (x, page); // update position - if (SSD1306_SUCCESS != status) { // check status - return status; // error - } - // TWI start & SLAW // ------------------------------------------------------------------------------------- status = SSD1306_Send_StartAndSLAW (SSD1306_ADDR); // start & SLAW if (SSD1306_SUCCESS != status) { // check status return status; // error } + // COLUMN + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_Command (SSD1306_SET_COLUMN_ADDR); // 0x21 + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + // start COLUMN + status = SSD1306_Send_Command (x); + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + // end COLUMN + status = SSD1306_Send_Command (x); + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + _indexCol = x; // update column index + + // PAGE + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_Command (SSD1306_SET_PAGE_ADDR); // 0x22 + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + // start PAGE + status = SSD1306_Send_Command (page); + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + // end PAGE + status = SSD1306_Send_Command (page); + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + _indexPage = y; // update page index + // TWI control byte data stream // ------------------------------------------------------------------------------------- - status = TWI_MT_Send_Data (SSD1306_DATA_STREAM); // send data 0x40 + status = TWI_MT_Send_Data (SSD1306_DATA); // send data 0xC0 if (SSD1306_SUCCESS != status) { // check status return status; // error } @@ -558,8 +606,96 @@ uint8_t SSD1306_DrawPixel (uint8_t x, uint8_t y) return SSD1306_SUCCESS; // success } +/** + * @desc Draw line horizontal + * + * @param uint8_t x + * @param uint8_t y1 + * @param uint8_t y2 + * + * @return uint8_t + */ +uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) +{ + uint8_t i = 0; // counter + uint8_t len = x2 - x1; // length + uint8_t page = y >> 3; // page + uint8_t pixel = 1 << (y - (page << 3)); // pixel + uint8_t status = INIT_STATUS; // TWI init status 0xFF + + if ((x > MAX_X) && (y > MAX_Y)) { // if out of range + return SSD1306_ERROR; // error + } + + // TWI start & SLAW + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_StartAndSLAW (SSD1306_ADDR); // start & SLAW + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + // COLUMN + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_Command (SSD1306_SET_COLUMN_ADDR); // 0x21 + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + // start COLUMN + status = SSD1306_Send_Command (x1); + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + // end COLUMN + status = SSD1306_Send_Command (x2); + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + _indexCol = x; // update column index + + // PAGE + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_Command (SSD1306_SET_PAGE_ADDR); // 0x22 + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + // start PAGE + status = SSD1306_Send_Command (page); + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + // end PAGE + status = SSD1306_Send_Command (page); + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + _indexPage = y; // update column index + + // TWI control byte data stream + // ------------------------------------------------------------------------------------- + status = TWI_MT_Send_Data (SSD1306_DATA_STREAM); // send data 0x40 + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + + // send pixels + // ------------------------------------------------------------------------------------- + while (i < len) { + status = TWI_MT_Send_Data (pixel); // send pixel + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + i++; + } + + // TWI stop + // ------------------------------------------------------------------------------------- + TWI_Stop (); + + return SSD1306_SUCCESS; // success return +} + /** * @desc Draw line by Bresenham algoritm + * @note Approach with DrawPixel function takes 11 bytes for drawing 1 pixel * * @param uint8_t x start position / 0 <= cols <= MAX_X-1 * @param uint8_t x end position / 0 <= cols <= MAX_X-1 @@ -573,34 +709,25 @@ uint8_t SSD1306_DrawLine (uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2) int16_t D; // determinant int16_t delta_x, delta_y; // deltas int16_t trace_x = 1, trace_y = 1; // steps + uint16_t buffer[]; // buffer delta_x = x2 - x1; // delta x delta_y = y2 - y1; // delta y - // Vertical line - // ------------------------------------------------------------------------------------- - if (delta_x == 0) { - status = SSD1306_DrawLineVert (x1, y1, y2); // draw vertical line - if (SSD1306_SUCCESS != status) { // check status - return status; // error - } - return SSD1306_SUCCESS; // success return - } - // Horizontal line + // draw line with faster draw horizontal line function // ------------------------------------------------------------------------------------- if (delta_y == 0) { - status = SSD1306_DrawLineHorz (y1, x1, x2); // draw horizontal line + status = SSD1306_DrawLineHorz (y1, x1, x2); // draw horiyontal line if (SSD1306_SUCCESS != status) { // check status return status; // error } - return SSD1306_SUCCESS; // success return - } + return SSD1306_SUCCESS; // success return + } if (delta_x < 0) { // check if x2 > x1 delta_x = -delta_x; // negate delta x trace_x = -trace_x; // negate step x } - if (delta_y < 0) { // check if y2 > y1 delta_y = -delta_y; // negate delta y trace_y = -trace_y; // negate step y From 59d4912c0f717a6e52f721ee1db8d7fb40fea6f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n?= Date: Thu, 1 Dec 2022 14:38:26 +0100 Subject: [PATCH 02/11] Small modifications --- lib/ssd1306.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/ssd1306.c b/lib/ssd1306.c index a2997a9..71caa89 100644 --- a/lib/ssd1306.c +++ b/lib/ssd1306.c @@ -21,6 +21,7 @@ * @usage Basic Setup for OLED Display */ +// @includes #include "ssd1306.h" // +---------------------------+ @@ -125,8 +126,8 @@ const uint8_t INIT_SSD1306[] PROGMEM = { 0, SSD1306_DISPLAY_ON // 0xAF = Set Display ON }; -unsigned short int _indexCol = START_COL_ADDR; // @var global - cache index column -unsigned short int _indexPage = START_PAGE_ADDR; // @var global - cache index page +uint8_t _indexCol = START_COL_ADDR; // @var global - cache index column +uint8_t _indexPage = START_PAGE_ADDR; // @var global - cache index page /** * @desc SSD1306 Init @@ -137,8 +138,8 @@ unsigned short int _indexPage = START_PAGE_ADDR; // @var global */ uint8_t SSD1306_Init (void) { - const uint8_t *commands = INIT_SSD1306; // variables - unsigned short int no_of_commands = pgm_read_byte(commands++); // number of commands + const uint8_t * commands = INIT_SSD1306; // variables + uint8_t no_of_commands = pgm_read_byte (commands++); // number of commands uint8_t no_of_arguments; // number od arguments uint8_t command; // command uint8_t status = INIT_STATUS; // TWI init status 0xFF @@ -172,7 +173,6 @@ uint8_t SSD1306_Init (void) return status; // error } } - no_of_commands--; // next command } // TWI STOP @@ -185,7 +185,7 @@ uint8_t SSD1306_Init (void) /** * @desc SSD1306 Send Start and SLAW request * - * @param uint8_t + * @param uint8_t address * * @return uint8_t */ @@ -264,7 +264,7 @@ uint8_t SSD1306_NormalScreen (void) } /** - * @desc SSD1306 Inverse colors + * @desc SSD1306 Inverse screen colors * * @param void * @@ -333,8 +333,8 @@ uint8_t SSD1306_ClearScreen (void) /** * @desc SSD1306 Set position * - * @param uint8_t column -> 0 ... 127 - * @param uint8_t page -> 0 ... 7 + * @param uint8_t x / column -> 0 ... 127 + * @param uint8_t y / page -> 0 ... 7 * * @return void */ @@ -667,7 +667,7 @@ uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) if (SSD1306_SUCCESS != status) { // check status return status; // error } - _indexPage = y; // update column index + _indexPage = y; // update page index // TWI control byte data stream // ------------------------------------------------------------------------------------- @@ -695,7 +695,7 @@ uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) /** * @desc Draw line by Bresenham algoritm - * @note Approach with DrawPixel function takes 11 bytes for drawing 1 pixel + * @note Approach with DrawPixel function takes 9 bytes for drawing 1 pixel * * @param uint8_t x start position / 0 <= cols <= MAX_X-1 * @param uint8_t x end position / 0 <= cols <= MAX_X-1 From 2ce548babaf474bd458bb4bafa3b8387a3b72a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n?= Date: Thu, 1 Dec 2022 15:00:32 +0100 Subject: [PATCH 03/11] Small modifications --- lib/ssd1306.h | 104 +++++++++++++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 39 deletions(-) diff --git a/lib/ssd1306.h b/lib/ssd1306.h index b514e42..52cdeb7 100644 --- a/lib/ssd1306.h +++ b/lib/ssd1306.h @@ -1,22 +1,23 @@ -/** - * ---------------------------------------------------------------+ +/** + * -------------------------------------------------------------------------------------+ * @desc SSD1306 OLED Driver - * ---------------------------------------------------------------+ + * -------------------------------------------------------------------------------------+ * Copyright (C) 2020 Marian Hrinko. * Written by Marian Hrinko (mato.hrinko@gmail.com) * * @author Marian Hrinko * @datum 06.10.2020 - * @update 19.07.2021 + * @update 21.11.2022 * @file ssd1306.h - * @version 2.0 - * @tested AVR Atmega328 + * @version 3.0 + * @tested AVR Atmega328p * * @depend font.h, twi.h - * ---------------------------------------------------------------+ + * -------------------------------------------------------------------------------------+ * @descr Version 1.0 -> applicable for 1 display * Version 2.0 -> rebuild to 'cacheMemLcd' array - * ---------------------------------------------------------------+ + * Version 3.0 -> remove 'cacheMemLcd' approach + * -------------------------------------------------------------------------------------+ * @usage Basic Setup for OLED Display */ @@ -24,24 +25,20 @@ #define __SSD1306_H__ // includes - #include #include "font.h" #include "twi.h" - // Success - // ------------------------------------------- + // Success / Error + // ------------------------------------------------------------------------------------ #define SSD1306_SUCCESS 0 - - // Error - // ------------------------------------------- #define SSD1306_ERROR 1 // Address definition - // ----------------------------------- + // ------------------------------------------------------------------------------------ #define SSD1306_ADDR 0x3C // Command definition - // ----------------------------------- + // ------------------------------------------------------------------------------------ #define SSD1306_COMMAND 0x80 // Continuation bit=1, D/C=0; 1000 0000 #define SSD1306_COMMAND_STREAM 0x00 // Continuation bit=0, D/C=0; 0000 0000 #define SSD1306_DATA 0xC0 // Continuation bit=1, D/C=1; 1100 0000 @@ -73,27 +70,24 @@ #define SSD1306_VCOM_DESELECT 0xDB // Clear Color - // ----------------------------------- + // ------------------------------------------------------------------------------------ #define CLEAR_COLOR 0x00 // Init Status - // ----------------------------------- + // ------------------------------------------------------------------------------------ #define INIT_STATUS 0xFF // AREA definition - // ----------------------------------- + // ------------------------------------------------------------------------------------ #define START_PAGE_ADDR 0 - #define END_PAGE_ADDR 7 - #define START_COLUMN_ADDR 0 - #define END_COLUMN_ADDR 127 + #define END_PAGE_ADDR 7 // 7 for 128x64, 3 for 128x32 version + #define START_COL_ADDR 0 + #define END_COL_ADDR 127 - #define CACHE_SIZE_MEM (1 + END_PAGE_ADDR) * (1 + END_COLUMN_ADDR) + #define CACHE_SIZE_MEM (1 + END_PAGE_ADDR) * (1 + END_COL_ADDR) - #define MAX_X END_COLUMN_ADDR - #define MAX_Y (END_PAGE_ADDR+1)*8 - - // @var set area - unsigned int _counter; + #define MAX_X END_COL_ADDR + #define MAX_Y (END_PAGE_ADDR + 1) * 8 /** * @desc SSD1306 Init @@ -107,7 +101,7 @@ /** * @desc SSD1306 Send Start and SLAW request * - * @param uint8_t + * @param uint8_t address * * @return uint8_t */ @@ -116,7 +110,7 @@ /** * @desc SSD1306 Send command * - * @param uint8_t + * @param uint8_t command * * @return uint8_t */ @@ -149,6 +143,15 @@ */ uint8_t SSD1306_InverseScreen (void); + /** + * @desc SSD1306 Update screen + * + * @param void + * + * @return uint8_t + */ + uint8_t SSD1306_UpdateScreen (void); + /** * @desc SSD1306 Update text position * @@ -161,13 +164,25 @@ /** * @desc SSD1306 Set position * - * @param uint8_t - * @param uint8_t + * @param uint8_t x + * @param uint8_t y * * @return uint8_t */ uint8_t SSD1306_SetPosition (uint8_t, uint8_t); + /** + * @desc SSD1306 Set window + * + * @param uint8_t x1 + * @param uint8_t x2 + * @param uint8_t y1 + * @param uint8_t y2 + * + * @return void + */ + uint8_t SSD1306_SetWindow (uint8_t, uint8_t, uint8_t, uint8_t); + /** * @desc SSD1306 Draw character * @@ -189,20 +204,31 @@ /** * @desc Draw pixel * - * @param uint8_t - * @param uint8_t + * @param uint8_t x + * @param uint8_t y * * @return uint8_t */ uint8_t SSD1306_DrawPixel (uint8_t, uint8_t); + /** + * @desc Draw line horizontal + * + * @param uint8_t y + * @param uint8_t x1 + * @param uint8_t x2 + * + * @return uint8_t + */ + uint8_t SSD1306_DrawLineHorz (uint8_t, uint8_t, uint8_t); + /** * @desc Draw line - * - * @param uint8_t - * @param uint8_t - * @param uint8_t - * @param uint8_t + * + * @param uint8_t x1 + * @param uint8_t x2 + * @param uint8_t y1 + * @param uint8_t y2 * * @return uint8_t */ From 6e7aff46ef5f702b6212e38f1b808d4930d38318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n?= Date: Thu, 1 Dec 2022 15:30:11 +0100 Subject: [PATCH 04/11] Small modification --- lib/ssd1306.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/ssd1306.c b/lib/ssd1306.c index 71caa89..8ce4eea 100644 --- a/lib/ssd1306.c +++ b/lib/ssd1306.c @@ -103,18 +103,21 @@ const uint8_t INIT_SSD1306[] PROGMEM = { 18, // number of initializers 0, SSD1306_DISPLAY_OFF, // 0xAE = Set Display OFF - 1, SSD1306_SET_MUX_RATIO, 0x3F, // 0xA8 - 64MUX + 1, SSD1306_SET_MUX_RATIO, 0x3F, // 0xA8 - 0x3F = 64MUX - for 128x64 version + // 0x1F = 32MUX - for 128x32 version 1, SSD1306_MEMORY_ADDR_MODE, 0x00, // 0x20 = Set Memory Addressing Mode // 0x00 - Horizontal Addressing Mode // 0x01 - Vertical Addressing Mode // 0x02 - Page Addressing Mode (RESET) - 2, SSD1306_SET_COLUMN_ADDR, START_COL_ADDR, END_COL_ADDR, // 0x21 = Set Column Address, 0 - 127 - 2, SSD1306_SET_PAGE_ADDR, START_PAGE_ADDR, END_PAGE_ADDR, // 0x22 = Set Page Address, 0 - 7 + 2, SSD1306_SET_COLUMN_ADDR, START_COL_ADDR, END_COL_ADDR, // 0x21 = Set Column Address, 0 to 127 + 2, SSD1306_SET_PAGE_ADDR, START_PAGE_ADDR, END_PAGE_ADDR, // 0x22 = Set Page Address, 0 to 7 for 128x64 version or 0 to 3 for 128x32 version 0, SSD1306_SET_START_LINE, // 0x40 1, SSD1306_DISPLAY_OFFSET, 0x00, // 0xD3 0, SSD1306_SEG_REMAP_OP, // 0xA0 / remap 0xA1 - 0, SSD1306_COM_SCAN_DIR_OP, // 0xC0 / remap 0xC8 - 1, SSD1306_COM_PIN_CONF, 0x12, // 0xDA, 0x12 - Disable COM Left/Right remap, Alternative COM pin configuration + 0, SSD1306_COM_SCAN_DIR_OP, // 0xC0 = normal / scan direction COM output + // 0xC8 = remap / scan direction COM output from up to bottom or vice versa + 1, SSD1306_COM_PIN_CONF, 0x12, // 0xDA, 0x12 - for 128x64 version, Disable COM Left/Right remap, Alternative COM pin conf + // 0x02 - for 128x32 version, Disable COM Left/Right remap, Sequential COM pin conf 1, SSD1306_SET_CONTRAST, 0x7F, // 0x81, 0x7F - reset value (max 0xFF) 0, SSD1306_DIS_ENT_DISP_ON, // 0xA4 0, SSD1306_DIS_NORMAL, // 0xA6 @@ -354,10 +357,10 @@ uint8_t SSD1306_SetPosition (uint8_t x, uint8_t y) /** * @desc SSD1306 Set window * - * @param uint8_t x1 / column -> 0 ... 127 - * @param uint8_t x2 / column -> 0 ... 127 - * @param uint8_t y1 / page -> 0 ... 7 - * @param uint8_t y2 / page -> 0 ... 7 + * @param uint8_t x1 / column -> 0 - MAX_X / 127 / + * @param uint8_t x2 / column -> 0 - MAX_X / 127 / + * @param uint8_t y1 / page -> 0 - MAX_Y / 7 for 128x64, 3 for 128x32 ver / + * @param uint8_t y2 / page -> 0 - MAX_Y / 7 for 128x64, 3 for 128x32 ver / * * @return void */ From 09d3f61e56da437f9e413f8be18a0fec584a141f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n?= Date: Thu, 1 Dec 2022 15:43:25 +0100 Subject: [PATCH 05/11] Small modification From 7e155513a89b011d4f806d9057dd5a9a4165ca6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n?= Date: Mon, 5 Dec 2022 22:49:43 +0100 Subject: [PATCH 06/11] V3 drawline horizontal successfull --- lib/ssd1306.c | 199 ++++++++++++++++++++++++++------------------------ 1 file changed, 102 insertions(+), 97 deletions(-) diff --git a/lib/ssd1306.c b/lib/ssd1306.c index 8ce4eea..650fa5d 100644 --- a/lib/ssd1306.c +++ b/lib/ssd1306.c @@ -1,7 +1,7 @@ -/** - * --------------------------------------------------------------------------------------+ +/** + * --------------------------------------------------------------------------------------+ * @desc SSD1306 OLED Driver - * --------------------------------------------------------------------------------------+ + * --------------------------------------------------------------------------------------+ * Copyright (C) 2020 Marian Hrinko. * Written by Marian Hrinko (mato.hrinko@gmail.com) * @@ -13,16 +13,16 @@ * @tested AVR Atmega328p * * @depend font.h, twi.h - * --------------------------------------------------------------------------------------+ + * --------------------------------------------------------------------------------------+ * @descr Version 1.0 -> applicable for 1 display * Version 2.0 -> rebuild to 'cacheMemLcd' array * Version 3.0 -> remove 'cacheMemLcd' approach - * --------------------------------------------------------------------------------------+ + * --------------------------------------------------------------------------------------+ * @usage Basic Setup for OLED Display */ - -// @includes + #include "ssd1306.h" + #include // +---------------------------+ // | Set MUX Ratio | @@ -103,21 +103,21 @@ const uint8_t INIT_SSD1306[] PROGMEM = { 18, // number of initializers 0, SSD1306_DISPLAY_OFF, // 0xAE = Set Display OFF - 1, SSD1306_SET_MUX_RATIO, 0x3F, // 0xA8 - 0x3F = 64MUX - for 128x64 version - // 0x1F = 32MUX - for 128x32 version + 1, SSD1306_SET_MUX_RATIO, 31, // 0xA8 - 64MUX for 128 x 64 version + // - 32MUX for 128 x 32 version 1, SSD1306_MEMORY_ADDR_MODE, 0x00, // 0x20 = Set Memory Addressing Mode // 0x00 - Horizontal Addressing Mode // 0x01 - Vertical Addressing Mode // 0x02 - Page Addressing Mode (RESET) - 2, SSD1306_SET_COLUMN_ADDR, START_COL_ADDR, END_COL_ADDR, // 0x21 = Set Column Address, 0 to 127 - 2, SSD1306_SET_PAGE_ADDR, START_PAGE_ADDR, END_PAGE_ADDR, // 0x22 = Set Page Address, 0 to 7 for 128x64 version or 0 to 3 for 128x32 version + 2, SSD1306_SET_COLUMN_ADDR, START_COLUMN_ADDR, END_COLUMN_ADDR, // 0x21 = Set Column Address, 0 - 127 + 2, SSD1306_SET_PAGE_ADDR, START_PAGE_ADDR, END_PAGE_ADDR, // 0x22 = Set Page Address, 0 - 7 0, SSD1306_SET_START_LINE, // 0x40 1, SSD1306_DISPLAY_OFFSET, 0x00, // 0xD3 0, SSD1306_SEG_REMAP_OP, // 0xA0 / remap 0xA1 - 0, SSD1306_COM_SCAN_DIR_OP, // 0xC0 = normal / scan direction COM output - // 0xC8 = remap / scan direction COM output from up to bottom or vice versa - 1, SSD1306_COM_PIN_CONF, 0x12, // 0xDA, 0x12 - for 128x64 version, Disable COM Left/Right remap, Alternative COM pin conf - // 0x02 - for 128x32 version, Disable COM Left/Right remap, Sequential COM pin conf + 0, SSD1306_COM_SCAN_DIR_OP, // 0xC0 / remap 0xC8 + 1, SSD1306_COM_PIN_CONF, 0x02, // 0xDA, 0x12 - Disable COM Left/Right remap, Alternative COM pin configuration + // 0x12 - for 128 x 64 version + // 0x02 - for 128 x 32 version 1, SSD1306_SET_CONTRAST, 0x7F, // 0x81, 0x7F - reset value (max 0xFF) 0, SSD1306_DIS_ENT_DISP_ON, // 0xA4 0, SSD1306_DIS_NORMAL, // 0xA6 @@ -129,8 +129,8 @@ const uint8_t INIT_SSD1306[] PROGMEM = { 0, SSD1306_DISPLAY_ON // 0xAF = Set Display ON }; -uint8_t _indexCol = START_COL_ADDR; // @var global - cache index column -uint8_t _indexPage = START_PAGE_ADDR; // @var global - cache index page +unsigned short int _indexCol = START_COLUMN_ADDR; // @var global - cache index column +unsigned short int _indexPage = START_PAGE_ADDR; // @var global - cache index page /** * @desc SSD1306 Init @@ -140,9 +140,9 @@ uint8_t _indexPage = START_PAGE_ADDR; // @var global * @return uint8_t */ uint8_t SSD1306_Init (void) -{ - const uint8_t * commands = INIT_SSD1306; // variables - uint8_t no_of_commands = pgm_read_byte (commands++); // number of commands +{ + const uint8_t *commands = INIT_SSD1306; // variables + uint8_t no_of_commands = pgm_read_byte(commands++); // number of commands uint8_t no_of_arguments; // number od arguments uint8_t command; // command uint8_t status = INIT_STATUS; // TWI init status 0xFF @@ -176,6 +176,7 @@ uint8_t SSD1306_Init (void) return status; // error } } + no_of_commands--; // next command } // TWI STOP @@ -188,7 +189,7 @@ uint8_t SSD1306_Init (void) /** * @desc SSD1306 Send Start and SLAW request * - * @param uint8_t address + * @param uint8_t * * @return uint8_t */ @@ -208,7 +209,7 @@ uint8_t SSD1306_Send_StartAndSLAW (uint8_t address) if (SSD1306_SUCCESS != status) { // check status return status; // error } - + return SSD1306_SUCCESS; // success } @@ -224,7 +225,7 @@ uint8_t SSD1306_Send_Command (uint8_t command) uint8_t status = INIT_STATUS; // TWI init status 0xFF // TWI send control byte - // ------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------------------- status = TWI_MT_Send_Data (SSD1306_COMMAND); // send control byte if (SSD1306_SUCCESS != status) { // check status return status; // error @@ -267,7 +268,7 @@ uint8_t SSD1306_NormalScreen (void) } /** - * @desc SSD1306 Inverse screen colors + * @desc SSD1306 Inverse colors * * @param void * @@ -336,35 +337,12 @@ uint8_t SSD1306_ClearScreen (void) /** * @desc SSD1306 Set position * - * @param uint8_t x / column -> 0 ... 127 - * @param uint8_t y / page -> 0 ... 7 + * @param uint8_t column -> 0 ... 127 + * @param uint8_t page -> 0 ... 7 * * @return void */ -uint8_t SSD1306_SetPosition (uint8_t x, uint8_t y) -{ - uint8_t status = INIT_STATUS; // TWI init status 0xFF - - // Set Window - // ------------------------------------------------------------------------------------- - status = SSD1306_SetWindow (x, END_COL_ADDR, y, END_PAGE_ADDR); - if (SSD1306_SUCCESS != status) { // check status - return status; // error - } - return SSD1306_SUCCESS; // success -} - -/** - * @desc SSD1306 Set window - * - * @param uint8_t x1 / column -> 0 - MAX_X / 127 / - * @param uint8_t x2 / column -> 0 - MAX_X / 127 / - * @param uint8_t y1 / page -> 0 - MAX_Y / 7 for 128x64, 3 for 128x32 ver / - * @param uint8_t y2 / page -> 0 - MAX_Y / 7 for 128x64, 3 for 128x32 ver / - * - * @return void - */ -uint8_t SSD1306_SetWindow (uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2) +uint8_t SSD1306_SetPosition (uint8_t x, uint8_t y) { uint8_t status = INIT_STATUS; // TWI init status 0xFF @@ -375,18 +353,18 @@ uint8_t SSD1306_SetWindow (uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2) return status; // error } // COLUMN - // ------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------------------- status = SSD1306_Send_Command (SSD1306_SET_COLUMN_ADDR); // 0x21 if (SSD1306_SUCCESS != status) { // check status return status; // error } // start COLUMN - status = SSD1306_Send_Command (x1); + status = SSD1306_Send_Command (x); if (SSD1306_SUCCESS != status) { // check status return status; // error } // end COLUMN - status = SSD1306_Send_Command (x2); + status = SSD1306_Send_Command (END_COLUMN_ADDR); // 127 if (SSD1306_SUCCESS != status) { // check status return status; // error } @@ -400,12 +378,12 @@ uint8_t SSD1306_SetWindow (uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2) return status; // error } // start PAGE - status = SSD1306_Send_Command (y1); + status = SSD1306_Send_Command (y); if (SSD1306_SUCCESS != status) { // check status return status; // error } // end PAGE - status = SSD1306_Send_Command (y2); + status = SSD1306_Send_Command (END_PAGE_ADDR); // 7 for 128x64 if (SSD1306_SUCCESS != status) { // check status return status; // error } @@ -427,14 +405,14 @@ uint8_t SSD1306_SetWindow (uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2) * * @return uint8_t */ -uint8_t SSD1306_UpdatePosition (void) +uint8_t SSD1306_UpdatePosition (void) { uint8_t status = INIT_STATUS; // TWI init status 0xFF uint8_t x = _indexCol + CHARS_COLS_LENGTH + 1; // check end col position // check position // ------------------------------------------------------------------------------------- - if (x > END_COL_ADDR) { + if (x > END_COLUMN_ADDR) { // last page not reached // ----------------------------------------------------------------------------------- if (_indexPage < END_PAGE_ADDR) { @@ -448,10 +426,10 @@ uint8_t SSD1306_UpdatePosition (void) // last page reached // ----------------------------------------------------------------------------------- if (_indexPage >= END_PAGE_ADDR) { - return SSD1306_ERROR; // return out of range + return SSD1306_ERROR; // return out of range } } - + return SSD1306_SUCCESS; // success } @@ -500,6 +478,7 @@ uint8_t SSD1306_DrawChar (char ch) if (SSD1306_SUCCESS != status) { // check status return status; // error } + _indexCol = _indexCol + CHARS_COLS_LENGTH + 1; // update global col // TWI stop @@ -521,7 +500,7 @@ uint8_t SSD1306_DrawString (char *str) uint8_t i = 0; // char counter // send characters of string - // ------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------------------- while (str[i] != '\0') { SSD1306_DrawChar (str[i++]); // send char } @@ -539,11 +518,11 @@ uint8_t SSD1306_DrawString (char *str) */ uint8_t SSD1306_DrawPixel (uint8_t x, uint8_t y) { - uint8_t page = y >> 3; // page - uint8_t pixel = 1 << (y - (page << 3)); // pixel + uint8_t page = y >> 3; // find page (y / 8) + uint8_t pixel = 1 << (y - (page << 3)); // which pixel (y % 8) uint8_t status = INIT_STATUS; // TWI init status 0xFF - - if ((x > MAX_X) && (y > MAX_Y)) { // if out of range + + if ((x > MAX_X) || (y > MAX_Y)) { // if out of range return SSD1306_ERROR; // error } @@ -569,7 +548,6 @@ uint8_t SSD1306_DrawPixel (uint8_t x, uint8_t y) if (SSD1306_SUCCESS != status) { // check status return status; // error } - _indexCol = x; // update column index // PAGE // ------------------------------------------------------------------------------------- @@ -587,7 +565,6 @@ uint8_t SSD1306_DrawPixel (uint8_t x, uint8_t y) if (SSD1306_SUCCESS != status) { // check status return status; // error } - _indexPage = y; // update page index // TWI control byte data stream // ------------------------------------------------------------------------------------- @@ -612,22 +589,29 @@ uint8_t SSD1306_DrawPixel (uint8_t x, uint8_t y) /** * @desc Draw line horizontal * - * @param uint8_t x - * @param uint8_t y1 - * @param uint8_t y2 + * @param uint8_t + * @param uint8_t + * @param uint8_t * * @return uint8_t */ uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) { + uint8_t status = INIT_STATUS; // TWI init status 0xFF uint8_t i = 0; // counter - uint8_t len = x2 - x1; // length + uint8_t j = 0; // counter uint8_t page = y >> 3; // page uint8_t pixel = 1 << (y - (page << 3)); // pixel - uint8_t status = INIT_STATUS; // TWI init status 0xFF - if ((x > MAX_X) && (y > MAX_Y)) { // if out of range - return SSD1306_ERROR; // error + uint8_t ram[RAM_Y_END][RAM_X_END]; + + while (i < RAM_Y_END) { + if (i == page) { + memset (ram[i], pixel, RAM_X_END); + } else { + memset (ram[i], 0x00, RAM_X_END); + } + i++; } // TWI start & SLAW @@ -643,16 +627,15 @@ uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) return status; // error } // start COLUMN - status = SSD1306_Send_Command (x1); + status = SSD1306_Send_Command (0); if (SSD1306_SUCCESS != status) { // check status return status; // error } // end COLUMN - status = SSD1306_Send_Command (x2); + status = SSD1306_Send_Command (127); if (SSD1306_SUCCESS != status) { // check status return status; // error } - _indexCol = x; // update column index // PAGE // ------------------------------------------------------------------------------------- @@ -661,16 +644,15 @@ uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) return status; // error } // start PAGE - status = SSD1306_Send_Command (page); + status = SSD1306_Send_Command (0); if (SSD1306_SUCCESS != status) { // check status return status; // error } // end PAGE - status = SSD1306_Send_Command (page); + status = SSD1306_Send_Command (3); if (SSD1306_SUCCESS != status) { // check status return status; // error } - _indexPage = y; // update page index // TWI control byte data stream // ------------------------------------------------------------------------------------- @@ -679,13 +661,19 @@ uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) return status; // error } + i = 0; + j = 0; // send pixels // ------------------------------------------------------------------------------------- - while (i < len) { - status = TWI_MT_Send_Data (pixel); // send pixel - if (SSD1306_SUCCESS != status) { // check status - return status; // error + while (i < RAM_Y_END) { + while (j < RAM_X_END) { + status = TWI_MT_Send_Data (ram[i][j]); // send data col + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + j++; } + j = 0; i++; } @@ -693,12 +681,27 @@ uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) // ------------------------------------------------------------------------------------- TWI_Stop (); + return SSD1306_SUCCESS; // success return } +/** + * @desc Draw line vertical + * + * @param uint8_t + * @param uint8_t + * @param uint8_t + * + * @return uint8_t + */ +uint8_t SSD1306_DrawLineVert (uint8_t x, uint8_t y1, uint8_t y2) +{ + + return SSD1306_SUCCESS; // success +} + /** * @desc Draw line by Bresenham algoritm - * @note Approach with DrawPixel function takes 9 bytes for drawing 1 pixel * * @param uint8_t x start position / 0 <= cols <= MAX_X-1 * @param uint8_t x end position / 0 <= cols <= MAX_X-1 @@ -709,32 +712,34 @@ uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) */ uint8_t SSD1306_DrawLine (uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2) { + uint8_t status = INIT_STATUS; // TWI init status 0xFF + int16_t D; // determinant int16_t delta_x, delta_y; // deltas int16_t trace_x = 1, trace_y = 1; // steps - uint16_t buffer[]; // buffer + + if ((x1 > MAX_X) || (y1 > MAX_Y) || + (x2 > MAX_X) || (y2 > MAX_Y) ) { // out of range? + return SSD1306_ERROR; // error + } + + if ((x1 > x2) || (y1 > y2) ) { // start point first? + return SSD1306_ERROR; // error + } delta_x = x2 - x1; // delta x delta_y = y2 - y1; // delta y - // draw line with faster draw horizontal line function + // Horizontal line // ------------------------------------------------------------------------------------- if (delta_y == 0) { - status = SSD1306_DrawLineHorz (y1, x1, x2); // draw horiyontal line + status = SSD1306_DrawLineHorz (y1, x1, x2); // draw horizontal line if (SSD1306_SUCCESS != status) { // check status return status; // error } - return SSD1306_SUCCESS; // success return - } + return SSD1306_SUCCESS; // success return + } - if (delta_x < 0) { // check if x2 > x1 - delta_x = -delta_x; // negate delta x - trace_x = -trace_x; // negate step x - } - if (delta_y < 0) { // check if y2 > y1 - delta_y = -delta_y; // negate delta y - trace_y = -trace_y; // negate step y - } // condition for m < 1 (dy < dx) // ------------------------------------------------------------------------------------- if (delta_y < delta_x) { // From 8bb1973a062d0dd14f7d96d15b9a38ecc44fd58a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n?= Date: Mon, 5 Dec 2022 22:50:38 +0100 Subject: [PATCH 07/11] Remove delay.h --- lib/ssd1306.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ssd1306.c b/lib/ssd1306.c index 650fa5d..846fab9 100644 --- a/lib/ssd1306.c +++ b/lib/ssd1306.c @@ -22,7 +22,6 @@ */ #include "ssd1306.h" - #include // +---------------------------+ // | Set MUX Ratio | From 85cb65f165030ebd235cde62709566e388ceb04b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n?= Date: Mon, 5 Dec 2022 22:52:50 +0100 Subject: [PATCH 08/11] V3 drawline horizontal successful --- lib/ssd1306.h | 89 ++++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/lib/ssd1306.h b/lib/ssd1306.h index 52cdeb7..51c578a 100644 --- a/lib/ssd1306.h +++ b/lib/ssd1306.h @@ -25,6 +25,7 @@ #define __SSD1306_H__ // includes + #include #include "font.h" #include "twi.h" @@ -80,13 +81,15 @@ // AREA definition // ------------------------------------------------------------------------------------ #define START_PAGE_ADDR 0 - #define END_PAGE_ADDR 7 // 7 for 128x64, 3 for 128x32 version - #define START_COL_ADDR 0 - #define END_COL_ADDR 127 + #define END_PAGE_ADDR 3 // 7 for 128x64, 3 for 128x32 version + #define START_COLUMN_ADDR 0 + #define END_COLUMN_ADDR 127 + #define RAM_X_END END_COLUMN_ADDR + 1 + #define RAM_Y_END END_PAGE_ADDR + 1 - #define CACHE_SIZE_MEM (1 + END_PAGE_ADDR) * (1 + END_COL_ADDR) + #define CACHE_SIZE_MEM (1 + END_PAGE_ADDR) * (1 + END_COLUMN_ADDR) - #define MAX_X END_COL_ADDR + #define MAX_X END_COLUMN_ADDR #define MAX_Y (END_PAGE_ADDR + 1) * 8 /** @@ -101,7 +104,7 @@ /** * @desc SSD1306 Send Start and SLAW request * - * @param uint8_t address + * @param uint8_t * * @return uint8_t */ @@ -110,7 +113,7 @@ /** * @desc SSD1306 Send command * - * @param uint8_t command + * @param uint8_t * * @return uint8_t */ @@ -143,15 +146,6 @@ */ uint8_t SSD1306_InverseScreen (void); - /** - * @desc SSD1306 Update screen - * - * @param void - * - * @return uint8_t - */ - uint8_t SSD1306_UpdateScreen (void); - /** * @desc SSD1306 Update text position * @@ -164,25 +158,13 @@ /** * @desc SSD1306 Set position * - * @param uint8_t x - * @param uint8_t y + * @param uint8_t + * @param uint8_t * * @return uint8_t */ uint8_t SSD1306_SetPosition (uint8_t, uint8_t); - /** - * @desc SSD1306 Set window - * - * @param uint8_t x1 - * @param uint8_t x2 - * @param uint8_t y1 - * @param uint8_t y2 - * - * @return void - */ - uint8_t SSD1306_SetWindow (uint8_t, uint8_t, uint8_t, uint8_t); - /** * @desc SSD1306 Draw character * @@ -204,34 +186,45 @@ /** * @desc Draw pixel * - * @param uint8_t x - * @param uint8_t y + * @param uint8_t + * @param uint8_t * * @return uint8_t */ uint8_t SSD1306_DrawPixel (uint8_t, uint8_t); - /** - * @desc Draw line horizontal - * - * @param uint8_t y - * @param uint8_t x1 - * @param uint8_t x2 - * - * @return uint8_t - */ - uint8_t SSD1306_DrawLineHorz (uint8_t, uint8_t, uint8_t); - /** * @desc Draw line - * - * @param uint8_t x1 - * @param uint8_t x2 - * @param uint8_t y1 - * @param uint8_t y2 + * + * @param uint8_t + * @param uint8_t + * @param uint8_t + * @param uint8_t * * @return uint8_t */ uint8_t SSD1306_DrawLine (uint8_t, uint8_t, uint8_t, uint8_t); + /** + * @desc Draw line horizontal + * + * @param uint8_t + * @param uint8_t + * @param uint8_t + * + * @return uint8_t + */ + uint8_t SSD1306_DrawLineHorz (uint8_t, uint8_t, uint8_t); + + /** + * @desc Draw line vertical + * + * @param uint8_t + * @param uint8_t + * @param uint8_t + * + * @return uint8_t + */ + uint8_t SSD1306_DrawLineVert (uint8_t, uint8_t, uint8_t); + #endif From 8580ddc78c1619382708f4226804a40b1be5649c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n?= Date: Tue, 6 Dec 2022 08:49:05 +0100 Subject: [PATCH 09/11] Draw line horizontal from x1 to x2 --- lib/ssd1306.c | 76 ++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 43 deletions(-) diff --git a/lib/ssd1306.c b/lib/ssd1306.c index 846fab9..7531ad6 100644 --- a/lib/ssd1306.c +++ b/lib/ssd1306.c @@ -7,7 +7,7 @@ * * @author Marian Hrinko * @datum 06.10.2020 - * @update 24.11.2022 + * @update 06.12.2022 * @file ssd1306.c * @version 3.0 * @tested AVR Atmega328p @@ -20,7 +20,7 @@ * --------------------------------------------------------------------------------------+ * @usage Basic Setup for OLED Display */ - + // @includes #include "ssd1306.h" // +---------------------------+ @@ -597,22 +597,32 @@ uint8_t SSD1306_DrawPixel (uint8_t x, uint8_t y) uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) { uint8_t status = INIT_STATUS; // TWI init status 0xFF - uint8_t i = 0; // counter - uint8_t j = 0; // counter + uint8_t i = 0; // counter for y dim + uint8_t j = 0; // counter for x dim uint8_t page = y >> 3; // page - uint8_t pixel = 1 << (y - (page << 3)); // pixel + uint8_t pixel = 1 << (y - (page << 3)); // which pixel + uint8_t ram[RAM_Y_END][RAM_X_END]; // buffer [3/7 x 127] - uint8_t ram[RAM_Y_END][RAM_X_END]; - - while (i < RAM_Y_END) { - if (i == page) { - memset (ram[i], pixel, RAM_X_END); - } else { - memset (ram[i], 0x00, RAM_X_END); + // fill RAM buffer + // ------------------------------------------------------------------------------------- + while (i < RAM_Y_END) + { + if (i == page) { // for correspond page + //memset (ram[i], pixel, RAM_X_END); // draw line + while (j < x1) { // + ram[i][j++] = CLEAR_COLOR; // clear to x1 + } + while (j < x2) { // + ram[i][j++] = pixel; // set pixels to x2 + } + while (j < RAM_X_END) { // + ram[i][j++] = CLEAR_COLOR; // clear to x end + } + } else { // + memset (ram[i], CLEAR_COLOR, RAM_X_END); // clear whole page } - i++; + i++; // next page } - // TWI start & SLAW // ------------------------------------------------------------------------------------- status = SSD1306_Send_StartAndSLAW (SSD1306_ADDR); // start & SLAW @@ -626,16 +636,15 @@ uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) return status; // error } // start COLUMN - status = SSD1306_Send_Command (0); + status = SSD1306_Send_Command (START_COLUMN_ADDR); if (SSD1306_SUCCESS != status) { // check status return status; // error } // end COLUMN - status = SSD1306_Send_Command (127); + status = SSD1306_Send_Command (END_COLUMN_ADDR); if (SSD1306_SUCCESS != status) { // check status return status; // error } - // PAGE // ------------------------------------------------------------------------------------- status = SSD1306_Send_Command (SSD1306_SET_PAGE_ADDR); // 0x22 @@ -643,62 +652,43 @@ uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) return status; // error } // start PAGE - status = SSD1306_Send_Command (0); + status = SSD1306_Send_Command (START_PAGE_ADDR); if (SSD1306_SUCCESS != status) { // check status return status; // error } // end PAGE - status = SSD1306_Send_Command (3); + status = SSD1306_Send_Command (END_PAGE_ADDR); if (SSD1306_SUCCESS != status) { // check status return status; // error } - // TWI control byte data stream // ------------------------------------------------------------------------------------- status = TWI_MT_Send_Data (SSD1306_DATA_STREAM); // send data 0x40 if (SSD1306_SUCCESS != status) { // check status return status; // error } - - i = 0; - j = 0; // send pixels // ------------------------------------------------------------------------------------- + i = 0; + j = 0; while (i < RAM_Y_END) { while (j < RAM_X_END) { - status = TWI_MT_Send_Data (ram[i][j]); // send data col + status = TWI_MT_Send_Data (ram[i][j]); // send RAM buffer if (SSD1306_SUCCESS != status) { // check status return status; // error } j++; } - j = 0; - i++; + j = 0; // null x counter + i++; // next page } - // TWI stop // ------------------------------------------------------------------------------------- TWI_Stop (); - return SSD1306_SUCCESS; // success return } -/** - * @desc Draw line vertical - * - * @param uint8_t - * @param uint8_t - * @param uint8_t - * - * @return uint8_t - */ -uint8_t SSD1306_DrawLineVert (uint8_t x, uint8_t y1, uint8_t y2) -{ - - return SSD1306_SUCCESS; // success -} - /** * @desc Draw line by Bresenham algoritm * From a9e421d5ff439b5e17a004bdf2ffe340954e01ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n?= Date: Tue, 6 Dec 2022 10:07:01 +0100 Subject: [PATCH 10/11] Small code modification --- lib/ssd1306.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/lib/ssd1306.c b/lib/ssd1306.c index 7531ad6..d5b1d57 100644 --- a/lib/ssd1306.c +++ b/lib/ssd1306.c @@ -357,38 +357,30 @@ uint8_t SSD1306_SetPosition (uint8_t x, uint8_t y) if (SSD1306_SUCCESS != status) { // check status return status; // error } - // start COLUMN - status = SSD1306_Send_Command (x); + status = SSD1306_Send_Command (x); // start COLUMN if (SSD1306_SUCCESS != status) { // check status return status; // error } - // end COLUMN - status = SSD1306_Send_Command (END_COLUMN_ADDR); // 127 + status = SSD1306_Send_Command (END_COLUMN_ADDR); // end COLUMN if (SSD1306_SUCCESS != status) { // check status return status; // error } - // update column index - _indexCol = x; - + _indexCol = x; // update column index // PAGE // ------------------------------------------------------------------------------------- status = SSD1306_Send_Command (SSD1306_SET_PAGE_ADDR); // 0x22 if (SSD1306_SUCCESS != status) { // check status return status; // error } - // start PAGE - status = SSD1306_Send_Command (y); + status = SSD1306_Send_Command (y); // start PAGE if (SSD1306_SUCCESS != status) { // check status return status; // error } - // end PAGE - status = SSD1306_Send_Command (END_PAGE_ADDR); // 7 for 128x64 + status = SSD1306_Send_Command (END_PAGE_ADDR); // end PAGE if (SSD1306_SUCCESS != status) { // check status return status; // error } - // update column index - _indexPage = y; - + _indexPage = y; // update column index // TWI stop // ------------------------------------------------------------------------------------- TWI_Stop (); @@ -477,7 +469,6 @@ uint8_t SSD1306_DrawChar (char ch) if (SSD1306_SUCCESS != status) { // check status return status; // error } - _indexCol = _indexCol + CHARS_COLS_LENGTH + 1; // update global col // TWI stop @@ -547,7 +538,6 @@ uint8_t SSD1306_DrawPixel (uint8_t x, uint8_t y) if (SSD1306_SUCCESS != status) { // check status return status; // error } - // PAGE // ------------------------------------------------------------------------------------- status = SSD1306_Send_Command (SSD1306_SET_PAGE_ADDR); // 0x22 @@ -564,20 +554,18 @@ uint8_t SSD1306_DrawPixel (uint8_t x, uint8_t y) if (SSD1306_SUCCESS != status) { // check status return status; // error } - // TWI control byte data stream // ------------------------------------------------------------------------------------- status = TWI_MT_Send_Data (SSD1306_DATA); // send data 0xC0 if (SSD1306_SUCCESS != status) { // check status return status; // error } - // send clear byte to memory lcd + // PIXEL // ------------------------------------------------------------------------------------- status = TWI_MT_Send_Data (pixel); // send pixel if (SSD1306_SUCCESS != status) { // check status return status; // error } - // TWI stop // ------------------------------------------------------------------------------------- TWI_Stop (); @@ -667,7 +655,7 @@ uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) if (SSD1306_SUCCESS != status) { // check status return status; // error } - // send pixels + // PIXELS // ------------------------------------------------------------------------------------- i = 0; j = 0; @@ -677,7 +665,7 @@ uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) if (SSD1306_SUCCESS != status) { // check status return status; // error } - j++; + j++; // next column } j = 0; // null x counter i++; // next page From f1845d86acfe0ec9366fdd1b33ed4554ac0c1226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n?= Date: Wed, 7 Dec 2022 15:53:48 +0100 Subject: [PATCH 11/11] Small code modification --- lib/ssd1306.c | 87 ++++++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 39 deletions(-) diff --git a/lib/ssd1306.c b/lib/ssd1306.c index d5b1d57..b274dba 100644 --- a/lib/ssd1306.c +++ b/lib/ssd1306.c @@ -1,7 +1,7 @@ -/** - * --------------------------------------------------------------------------------------+ +/** + * --------------------------------------------------------------------------------------+ * @desc SSD1306 OLED Driver - * --------------------------------------------------------------------------------------+ + * --------------------------------------------------------------------------------------+ * Copyright (C) 2020 Marian Hrinko. * Written by Marian Hrinko (mato.hrinko@gmail.com) * @@ -13,11 +13,11 @@ * @tested AVR Atmega328p * * @depend font.h, twi.h - * --------------------------------------------------------------------------------------+ + * --------------------------------------------------------------------------------------+ * @descr Version 1.0 -> applicable for 1 display * Version 2.0 -> rebuild to 'cacheMemLcd' array * Version 3.0 -> remove 'cacheMemLcd' approach - * --------------------------------------------------------------------------------------+ + * --------------------------------------------------------------------------------------+ * @usage Basic Setup for OLED Display */ // @includes @@ -139,7 +139,7 @@ unsigned short int _indexPage = START_PAGE_ADDR; // @var global * @return uint8_t */ uint8_t SSD1306_Init (void) -{ +{ const uint8_t *commands = INIT_SSD1306; // variables uint8_t no_of_commands = pgm_read_byte(commands++); // number of commands uint8_t no_of_arguments; // number od arguments @@ -150,24 +150,24 @@ uint8_t SSD1306_Init (void) // ------------------------------------------------------------------------------------- TWI_Init (); - // TWI Start & SLAW + // TWI START & SLAW // ------------------------------------------------------------------------------------- status = SSD1306_Send_StartAndSLAW (SSD1306_ADDR); // start & SLAW if (SSD1306_SUCCESS != status) { // check status return status; // error } - // MAIN LOOP + // SEND COMMAND & ARGUMENTS // ------------------------------------------------------------------------------------- while (no_of_commands) { // commands loop no_of_arguments = pgm_read_byte (commands++); // number of arguments command = pgm_read_byte (commands++); // command - // SEND COMMAND + // Send commands // ----------------------------------------------------------------------------------- status = SSD1306_Send_Command (command); // send command if (SSD1306_SUCCESS != status) { // check status return status; // error } - // SEND ARGUMENTS + // Send arguments // ----------------------------------------------------------------------------------- while (no_of_arguments--) { status = SSD1306_Send_Command (pgm_read_byte(commands++)); // send argument @@ -175,7 +175,6 @@ uint8_t SSD1306_Init (void) return status; // error } } - no_of_commands--; // next command } // TWI STOP @@ -202,13 +201,13 @@ uint8_t SSD1306_Send_StartAndSLAW (uint8_t address) if (SSD1306_SUCCESS != status) { // check status return status; // error } - // TWI start & SLAW + // TWI SLAW // ------------------------------------------------------------------------------------- status = TWI_MT_Send_SLAW (address); // start & SLAW if (SSD1306_SUCCESS != status) { // check status return status; // error } - + return SSD1306_SUCCESS; // success } @@ -224,7 +223,7 @@ uint8_t SSD1306_Send_Command (uint8_t command) uint8_t status = INIT_STATUS; // TWI init status 0xFF // TWI send control byte - // ------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------------------- status = TWI_MT_Send_Data (SSD1306_COMMAND); // send control byte if (SSD1306_SUCCESS != status) { // check status return status; // error @@ -250,7 +249,7 @@ uint8_t SSD1306_NormalScreen (void) { uint8_t status = INIT_STATUS; // TWI init status 0xFF - // TWI start & SLAW + // TWI START & SLAW // ------------------------------------------------------------------------------------- status = SSD1306_Send_StartAndSLAW (SSD1306_ADDR); // start & SLAW if (SSD1306_SUCCESS != status) { // check status @@ -262,6 +261,9 @@ uint8_t SSD1306_NormalScreen (void) if (SSD1306_SUCCESS != status) { // check status return status; // error } + // TWI STOP + // ------------------------------------------------------------------------------------- + TWI_Stop (); return SSD1306_SUCCESS; // success } @@ -277,7 +279,7 @@ uint8_t SSD1306_InverseScreen (void) { uint8_t status = INIT_STATUS; // TWI init status 0xFF - // TWI start & SLAW + // TWI START & SLAW // ------------------------------------------------------------------------------------- status = SSD1306_Send_StartAndSLAW (SSD1306_ADDR); // start & SLAW if (SSD1306_SUCCESS != status) { // check status @@ -289,6 +291,9 @@ uint8_t SSD1306_InverseScreen (void) if (SSD1306_SUCCESS != status) { // check status return status; // error } + // TWI STOP + // ------------------------------------------------------------------------------------- + TWI_Stop (); return SSD1306_SUCCESS; // success } @@ -305,7 +310,7 @@ uint8_t SSD1306_ClearScreen (void) uint8_t status = INIT_STATUS; // TWI init status 0xFF uint16_t i = 0; // counter - // TWI start & SLAW + // TWI START & SLAW // ------------------------------------------------------------------------------------- status = SSD1306_Send_StartAndSLAW (SSD1306_ADDR); // start & SLAW if (SSD1306_SUCCESS != status) { // check status @@ -326,7 +331,7 @@ uint8_t SSD1306_ClearScreen (void) } i++; // update counter } - // TWI stop + // TWI STOP // ------------------------------------------------------------------------------------- TWI_Stop (); @@ -341,18 +346,18 @@ uint8_t SSD1306_ClearScreen (void) * * @return void */ -uint8_t SSD1306_SetPosition (uint8_t x, uint8_t y) +uint8_t SSD1306_SetPosition (uint8_t x, uint8_t y) { uint8_t status = INIT_STATUS; // TWI init status 0xFF - // TWI start & SLAW + // TWI START & SLAW // ------------------------------------------------------------------------------------- status = SSD1306_Send_StartAndSLAW (SSD1306_ADDR); // start & SLAW if (SSD1306_SUCCESS != status) { // check status return status; // error } // COLUMN - // ------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------------------- status = SSD1306_Send_Command (SSD1306_SET_COLUMN_ADDR); // 0x21 if (SSD1306_SUCCESS != status) { // check status return status; // error @@ -381,7 +386,8 @@ uint8_t SSD1306_SetPosition (uint8_t x, uint8_t y) return status; // error } _indexPage = y; // update column index - // TWI stop + + // TWI STOP // ------------------------------------------------------------------------------------- TWI_Stop (); @@ -396,7 +402,7 @@ uint8_t SSD1306_SetPosition (uint8_t x, uint8_t y) * * @return uint8_t */ -uint8_t SSD1306_UpdatePosition (void) +uint8_t SSD1306_UpdatePosition (void) { uint8_t status = INIT_STATUS; // TWI init status 0xFF uint8_t x = _indexCol + CHARS_COLS_LENGTH + 1; // check end col position @@ -417,10 +423,10 @@ uint8_t SSD1306_UpdatePosition (void) // last page reached // ----------------------------------------------------------------------------------- if (_indexPage >= END_PAGE_ADDR) { - return SSD1306_ERROR; // return out of range + return SSD1306_ERROR; // return out of range } } - + return SSD1306_SUCCESS; // success } @@ -442,7 +448,8 @@ uint8_t SSD1306_DrawChar (char ch) if (SSD1306_SUCCESS != status) { // check status return status; // error } - // TWI start & SLAW + + // TWI START & SLAW // ------------------------------------------------------------------------------------- status = SSD1306_Send_StartAndSLAW (SSD1306_ADDR); // start & SLAW if (SSD1306_SUCCESS != status) { // check status @@ -471,7 +478,7 @@ uint8_t SSD1306_DrawChar (char ch) } _indexCol = _indexCol + CHARS_COLS_LENGTH + 1; // update global col - // TWI stop + // TWI STOP // ------------------------------------------------------------------------------------- TWI_Stop (); @@ -490,7 +497,7 @@ uint8_t SSD1306_DrawString (char *str) uint8_t i = 0; // char counter // send characters of string - // ------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------------------- while (str[i] != '\0') { SSD1306_DrawChar (str[i++]); // send char } @@ -511,12 +518,12 @@ uint8_t SSD1306_DrawPixel (uint8_t x, uint8_t y) uint8_t page = y >> 3; // find page (y / 8) uint8_t pixel = 1 << (y - (page << 3)); // which pixel (y % 8) uint8_t status = INIT_STATUS; // TWI init status 0xFF - + if ((x > MAX_X) || (y > MAX_Y)) { // if out of range return SSD1306_ERROR; // error } - // TWI start & SLAW + // TWI START & SLAW // ------------------------------------------------------------------------------------- status = SSD1306_Send_StartAndSLAW (SSD1306_ADDR); // start & SLAW if (SSD1306_SUCCESS != status) { // check status @@ -566,7 +573,8 @@ uint8_t SSD1306_DrawPixel (uint8_t x, uint8_t y) if (SSD1306_SUCCESS != status) { // check status return status; // error } - // TWI stop + + // TWI STOP // ------------------------------------------------------------------------------------- TWI_Stop (); @@ -588,12 +596,12 @@ uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) uint8_t i = 0; // counter for y dim uint8_t j = 0; // counter for x dim uint8_t page = y >> 3; // page - uint8_t pixel = 1 << (y - (page << 3)); // which pixel + uint8_t pixel = 1 << (y - (page << 3)); // which pixel uint8_t ram[RAM_Y_END][RAM_X_END]; // buffer [3/7 x 127] // fill RAM buffer - // ------------------------------------------------------------------------------------- - while (i < RAM_Y_END) + // ------------------------------------------------------------------------------------- + while (i < RAM_Y_END) { if (i == page) { // for correspond page //memset (ram[i], pixel, RAM_X_END); // draw line @@ -611,7 +619,7 @@ uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) } i++; // next page } - // TWI start & SLAW + // TWI START & SLAW // ------------------------------------------------------------------------------------- status = SSD1306_Send_StartAndSLAW (SSD1306_ADDR); // start & SLAW if (SSD1306_SUCCESS != status) { // check status @@ -670,7 +678,8 @@ uint8_t SSD1306_DrawLineHorz (uint8_t y, uint8_t x1, uint8_t x2) j = 0; // null x counter i++; // next page } - // TWI stop + + // TWI STOP // ------------------------------------------------------------------------------------- TWI_Stop (); @@ -695,7 +704,7 @@ uint8_t SSD1306_DrawLine (uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2) int16_t delta_x, delta_y; // deltas int16_t trace_x = 1, trace_y = 1; // steps - if ((x1 > MAX_X) || (y1 > MAX_Y) || + if ((x1 > MAX_X) || (y1 > MAX_Y) || (x2 > MAX_X) || (y2 > MAX_Y) ) { // out of range? return SSD1306_ERROR; // error } @@ -714,8 +723,8 @@ uint8_t SSD1306_DrawLine (uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2) if (SSD1306_SUCCESS != status) { // check status return status; // error } - return SSD1306_SUCCESS; // success return - } + return SSD1306_SUCCESS; // success return + } // condition for m < 1 (dy < dx) // -------------------------------------------------------------------------------------