diff --git a/lib/ssd1306.c b/lib/ssd1306.c index 2cf4f9d..96b81c9 100644 --- a/lib/ssd1306.c +++ b/lib/ssd1306.c @@ -7,16 +7,16 @@ * * @author Marian Hrinko * @date 06.10.2020 - * @update 15.12.2022 + * @update 06.12.2022 * @file ssd1306.c - * @version 3.0.0 + * @version 3.0 * @tested AVR Atmega328p * - * @depend ssd1306.h + * @depend font.h, twi.h * --------------------------------------------------------------------------------------+ - * @descr Version 1.0.0 -> applicable for 1 display - * Version 2.0.0 -> rebuild to 'cacheMemLcd' array - * Version 3.0.0 -> simplified alphanumeric version for 1 display + * @descr Version 1.0 -> applicable for 1 display + * Version 2.0 -> rebuild to 'cacheMemLcd' array + * Version 3.0 -> simplified alphanumeric version * --------------------------------------------------------------------------------------+ * @usage Basic Setup for OLED Display */ @@ -24,109 +24,34 @@ // @includes #include "ssd1306.h" -// +---------------------------+ -// | Set MUX Ratio | -// +---------------------------+ -// | 0xA8, 0x3F | -// +---------------------------+ -// | -// +---------------------------+ -// | Set Display Offset | -// +---------------------------+ -// | 0xD3, 0x00 | -// +---------------------------+ -// | -// +---------------------------+ -// | Set Display Start Line | -// +---------------------------+ -// | 0x40 | -// +---------------------------+ -// | -// +---------------------------+ -// | Set Segment Remap | -// +---------------------------+ -// | 0xA0 / 0xA1 | -// +---------------------------+ -// | -// +---------------------------+ -// | Set COM Output Scan | -// | Direction | -// +---------------------------+ -// | 0xC0 / 0xC8 | -// +---------------------------+ -// | -// +---------------------------+ -// | Set COM Pins hardware | -// | configuration | -// +---------------------------+ -// | 0xDA, 0x02 | -// +---------------------------+ -// | -// +---------------------------+ -// | Set Contrast Control | -// +---------------------------+ -// | 0x81, 0x7F | -// +---------------------------+ -// | -// +---------------------------+ -// | Disable Entire Display On | -// +---------------------------+ -// | 0xA4 | -// +---------------------------+ -// | -// +---------------------------+ -// | Set Normal Display | -// +---------------------------+ -// | 0xA6 | -// +---------------------------+ -// | -// +---------------------------+ -// | Set Osc Frequency | -// +---------------------------+ -// | 0xD5, 0x80 | -// +---------------------------+ -// | -// +---------------------------+ -// | Enable charge pump | -// | regulator | -// +---------------------------+ -// | 0x8D, 0x14 | -// +---------------------------+ -// | -// +---------------------------+ -// | Display On | -// +---------------------------+ -// | 0xAF | -// +---------------------------+ - -// @array Init command +// @const uint8_t - List of init commands according to datasheet SSD1306 const uint8_t INIT_SSD1306[] PROGMEM = { - 18, // number of initializers - 0, SSD1306_DISPLAY_OFF, // 0xAE = Set Display OFF - 1, SSD1306_SET_MUX_RATIO, 63, // 0xA8 - 64MUX for 128 x 64 version - // - 32MUX for 128 x 32 version - 1, SSD1306_MEMORY_ADDR_MODE, 0x00, // 0x20 = Set Memory Addressing Mode + 17, // number of initializers + //SSD1306_RESET, 0, // 0xE4 = Software Reset? + SSD1306_DISPLAY_OFF, 0, // 0xAE = Set Display OFF + SSD1306_SET_MUX_RATIO, 1, 0x3F, // 0xA8 - 0x3F for 128 x 64 version (64MUX) + // - 0x1F for 128 x 32 version (32MUX) + SSD1306_MEMORY_ADDR_MODE, 1, 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_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 / remap 0xC8 - 1, SSD1306_COM_PIN_CONF, 0x12, // 0xDA, 0x12 - Disable COM Left/Right remap, Alternative COM pin configuration + SSD1306_SET_START_LINE, 0, // 0x40 + SSD1306_DISPLAY_OFFSET, 1, 0x00, // 0xD3 + SSD1306_SEG_REMAP_OP, 0, // 0xA0 / remap 0xA1 + SSD1306_COM_SCAN_DIR_OP, 0, // 0xC0 / remap 0xC8 + SSD1306_COM_PIN_CONF, 1, 0x12, // 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 - 1, SSD1306_SET_OSC_FREQ, 0x80, // 0xD5, 0x80 => D=1; DCLK = Fosc / D <=> DCLK = Fosc - 1, SSD1306_SET_PRECHARGE, 0xc2, // 0xD9, higher value less blinking + SSD1306_SET_CONTRAST, 1, 0x7F, // 0x81, 0x7F - reset value (max 0xFF) + SSD1306_DIS_ENT_DISP_ON, 0, // 0xA4 + SSD1306_DIS_NORMAL, 0, // 0xA6 + SSD1306_SET_OSC_FREQ, 1, 0x80, // 0xD5, 0x80 => D=1; DCLK = Fosc / D <=> DCLK = Fosc + SSD1306_SET_PRECHARGE, 1, 0xc2, // 0xD9, higher value less blinking // 0xC2, 1st phase = 2 DCLK, 2nd phase = 13 DCLK - 1, SSD1306_VCOM_DESELECT, 0x20, // Set V COMH Deselect, reset value 0x22 = 0,77xUcc - 1, SSD1306_SET_CHAR_REG, 0x14, // 0x8D, Enable charge pump during display on - 0, SSD1306_DISPLAY_ON // 0xAF = Set Display ON + SSD1306_VCOM_DESELECT, 1, 0x20, // Set V COMH Deselect, reset value 0x22 = 0,77xUcc + SSD1306_SET_CHAR_REG, 1, 0x14, // 0x8D, Enable charge pump during display on + SSD1306_DEACT_SCROLL, 0, // 0x2E + SSD1306_DISPLAY_ON, 0 // 0xAF = Set Display ON }; unsigned short int _indexCol = START_COLUMN_ADDR; // @var global - cache index column @@ -189,50 +114,56 @@ uint8_t SSD1306_Send_Command (uint8_t command) /** * @desc SSD1306 Init * - * @param void + * @param uint8_t address * * @return uint8_t */ -uint8_t SSD1306_Init (void) +uint8_t SSD1306_Init (uint8_t address) { - 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 + const uint8_t * list = INIT_SSD1306; + uint8_t status = INIT_STATUS; // init status + uint8_t arguments; + uint8_t commands = pgm_read_byte (list++); - // TWI INIT + // TWI: Init // ------------------------------------------------------------------------------------- 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 + status = SSD1306_Send_StartAndSLAW (address); + if (SSD1306_SUCCESS != status) { + return status; } - // SEND COMMAND & ARGUMENTS + + // SW RESET + // ----------------------------------------------------------------------------------- + status = SSD1306_Send_Command (SSD1306_RESET); + if (SSD1306_SUCCESS != status) { + return status; + } + _delay_ms (1); + + // Commands & Arguments // ------------------------------------------------------------------------------------- - while (no_of_commands) { // commands loop - no_of_arguments = pgm_read_byte (commands++); // number of arguments - command = pgm_read_byte (commands++); // command - // Send commands + while (commands--) { + // Command // ----------------------------------------------------------------------------------- - status = SSD1306_Send_Command (command); // send command - if (SSD1306_SUCCESS != status) { // check status - return status; // error + status = SSD1306_Send_Command (pgm_read_byte(list++)); + if (SSD1306_SUCCESS != status) { + return status; } - // Send arguments + // Arguments // ----------------------------------------------------------------------------------- - while (no_of_arguments--) { - status = SSD1306_Send_Command (pgm_read_byte(commands++)); // send argument - if (SSD1306_SUCCESS != status) { // check status - return status; // error + arguments = pgm_read_byte (list++); + while (arguments--) { + status = SSD1306_Send_Command (pgm_read_byte(list++)); // argument + if (SSD1306_SUCCESS != status) { + return status; } } - no_of_commands--; // next command } - // TWI STOP + // TWI: Stop // ------------------------------------------------------------------------------------- TWI_Stop (); @@ -309,8 +240,7 @@ uint8_t SSD1306_InverseScreen (void) uint8_t SSD1306_ClearScreen (void) { uint8_t status = INIT_STATUS; // TWI init status 0xFF - uint16_t i = 0; // counter - + // TWI START & SLAW // ------------------------------------------------------------------------------------- status = SSD1306_Send_StartAndSLAW (SSD1306_ADDR); // start & SLAW @@ -353,6 +283,68 @@ uint8_t SSD1306_ClearScreen (void) if (SSD1306_SUCCESS != status) { // check status return status; // error } + // send clear byte to memory lcd + // ------------------------------------------------------------------------------------- + for (uint16_t i=0; i END_COLUMN_ADDRESS} + * @param uint8_t y {0 -> END_PAGE_ADDR} + * @param uint8_t height + * + * @return uint8_t + */ +uint8_t SSD1306_DrawLineVertical (uint8_t x, uint8_t y, uint8_t height) +{ + uint8_t i = 0; + uint8_t status = INIT_STATUS; // TWI init status 0xFF + + if ((y + height) > END_PAGE_ADDR) { + return SSD1306_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 + } + status = SSD1306_Send_Command (x); // start COLUMN + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + status = SSD1306_Send_Command (x); // end COLUMN + 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 + } + status = SSD1306_Send_Command (y); // start PAGE + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + status = SSD1306_Send_Command (y + height); // end 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 + } + while (i++ <= height) { + status = TWI_MT_Send_Data (0xff); // send data col + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + } + + // TWI STOP + // ------------------------------------------------------------------------------------- + TWI_Stop (); + + return SSD1306_SUCCESS; // success +} + +/** + * @brief SSD1306 Draw rectangle + * + * @param uint8_t x {0 -> END_COLUMN_ADDRESS} + * @param uint8_t y {0 -> END_PAGE_ADDR} + * @param uint8_t width + * @param uint8_t height + * + * @return uint8_t + */ +uint8_t SSD1306_DrawRectangle (uint8_t x, uint8_t y, uint8_t width, uint8_t height) +{ + uint16_t i = 0; + uint8_t status = INIT_STATUS; // TWI init status 0xFF + uint16_t loops; + + if (((x + width) > END_COLUMN_ADDR) || + ((y + height) > END_PAGE_ADDR)) { + return SSD1306_ERROR; + } + + loops = (x + width) * (y + height); // num of loops + + // 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 + } + status = SSD1306_Send_Command (x); // start COLUMN + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + status = SSD1306_Send_Command (x + width); // end COLUMN + 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 + } + status = SSD1306_Send_Command (y); // start PAGE + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + status = SSD1306_Send_Command (y + height); // end 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 + } + while (i++ <= loops) { + status = TWI_MT_Send_Data (0xff); // send data col + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + } + + // TWI STOP + // ------------------------------------------------------------------------------------- + TWI_Stop (); + + return SSD1306_SUCCESS; // success +} + +/** + * @brief SSD1306 Draw line horizontal + * + * @param uint8_t x {0 -> END_COLUMN_ADDRESS} + * @param uint8_t y {0 -> END_PAGE_ADDR} + * @param uint8_t width {(x + width) <= END_COLUMN_ADDRESS} + * @param enum E_line {TOP, TOPDOUBLE, ... BOTTOM, BOTTOMDOUBLE} see enum E_Line + * + * @return uint8_t + */ +uint8_t SSD1306_DrawLineHorizontal (uint8_t x, uint8_t y, uint8_t width, enum E_Line line) +{ + uint8_t status = INIT_STATUS; // TWI init status 0xFF + uint8_t i = 0; // counter + + if ((x + width) > END_COLUMN_ADDR) { + return SSD1306_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 + } + status = SSD1306_Send_Command (x); // start COLUMN + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + status = SSD1306_Send_Command (x + width); // end COLUMN + 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 + } + status = SSD1306_Send_Command (y); // start PAGE + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + status = SSD1306_Send_Command (y ); // end 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 + } + + while (i++ < width) { + status = TWI_MT_Send_Data (line); // send data col + if (SSD1306_SUCCESS != status) { // check status + return status; // error + } + _indexCol++; // update global col + } + + // TWI STOP + // ------------------------------------------------------------------------------------- + TWI_Stop (); + + return SSD1306_SUCCESS; // success +} + +/** + * @brief SSD1306 Horizontal Scroll + * + * @param uint8_t address + * @param uint8_t start page + * @param uint8_t end page + * + * @return uint8_t + */ +uint8_t SSD1306_HorizontalScroll (uint8_t address, uint8_t start, uint8_t end) +{ + uint8_t status = INIT_STATUS; + + // TWI: start & SLAW + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_StartAndSLAW (address); + if (SSD1306_SUCCESS != status) { + return status; + } + // send command + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_Command (SSD1306_SCROLL_HOR_LEFT); + if (SSD1306_SUCCESS != status) { + return status; + } + // dummy BYTE + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_Command (0x00); + if (SSD1306_SUCCESS != status) { + return status; + } + // Start PAGE + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_Command (start); + if (SSD1306_SUCCESS != status) { + return status; + } + // Speed + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_Command (0x00); + if (SSD1306_SUCCESS != status) { + return status; + } + // End PAGE + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_Command (end); + if (SSD1306_SUCCESS != status) { + return status; + } + // dummy BYTE + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_Command (0x00); + if (SSD1306_SUCCESS != status) { + return status; + } + // dummy BYTE + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_Command (0xFF); + if (SSD1306_SUCCESS != status) { + return status; + } + // Start Scroll + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_Command (SSD1306_ACTIVE_SCROLL); + if (SSD1306_SUCCESS != status) { + return status; + } + // TWI: Stop + // ------------------------------------------------------------------------------------- + TWI_Stop (); + + return SSD1306_SUCCESS; +} + +/** + * @brief SSD1306 Horizontal Scroll Stop + * + * @param uint8_t address + * + * @return uint8_t + */ +uint8_t SSD1306_HorizontalScrollStop (uint8_t address) +{ + uint8_t status = INIT_STATUS; + + // TWI: start & SLAW + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_StartAndSLAW (address); + if (SSD1306_SUCCESS != status) { + return status; + } + // Stop Scroll + // ------------------------------------------------------------------------------------- + status = SSD1306_Send_Command (SSD1306_DEACT_SCROLL); + if (SSD1306_SUCCESS != status) { + return status; + } + // TWI: Stop + // ------------------------------------------------------------------------------------- + TWI_Stop (); + + return SSD1306_SUCCESS; +} \ No newline at end of file diff --git a/lib/ssd1306.h b/lib/ssd1306.h index ba62d56..6b193b1 100644 --- a/lib/ssd1306.h +++ b/lib/ssd1306.h @@ -1,22 +1,22 @@ /** * -------------------------------------------------------------------------------------+ - * @desc SSD1306 OLED Driver + * @brief SSD1306 OLED Driver * -------------------------------------------------------------------------------------+ * Copyright (C) 2020 Marian Hrinko. * Written by Marian Hrinko (mato.hrinko@gmail.com) * * @author Marian Hrinko * @date 06.10.2020 - * @update 15.12.2022 + * @update 21.11.2022 * @file ssd1306.h - * @version 3.0.0 + * @version 3.0 * @tested AVR Atmega328p * * @depend font.h, twi.h * -------------------------------------------------------------------------------------+ - * @descr Version 1.0.0 -> applicable for 1 display - * Version 2.0.0 -> rebuild to 'cacheMemLcd' array - * Version 3.0.0 -> simplified alphanumeric version for 1 display + * @descr Version 1.0 -> applicable for 1 display + * Version 2.0 -> rebuild to 'cacheMemLcd' array + * Version 3.0 -> simplified alphanumeric version * -------------------------------------------------------------------------------------+ * @usage Basic Setup for OLED Display */ @@ -25,6 +25,7 @@ #define __SSD1306_H__ // includes + #include #include "font.h" #include "twi.h" @@ -44,30 +45,45 @@ #define SSD1306_DATA 0xC0 // Continuation bit=1, D/C=1; 1100 0000 #define SSD1306_DATA_STREAM 0x40 // Continuation bit=0, D/C=1; 0100 0000 - #define SSD1306_SET_MUX_RATIO 0xA8 - #define SSD1306_DISPLAY_OFFSET 0xD3 - #define SSD1306_DISPLAY_ON 0xAF - #define SSD1306_DISPLAY_OFF 0xAE - #define SSD1306_DIS_ENT_DISP_ON 0xA4 - #define SSD1306_DIS_IGNORE_RAM 0xA5 - #define SSD1306_DIS_NORMAL 0xA6 - #define SSD1306_DIS_INVERSE 0xA7 - #define SSD1306_DEACT_SCROLL 0x2E - #define SSD1306_ACTIVE_SCROLL 0x2F - #define SSD1306_SET_START_LINE 0x40 - #define SSD1306_MEMORY_ADDR_MODE 0x20 - #define SSD1306_SET_COLUMN_ADDR 0x21 - #define SSD1306_SET_PAGE_ADDR 0x22 - #define SSD1306_SEG_REMAP 0xA0 - #define SSD1306_SEG_REMAP_OP 0xA1 - #define SSD1306_COM_SCAN_DIR 0xC0 - #define SSD1306_COM_SCAN_DIR_OP 0xC8 - #define SSD1306_COM_PIN_CONF 0xDA - #define SSD1306_SET_CONTRAST 0x81 - #define SSD1306_SET_OSC_FREQ 0xD5 - #define SSD1306_SET_CHAR_REG 0x8D - #define SSD1306_SET_PRECHARGE 0xD9 - #define SSD1306_VCOM_DESELECT 0xDB + #define SSD1306_SET_MUX_RATIO 0xA8 // Set MUX ratio to N+1 MUX, N=A[5:0] : from 16MUX to 64MUX + #define SSD1306_DISPLAY_OFFSET 0xD3 // Set Display Offset + #define SSD1306_DISPLAY_ON 0xAF // Display ON in normal mode + #define SSD1306_DISPLAY_OFF 0xAE // Display OFF (sleep mode) + #define SSD1306_DIS_ENT_DISP_ON 0xA4 // Entire Display ON, Output ignores RAM content + #define SSD1306_DIS_IGNORE_RAM 0xA5 // Resume to RAM content display, Output follows RAM content + #define SSD1306_DIS_NORMAL 0xA6 // Normal display, 0 in RAM: OFF in display panel, 1 in RAM: ON in display panel + #define SSD1306_DIS_INVERSE 0xA7 // Inverse display, 0 in RAM: ON in display panel, 1 in RAM: OFF in display panel + #define SSD1306_DEACT_SCROLL 0x2E // Stop scrolling that is configured by command 26h/27h/29h/2Ah + #define SSD1306_ACTIVE_SCROLL 0x2F // Start scrolling that is configured by the scrolling setup commands:26h/27h/29h/2Ah + #define SSD1306_SCROLL_HOR_RIGHT 0x26 // Horizontal Right Horizontal Scroll + #define SSD1306_SCROLL_HOR_LEFT 0x27 // Horizontal Left Horizontal Scroll + #define SSD1306_SET_START_LINE 0x40 // Set Display Start Line + #define SSD1306_MEMORY_ADDR_MODE 0x20 // Set Memory, Addressing Mode + #define SSD1306_SET_COLUMN_ADDR 0x21 // Set Column Address + #define SSD1306_SET_PAGE_ADDR 0x22 // Set Page Address + #define SSD1306_SEG_REMAP 0xA0 // Set Segment Re-map, X[0]=0b column address 0 is mapped to SEG0 + #define SSD1306_SEG_REMAP_OP 0xA1 // Set Segment Re-map, X[0]=1b: column address 127 is mapped to SEG0 + #define SSD1306_COM_SCAN_DIR 0xC0 // Set COM Output, X[3]=0b: normal mode (RESET) Scan from COM0 to COM[N –1], e N is the Multiplex ratio + #define SSD1306_COM_SCAN_DIR_OP 0xC8 // Set COM Output, X[3]=1b: remapped mode. Scan from COM[N-1] to COM0, e N is the Multiplex ratio + #define SSD1306_COM_PIN_CONF 0xDA // Set COM Pins Hardware Configuration, + // A[4]=0b, Sequential COM pin configuration, A[4]=1b(RESET), Alternative COM pin configuration + // A[5]=0b(RESET), Disable COM Left/Right remap, A[5]=1b, Enable COM Left/Right remap + #define SSD1306_SET_CONTRAST 0x81 // Set Contrast Control, Double byte command to select 1 to 256 contrast steps, increases as the value increases + #define SSD1306_SET_OSC_FREQ 0xD5 // Set Display Clock Divide Ratio/Oscillator Frequency + // A[3:0] : Define the divide ratio (D) of the display clocks (DCLK): Divide ratio= A[3:0] + 1, RESET is 0000b (divide ratio = 1) + // A[7:4] : Set the Oscillator Frequency, FOSC. Oscillator Frequency increases with the value of A[7:4] and vice versa. RESET is 1000b + #define SSD1306_SET_CHAR_REG 0x8D // Charge Pump Setting, A[2] = 0b, Disable charge pump(RESET), A[2] = 1b, Enable charge pump during display on + // The Charge Pump must be enabled by the following command: + // 8Dh ; Charge Pump Setting + // 14h ; Enable Charge Pump + // AFh; Display ON + #define SSD1306_SET_PRECHARGE 0xD9 // Set Pre-charge Period + #define SSD1306_VCOM_DESELECT 0xDB // Set VCOMH Deselect Level + #define SSD1306_NOP 0xE3 // No operation + #define SSD1306_RESET 0xE4 // Maybe SW RESET, @source https://github.com/SmingHub/Sming/issues/501 + + #define SSD1306_VERTICAL_MODE 0x01 + #define SSD1306_HORIZONTAL_MODE 0x00 // Clear Color // ------------------------------------------------------------------------------------ @@ -98,8 +114,18 @@ UNDERLINE = 0x10 }; + // @enum + enum E_Line { + TOP = 0x01, + TOPDOUBLE = 0x03, + MIDDLE = 0x01, + MIDDLEDOUBLE = 0x18, + BOTTOM = 0x80, + BOTTOMDOUBLE = 0xC0 + }; + /** - * @desc SSD1306 Send Start and SLAW request + * @brief SSD1306 Send Start and SLAW request * * @param uint8_t * @@ -108,7 +134,7 @@ uint8_t SSD1306_Send_StartAndSLAW (uint8_t); /** - * @desc SSD1306 Send command + * @brief SSD1306 Send command * * @param uint8_t * @@ -117,16 +143,16 @@ uint8_t SSD1306_Send_Command (uint8_t); /** - * @desc SSD1306 Init + * @brief SSD1306 Init * - * @param void + * @param uint8_t address * * @return uint8_t */ - uint8_t SSD1306_Init (void); + uint8_t SSD1306_Init (uint8_t); /** - * @desc SSD1306 Clear screen + * @brief SSD1306 Clear screen * * @param void * @@ -135,7 +161,26 @@ uint8_t SSD1306_ClearScreen (void); /** - * @desc SSD1306 Normal colors + * @desc SSD1306 Clear Page + * + * @param uint8_t page + * + * @return uint8_t + */ + uint8_t SSD1306_ClearPage (uint8_t); + + /** + * @desc SSD1306 Clear screen + * + * @param uint8_t page + * @param uint8_t margin + * + * @return uint8_t + */ + uint8_t SSD1306_ClearPageFromToEnd (uint8_t, uint8_t); + + /** + * @brief SSD1306 Normal colors * * @param void * @@ -144,7 +189,7 @@ uint8_t SSD1306_NormalScreen (void); /** - * @desc SSD1306 Inverse colors + * @brief SSD1306 Inverse colors * * @param void * @@ -153,7 +198,7 @@ uint8_t SSD1306_InverseScreen (void); /** - * @desc SSD1306 Update text position + * @brief SSD1306 Update text position * * @param void * @@ -162,7 +207,7 @@ uint8_t SSD1306_UpdatePosition (uint8_t, uint8_t); /** - * @desc SSD1306 Set position + * @brief SSD1306 Set position * * @param uint8_t * @param uint8_t @@ -172,7 +217,7 @@ uint8_t SSD1306_SetPosition (uint8_t, uint8_t); /** - * @desc SSD1306 Set window + * @brief SSD1306 Set window * * @param uint8_t column -> 0 ... 127 * @param uint8_t column -> 0 ... 127 @@ -184,7 +229,7 @@ uint8_t SSD1306_SetWindow (uint8_t, uint8_t, uint8_t, uint8_t); /** - * @desc SSD1306 Draw character + * @brief SSD1306 Draw character * * @param char * @param enum E_Font @@ -194,7 +239,7 @@ uint8_t SSD1306_DrawChar (char, enum E_Font); /** - * @desc SSD1306 Draw string + * @brief SSD1306 Draw string * * @param char * * @@ -202,4 +247,69 @@ */ uint8_t SSD1306_DrawString (char *, enum E_Font); -#endif + /** + * @desc SSD1306 Draw String + * + * @param char * string + * @param E_Font + * + * @return uint8_t + */ + uint8_t SSD1306_DrawSongName (char *, enum E_Font); + + /** + * @brief SSD1306 Draw line horizontal + * + * @param uint8_t x + * @param uint8_t y + * @param uint8_t width + * @param enum E_line {TOP, TOPDOUBLE, ... BOTTOM, BOTTOMDOUBLE} see enum E_Line + * + * @return uint8_t + */ + uint8_t SSD1306_DrawLineHorizontal (uint8_t, uint8_t, uint8_t, enum E_Line); + + /** + * @brief SSD1306 Draw line vertical + * + * @param uint8_t x {0 -> END_COLUMN_ADDRESS} + * @param uint8_t y {0 -> END_PAGE_ADDR} + * @param uint8_t height + * + * @return uint8_t + */ + uint8_t SSD1306_DrawLineVertical (uint8_t, uint8_t, uint8_t); + + /** + * @brief SSD1306 Draw rectangle + * + * @param uint8_t x {0 -> END_COLUMN_ADDRESS} + * @param uint8_t y {0 -> END_PAGE_ADDR} + * @param uint8_t width + * @param uint8_t height + * + * @return uint8_t + */ + uint8_t SSD1306_DrawRectangle (uint8_t, uint8_t, uint8_t, uint8_t); + + /** + * @brief SSD1306 Horizontal Scroll Start + * + * @param uint8_t address + * @param uint8_t start page + * @param uint8_t end page + * + * @return uint8_t + */ + uint8_t SSD1306_HorizontalScroll (uint8_t, uint8_t, uint8_t); + + /** + * @brief SSD1306 Horizontal Scroll Stop + * + * @param uint8_t + * + * @return uint8_t + */ + uint8_t SSD1306_HorizontalScrollStop (uint8_t); + +#endif \ No newline at end of file diff --git a/main.c b/main.c index 2814074..d16148b 100644 --- a/main.c +++ b/main.c @@ -32,16 +32,22 @@ */ int main(void) { - SSD1306_Init (); + SSD1306_Init (SSD1306_ADDR); SSD1306_ClearScreen (); - SSD1306_SetPosition (25, 0) ; + SSD1306_DrawLineHorizontal (0, 0, END_COLUMN_ADDR, 0x03); + SSD1306_DrawLineHorizontal (0, 2, END_COLUMN_ADDR, 0x18); + SSD1306_DrawLineHorizontal (0, END_PAGE_ADDR, END_COLUMN_ADDR, 0x80); + SSD1306_DrawLineVertical (0, 0, END_PAGE_ADDR); + SSD1306_DrawLineVertical (END_COLUMN_ADDR, 0, END_PAGE_ADDR); + + SSD1306_SetPosition (25, 1) ; SSD1306_DrawString ("SSD1306", BOLD); - SSD1306_SetPosition (4, 2) ; + SSD1306_SetPosition (4, 3) ; SSD1306_DrawString ("by ", NORMAL); SSD1306_DrawString ("MATIASUS", NORMAL | UNDERLINE); - SSD1306_DrawString (" (C) 2022", NORMAL); + SSD1306_DrawString (" (C) 2024", NORMAL); // return value return 0;