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] 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) { //