From 3444217ae658c890819f4b703d652f2112c1c899 Mon Sep 17 00:00:00 2001 From: Matiasus Date: Tue, 19 Dec 2023 22:42:11 +0100 Subject: [PATCH] Add Adafuit Init Command List for testing purpose 0.91 / 128x32 oled --- Makefile | 29 ++-- lib/ssd1306.c | 452 +++++++++++++++++--------------------------------- lib/ssd1306.h | 2 +- main.c | 56 +++---- 4 files changed, 196 insertions(+), 343 deletions(-) diff --git a/Makefile b/Makefile index 9a5c223..900b237 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ # ------------------------------------------------------------------ # # Final file -TARGET = main +TARGET = main # # Library directory LIBDIR = lib @@ -22,7 +22,7 @@ LIBDIR = lib DEVICE = atmega328p # # Frequency -FCPU = 8000000 +FCPU = 16000000 # # Optimization OPTIMIZE = Os @@ -53,7 +53,7 @@ AVRSIZE = avr-size SFLAGS = --mcu=$(DEVICE) --format=avr # # Target and dependencies .c -SOURCES := $(wildcard *.c $(LIBDIR)/*.c) +SOURCES := $(wildcard *.c $(LIBDIR)/*.c $(LIBDIR)/*/*.c) # # Target and dependencies .o OBJECTS = $(SOURCES:.c=.o) @@ -75,7 +75,7 @@ AVRDUDE_PORT = /dev/ttyUSB0 AVRDUDE_PROG = usbasp # # AVRDUDE BAUD RATE -AVRDUDE_BAUD = 57600 +AVRDUDE_BAUD = 19200 # # AVRDUDE BAUD RATE AVROBJ_FORMAT = ihex @@ -91,8 +91,8 @@ main: $(TARGET).hex # Create hex file $(TARGET).hex: $(TARGET).elf $(OBJCOPY) $(OBJFLAGS) $(TARGET).elf $(TARGET).hex + @echo "-----------------------------------------------------------------------" $(AVRSIZE) $(TARGET).elf - # # Create .elf file $(TARGET).elf:$(OBJECTS) @@ -105,17 +105,24 @@ $(TARGET).elf:$(OBJECTS) # # Program avr - send file to programmer -flash: +flash: + @echo "-----------------------------------------------------------------------" $(AVRDUDE) $(AVRDUDE_FLAGS) flash:w:$(TARGET).hex:i +# +# Size +size: + @echo "-----------------------------------------------------------------------" + $(AVRSIZE) -C --mcu=$(DEVICE) $(TARGET).elf + # # Clean -clean: +clean: + @echo "-----------------------------------------------------------------------" rm -f $(OBJECTS) $(TARGET).elf $(TARGET).map # # Cleanall -cleanall: - rm -f $(OBJECTS) $(TARGET).hex $(TARGET).elf $(TARGET).map - - +cleanall: + @echo "-----------------------------------------------------------------------" + rm -f $(OBJECTS) $(TARGET).hex $(TARGET).elf $(TARGET).map \ No newline at end of file diff --git a/lib/ssd1306.c b/lib/ssd1306.c index 84b9b02..8221a7f 100644 --- a/lib/ssd1306.c +++ b/lib/ssd1306.c @@ -1,6 +1,6 @@ /** * --------------------------------------------------------------------------------------+ - * @desc SSD1306 OLED Driver + * @brief SSD1306 OLED Driver * --------------------------------------------------------------------------------------+ * Copyright (C) 2020 Marian Hrinko. * Written by Marian Hrinko (mato.hrinko@gmail.com) @@ -24,116 +24,76 @@ // @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 | -// +---------------------------+ +// @const List of init commands with arguments by Adafruit +// @link https://github.com/adafruit/Adafruit_SSD1306 +const uint8_t INIT_SSD1306_ADAFRUIT[] PROGMEM = { + 17, // number of initializers + SSD1306_DISPLAY_OFF, 0, // 0xAE / Set Display OFF + SSD1306_SET_OSC_FREQ, 1, 0x80, // 0xD5 / 0x80 => D=1; DCLK = Fosc / D <=> DCLK = Fosc + SSD1306_SET_MUX_RATIO, 1, 0x1F, // 0xA8 / 0x3F (64MUX) for 128 x 64 version + // / 0x1F (32MUX) for 128 x 32 version + SSD1306_DISPLAY_OFFSET, 1, 0x00, // 0xD3 + SSD1306_SET_START_LINE, 0, // 0x40 + SSD1306_SET_CHAR_REG, 1, 0x14, // 0x8D / Enable charge pump during display on + SSD1306_MEMORY_ADDR_MODE, 1, 0x00, // 0x20 / Set Memory Addressing Mode + // 0x00 / Horizontal Addressing Mode + // 0x01 / Vertical Addressing Mode + // 0x02 / Page Addressing Mode (RESET) + SSD1306_SEG_REMAP_OP, 0, // 0xA0 / remap 0xA1 + SSD1306_COM_SCAN_DIR_OP, 0, // 0xC8 + SSD1306_COM_PIN_CONF, 0, 0x02, // 0xDA / 0x12 - Disable COM Left/Right remap, Alternative COM pin configuration + // 0x12 - for 128 x 64 version + // 0x02 - for 128 x 32 version + SSD1306_SET_CONTRAST, 1, 0x8F, // 0x81 / 0x8F - reset value (max 0xFF) + SSD1306_SET_PRECHARGE, 1, 0xc2, // 0xD9 / higher value less blinking + // 0xC2, 1st phase = 2 DCLK, 2nd phase = 13 DCLK + SSD1306_VCOM_DESELECT, 1, 0x40, // 0xDB / Set V COMH Deselect, reset value 0x22 = 0,77xUcc + SSD1306_DIS_ENT_DISP_ON, 0, // 0xA4 + SSD1306_DIS_NORMAL, 0, // 0xA6 + SSD1306_DEACT_SCROLL, 0, // 0x2E + SSD1306_DISPLAY_ON, 0 // 0xAF / Set Display ON +}; -// @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_DISPLAY_OFF, 0, // 0xAE = Set Display OFF + SSD1306_SET_MUX_RATIO, 1, 0x1F, // 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, 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 - 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 }; // @var array Chache memory Lcd 8 * 128 = 1024 static char cacheMemLcd[CACHE_SIZE_MEM]; /** - * @desc SSD1306 Init + * +------------------------------------------------------------------------------------+ + * |== PRIVATE FUNCTIONS ===============================================================| + * +------------------------------------------------------------------------------------+ + */ + +/** + * @brief SSD1306 Init * * @param uint8_t address * @@ -141,72 +101,48 @@ static char cacheMemLcd[CACHE_SIZE_MEM]; */ uint8_t SSD1306_Init (uint8_t address) { - // variables - const uint8_t *commands = INIT_SSD1306; - // number of commands - unsigned short int no_of_commands = pgm_read_byte(commands++); - // argument - uint8_t no_of_arguments; - // command - uint8_t command; - // init status - uint8_t status = INIT_STATUS; + 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: start & SLAW // ------------------------------------------------------------------------------------- status = SSD1306_Send_StartAndSLAW (address); - // request - start TWI if (SSD1306_SUCCESS != status) { - // error return status; } - - // loop through commands - while (no_of_commands) { - - // number of arguments - no_of_arguments = pgm_read_byte (commands++); - // command - command = pgm_read_byte (commands++); - - // send command + // Commands & Arguments // ------------------------------------------------------------------------------------- - status = SSD1306_Send_Command (command); - // request - start TWI + while (commands--) { + // Command + // ----------------------------------------------------------------------------------- + status = SSD1306_Send_Command (pgm_read_byte(list++)); if (SSD1306_SUCCESS != status) { - // error return status; } - - // send arguments - // ------------------------------------------------------------------------------------- - while (no_of_arguments--) { - // send command - status = SSD1306_Send_Command (pgm_read_byte(commands++)); - // request - start TWI + // Arguments + // ----------------------------------------------------------------------------------- + arguments = pgm_read_byte (list++); + while (arguments--) { + status = SSD1306_Send_Command (pgm_read_byte(list++)); // argument if (SSD1306_SUCCESS != status) { - // error return status; } } - // decrement - no_of_commands--; } - // TWI: Stop // ------------------------------------------------------------------------------------- TWI_Stop (); - // success return SSD1306_SUCCESS; } /** - * @desc SSD1306 Send Start and SLAW request + * @brief SSD1306 Send Start and SLAW request * * @param uint8_t * @@ -214,33 +150,26 @@ uint8_t SSD1306_Init (uint8_t address) */ uint8_t SSD1306_Send_StartAndSLAW (uint8_t address) { - // init status uint8_t status = INIT_STATUS; // TWI: start // ------------------------------------------------------------------------------------- status = TWI_MT_Start (); - // request - start TWI if (SSD1306_SUCCESS != status) { - // error return status; } - // TWI: send SLAW // ------------------------------------------------------------------------------------- status = TWI_MT_Send_SLAW (address); - // request - send SLAW if (SSD1306_SUCCESS != status) { - // error return status; } - // success return SSD1306_SUCCESS; } /** - * @desc SSD1306 Send command + * @brief SSD1306 Send command * * @param uint8_t command * @@ -248,33 +177,32 @@ uint8_t SSD1306_Send_StartAndSLAW (uint8_t address) */ uint8_t SSD1306_Send_Command (uint8_t command) { - // init status uint8_t status = INIT_STATUS; // send control byte // ------------------------------------------------------------------------------------- status = TWI_MT_Send_Data (SSD1306_COMMAND); - // request - start TWI if (SSD1306_SUCCESS != status) { - // error return status; } - // send command // ------------------------------------------------------------------------------------- status = TWI_MT_Send_Data (command); - // request - start TWI if (SSD1306_SUCCESS != status) { - // error return status; } - // success return SSD1306_SUCCESS; } /** - * @desc SSD1306 Normal colors + * +------------------------------------------------------------------------------------+ + * |== PUBLIC FUNCTIONS ================================================================| + * +------------------------------------------------------------------------------------+ + */ + +/** + * @brief SSD1306 Normal colors * * @param uint8_t address * @@ -282,33 +210,29 @@ uint8_t SSD1306_Send_Command (uint8_t command) */ uint8_t SSD1306_NormalScreen (uint8_t address) { - // init status uint8_t status = INIT_STATUS; // TWI: start & SLAW // ------------------------------------------------------------------------------------- status = SSD1306_Send_StartAndSLAW (address); - // request succesfull if (SSD1306_SUCCESS != status) { - // error return status; } - // send command // ------------------------------------------------------------------------------------- status = SSD1306_Send_Command (SSD1306_DIS_NORMAL); - // request succesfull if (SSD1306_SUCCESS != status) { - // error return status; } + // TWI: Stop + // ------------------------------------------------------------------------------------- + TWI_Stop (); - // success return SSD1306_SUCCESS; } /** - * @desc SSD1306 Inverse colors + * @brief SSD1306 Inverse colors * * @param uint8_t address * @@ -316,33 +240,29 @@ uint8_t SSD1306_NormalScreen (uint8_t address) */ uint8_t SSD1306_InverseScreen (uint8_t address) { - // init status uint8_t status = INIT_STATUS; // TWI: start & SLAW // ------------------------------------------------------------------------------------- status = SSD1306_Send_StartAndSLAW (address); - // request succesfull if (SSD1306_SUCCESS != status) { - // error return status; } - // send command // ------------------------------------------------------------------------------------- status = SSD1306_Send_Command (SSD1306_DIS_INVERSE); - // request succesfull if (SSD1306_SUCCESS != status) { - // error return status; } + // TWI: Stop + // ------------------------------------------------------------------------------------- + TWI_Stop (); - // success return SSD1306_SUCCESS; } /** - * @desc SSD1306 Update screen + * @brief SSD1306 Update screen * * @param uint8_t address * @@ -350,52 +270,38 @@ uint8_t SSD1306_InverseScreen (uint8_t address) */ uint8_t SSD1306_UpdateScreen (uint8_t address) { - // init status uint8_t status = INIT_STATUS; - // init i uint16_t i = 0; // TWI: start & SLAW // ------------------------------------------------------------------------------------- status = SSD1306_Send_StartAndSLAW (address); - // request succesfull if (SSD1306_SUCCESS != status) { - // error return status; } - // control byte data stream // ------------------------------------------------------------------------------------- status = TWI_MT_Send_Data (SSD1306_DATA_STREAM); - // request succesfull if (SSD1306_SUCCESS != status) { - // error return status; } - // send cache memory lcd // ------------------------------------------------------------------------------------- while (i < CACHE_SIZE_MEM) { - // send data - status = TWI_MT_Send_Data (cacheMemLcd[i]); - // request succesfull + status = TWI_MT_Send_Data (cacheMemLcd[i++]); // send data if (SSD1306_SUCCESS != status) { - // error return status; } - // increment - i++; } - // stop TWI + // ------------------------------------------------------------------------------------- TWI_Stop (); - // success return SSD1306_SUCCESS; } /** - * @desc SSD1306 Clear screen + * @brief SSD1306 Clear screen * * @param void * @@ -403,12 +309,11 @@ uint8_t SSD1306_UpdateScreen (uint8_t address) */ void SSD1306_ClearScreen (void) { - // null cache memory lcd - memset (cacheMemLcd, 0x00, CACHE_SIZE_MEM); + memset (cacheMemLcd, 0x00, CACHE_SIZE_MEM); // null cache memory lcd } /** - * @desc SSD1306 Set position + * @brief SSD1306 Set position * * @param uint8_t column -> 0 ... 127 * @param uint8_t page -> 0 ... 7 or 3 @@ -417,12 +322,11 @@ void SSD1306_ClearScreen (void) */ void SSD1306_SetPosition (uint8_t x, uint8_t y) { - // calculate counter - _counter = x + (y << 7); + _counter = x + (y << 7); // update counter } /** - * @desc SSD1306 Update text poisition - this ensure that character will not be divided at the end of row, + * @brief SSD1306 Update text poisition - this ensure that character will not be divided at the end of row, * the whole character will be depicted on the new row * * @param void @@ -431,32 +335,23 @@ void SSD1306_SetPosition (uint8_t x, uint8_t y) */ uint8_t SSD1306_UpdatePosition (void) { - // y / 8 - uint8_t y = _counter >> 7; - // y % 8 - uint8_t x = _counter - (y << 7); - // x + character length + 1 - uint8_t x_new = x + CHARS_COLS_LENGTH + 1; - - // check position - if (x_new > END_COLUMN_ADDR) { - // if more than allowable number of pages - if (y > END_PAGE_ADDR) { - // return out of range - return SSD1306_ERROR; - // if x reach the end but page in range - } else if (y < (END_PAGE_ADDR-1)) { - // update - _counter = ((++y) << 7); + uint8_t y = _counter >> 7; // y / 8 + uint8_t x = _counter - (y << 7); // y % 8 + uint8_t x_new = x + CHARS_COLS_LENGTH + 1; // x + character length + 1 + + if (x_new > END_COLUMN_ADDR) { // check position + if (y > END_PAGE_ADDR) { // if more than allowable number of pages + return SSD1306_ERROR; // return out of range + } else if (y < (END_PAGE_ADDR-1)) { // if x reach the end but page in range + _counter = ((++y) << 7); // update } } - // success return SSD1306_SUCCESS; } /** - * @desc SSD1306 Draw character + * @brief SSD1306 Draw character * * @param char character * @@ -464,31 +359,21 @@ uint8_t SSD1306_UpdatePosition (void) */ uint8_t SSD1306_DrawChar (char character) { - // variables uint8_t i = 0; - // update text position - // this ensure that character will not be divided at the end of row, the whole character will be depicted on the new row if (SSD1306_UpdatePosition () == SSD1306_ERROR) { - // error return SSD1306_ERROR; } - - // loop through 5 bits while (i < CHARS_COLS_LENGTH) { - // read byte cacheMemLcd[_counter++] = pgm_read_byte(&FONTS[character-32][i++]); } - - // update position _counter++; - // success return SSD1306_SUCCESS; } /** - * @desc SSD1306 Draw String + * @brief SSD1306 Draw String * * @param char * string * @@ -496,17 +381,14 @@ uint8_t SSD1306_DrawChar (char character) */ void SSD1306_DrawString (char *str) { - // init int i = 0; - // loop through character of string while (str[i] != '\0') { - // draw string SSD1306_DrawChar (str[i++]); } } /** - * @desc Draw pixel + * @brief Draw pixel * * @param uint8_t x -> 0 ... MAX_X * @param uint8_t y -> 0 ... MAX_Y @@ -517,27 +399,20 @@ uint8_t SSD1306_DrawPixel (uint8_t x, uint8_t y) { uint8_t page = 0; uint8_t pixel = 0; - - // if out of range - if ((x > MAX_X) || (y > MAX_Y)) { - // out of range - return SSD1306_ERROR; + + if ((x > MAX_X) || (y > MAX_Y)) { // if out of range + return SSD1306_ERROR; // out of range } - // find page (y / 8) - page = y >> 3; - // which pixel (y % 8) - pixel = 1 << (y - (page << 3)); - // update counter - _counter = x + (page << 7); - // save pixel - cacheMemLcd[_counter++] |= pixel; + page = y >> 3; // find page (y / 8) + pixel = 1 << (y - (page << 3)); // which pixel (y % 8) + _counter = x + (page << 7); // update counter + cacheMemLcd[_counter++] |= pixel; // save pixel - // success return SSD1306_SUCCESS; } /** - * @desc Draw line by Bresenham algoritm + * @brief Draw line by Bresenham algoritm * * @param uint8_t x start position / 0 <= cols <= MAX_X-1 * @param uint8_t x end position / 0 <= cols <= MAX_X-1 @@ -548,79 +423,52 @@ uint8_t SSD1306_DrawPixel (uint8_t x, uint8_t y) */ uint8_t SSD1306_DrawLine (uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2) { - // determinant - int16_t D; - // deltas - int16_t delta_x, delta_y; - // steps - int16_t trace_x = 1, trace_y = 1; + int16_t D; // determinant + int16_t delta_x, delta_y; // deltas + int16_t trace_x = 1, trace_y = 1; // steps - // delta x - delta_x = x2 - x1; - // delta y - delta_y = y2 - y1; - - // check if x2 > x1 - if (delta_x < 0) { - // negate delta x - delta_x = -delta_x; - // negate step x - trace_x = -trace_x; + delta_x = x2 - x1; // delta x + delta_y = y2 - y1; // delta y + + if (delta_x < 0) { // check if x2 > x1 + delta_x = -delta_x; // negate delta x + trace_x = -trace_x; // negate step x } - - // check if y2 > y1 - if (delta_y < 0) { - // negate detla y - delta_y = -delta_y; - // negate step y - trace_y = -trace_y; + + if (delta_y < 0) { // check if y2 > y1 + delta_y = -delta_y; // negate detla y + trace_y = -trace_y; // negate step y } // Bresenham condition for m < 1 (dy < dx) + // ------------------------------------------------------------------------------------- if (delta_y < delta_x) { - // calculate determinant - D = (delta_y << 1) - delta_x; - // draw first pixel - SSD1306_DrawPixel (x1, y1); - // check if x1 equal x2 - while (x1 != x2) { - // update x1 - x1 += trace_x; - // check if determinant is positive - if (D >= 0) { - // update y1 - y1 += trace_y; - // update determinant - D -= 2*delta_x; + D = (delta_y << 1) - delta_x; // calculate determinant + SSD1306_DrawPixel (x1, y1); // draw first pixel + while (x1 != x2) { // check if x1 equal x2 + x1 += trace_x; // update x1 + if (D >= 0) { // check if determinant is positive + y1 += trace_y; // update y1 + D -= 2*delta_x; // update determinant } - // update deteminant - D += 2*delta_y; - // draw next pixel - SSD1306_DrawPixel (x1, y1); + D += 2*delta_y; // update deteminant + SSD1306_DrawPixel (x1, y1); // draw next pixel } // for m > 1 (dy > dx) + // ------------------------------------------------------------------------------------- } else { - // calculate determinant - D = delta_y - (delta_x << 1); - // draw first pixel - SSD1306_DrawPixel (x1, y1); - // check if y2 equal y1 - while (y1 != y2) { - // update y1 - y1 += trace_y; - // check if determinant is positive - if (D <= 0) { - // update y1 - x1 += trace_x; - // update determinant - D += 2*delta_y; + D = delta_y - (delta_x << 1); // calculate determinant + SSD1306_DrawPixel (x1, y1); // draw first pixel + while (y1 != y2) { // check if y2 equal y1 + y1 += trace_y; // update y1 + if (D <= 0) { // check if determinant is positive + x1 += trace_x; // update y1 + D += 2*delta_y; // update determinant } - // update deteminant - D -= 2*delta_x; - // draw next pixel - SSD1306_DrawPixel (x1, y1); + D -= 2*delta_x; // update deteminant + SSD1306_DrawPixel (x1, y1); // draw next pixel } } - // success return + return SSD1306_SUCCESS; -} +} \ No newline at end of file diff --git a/lib/ssd1306.h b/lib/ssd1306.h index ff73588..7b8b6d0 100644 --- a/lib/ssd1306.h +++ b/lib/ssd1306.h @@ -81,7 +81,7 @@ // AREA definition // ------------------------------------------------------------------------------------ #define START_PAGE_ADDR 0 - #define END_PAGE_ADDR 7 // 7 for 128x64, 3 for 128x32 version + #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 diff --git a/main.c b/main.c index 6df8925..1e3441c 100644 --- a/main.c +++ b/main.c @@ -1,20 +1,19 @@ /** * --------------------------------------------------------------------------------------+ - * @desc OLED SSD1306 example + * @name OLED SSD1306 example * --------------------------------------------------------------------------------------+ * Copyright (C) 2020 Marian Hrinko. * Written by Marian Hrinko (mato.hrinko@gmail.com) * * @author Marian Hrinko * @date 06.10.2020 - * @update 19.07.2021 * @file main.c * @version 2.0.0 - * @tested AVR Atmega328p + * @test AVR Atmega328p * * @depend lib/ssd1306.h * --------------------------------------------------------------------------------------+ - * @descr Version 1.0.0 -> applicable for 1 display + * @brief 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 * --------------------------------------------------------------------------------------+ @@ -22,6 +21,7 @@ // include libraries #include "lib/ssd1306.h" +#include /** * @desc Main function @@ -32,32 +32,30 @@ */ int main(void) { - uint8_t addr = SSD1306_ADDR; + // LCD INIT + // ------------------------------------------------------------------------------------- + SSD1306_Init (SSD1306_ADDR); // 0x3C - // init ssd1306 - SSD1306_Init (addr); + // DRAWING + // ------------------------------------------------------------------------------------- + SSD1306_ClearScreen (); // clear screen + SSD1306_DrawLine (0, MAX_X, 4, 4); // draw line + SSD1306_SetPosition (7, 1); // set position + SSD1306_DrawString ("SSD1306 OLED DRIVER"); // draw string + SSD1306_DrawLine (0, MAX_X, 18, 18); // draw line + SSD1306_SetPosition (40, 3); // set position + SSD1306_DrawString ("MATIASUS"); // draw string + SSD1306_SetPosition (53, 5); // set position + SSD1306_DrawString ("2021"); // draw string + SSD1306_UpdateScreen (SSD1306_ADDR); // update - // clear screen - SSD1306_ClearScreen (); - // draw line - SSD1306_DrawLine (0, MAX_X, 4, 4); - // set position - SSD1306_SetPosition (7, 1); - // draw string - SSD1306_DrawString ("SSD1306 OLED DRIVER"); - // draw line - SSD1306_DrawLine (0, MAX_X, 18, 18); - // set position - SSD1306_SetPosition (40, 3); - // draw string - SSD1306_DrawString ("MATIASUS"); - // set position - SSD1306_SetPosition (53, 5); - // draw string - SSD1306_DrawString ("2021"); - // update - SSD1306_UpdateScreen (addr); + _delay_ms (1000); + SSD1306_InverseScreen (SSD1306_ADDR); - // return value + _delay_ms (1000); + SSD1306_NormalScreen (SSD1306_ADDR); + + // RETURN + // ------------------------------------------------------------------------------------- return 0; -} +} \ No newline at end of file