SSD1306/lib/ssd1306.c

506 lines
20 KiB
C
Raw Normal View History

2022-11-21 08:31:26 -05:00
/**
* ---------------------------------------------------------------+
2020-10-13 04:45:09 -04:00
* @desc SSD1306 OLED Driver
2022-11-21 08:31:26 -05:00
* ---------------------------------------------------------------+
2020-10-13 04:45:09 -04:00
* Copyright (C) 2020 Marian Hrinko.
* Written by Marian Hrinko (mato.hrinko@gmail.com)
*
* @author Marian Hrinko
* @datum 06.10.2020
2022-11-21 08:31:26 -05:00
* @update 21.11.2022
2022-11-22 14:38:14 -05:00
* @file ssd1306.c
2022-11-21 08:31:26 -05:00
* @version 3.0
2022-11-22 14:38:14 -05:00
* @tested AVR Atmega328
2020-10-13 04:48:15 -04:00
*
* @depend font.h, twi.h
2020-10-13 04:45:09 -04:00
* ---------------------------------------------------------------+
2022-11-22 14:38:14 -05:00
* @descr Version 1.0 -> applicable for 1 display
* Version 2.0 -> rebuild to 'cacheMemLcd' array
2022-11-21 08:31:26 -05:00
* Version 3.0 -> remove 'cacheMemLcd' approach
2022-11-22 14:38:14 -05:00
* ---------------------------------------------------------------+
* @usage Basic Setup for OLED Display
2020-10-13 04:45:09 -04:00
*/
2022-11-21 08:31:26 -05:00
2020-10-13 04:45:09 -04:00
#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 |
// +---------------------------+
2022-11-21 08:31:26 -05:00
// @array Init command
2020-10-13 04:45:09 -04:00
const uint8_t INIT_SSD1306[] PROGMEM = {
2022-11-21 08:31:26 -05:00
18, // number of initializers
0, SSD1306_DISPLAY_OFF, // 0xAE = Set Display OFF
1, SSD1306_SET_MUX_RATIO, 0x3F, // 0xA8
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_COLUMN_ADDR, END_COLUMN_ADDR, // 0x21 = Set Column Address
2, SSD1306_SET_PAGE_ADDR, START_PAGE_ADDR, END_PAGE_ADDR, // 0x22 = Set Page Address
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
1, SSD1306_SET_CONTRAST, 0x7F, // 0x81
0, SSD1306_DIS_ENT_DISP_ON, // 0xA4
0, SSD1306_DIS_NORMAL, // 0xA6
1, SSD1306_SET_OSC_FREQ, 0x80, // 0xD5
1, SSD1306_SET_PRECHARGE, 0xc2, // 0xD9, 1st Period = higher value less blinking
1, SSD1306_VCOM_DESELECT, 0x20, // Set V COMH Deselect, reset value 0x22 = 0,77xUcc
1, SSD1306_SET_CHAR_REG, 0x14, // 0x8D
0, SSD1306_DISPLAY_ON // 0xAF = Set Display ON
2020-10-13 04:45:09 -04:00
};
2022-11-22 14:38:14 -05:00
// @var array Chache memory Lcd 8 * 128 = 1024
static char cacheMemLcd[CACHE_SIZE_MEM];
2020-10-13 04:45:09 -04:00
/**
* @desc SSD1306 Init
*
2022-11-22 14:38:14 -05:00
* @param uint8_t address
2020-10-13 04:45:09 -04:00
*
2022-11-22 14:38:14 -05:00
* @return uint8_t
2020-10-13 04:45:09 -04:00
*/
2022-11-22 14:38:14 -05:00
uint8_t SSD1306_Init (uint8_t address)
2022-11-21 08:31:26 -05:00
{
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
uint8_t command; // command
uint8_t status = INIT_STATUS; // TWI init status 0xFF
// TWI INIT
// -------------------------------------------------------------------------------------
2022-11-22 14:38:14 -05:00
TWI_Init ();
2020-10-13 04:45:09 -04:00
2022-11-21 08:31:26 -05:00
// TWI Start & SLAW
// -------------------------------------------------------------------------------------
status = SSD1306_Send_StartAndSLAW (address); // start & SLAW
if (SSD1306_SUCCESS != status) { // check status
return status; // error
2020-10-13 04:45:09 -04:00
}
2022-11-21 08:31:26 -05:00
// MAIN LOOP
// -------------------------------------------------------------------------------------
while (no_of_commands) { // commands loop
no_of_arguments = pgm_read_byte (commands++); // number of arguments
command = pgm_read_byte (commands++); // command
// SEND COMMAND
// -----------------------------------------------------------------------------------
status = SSD1306_Send_Command (command); // send command
if (SSD1306_SUCCESS != status) { // check status
return status; // error
2020-10-13 04:45:09 -04:00
}
2022-11-21 08:31:26 -05:00
// SEND ARGUMENTS
// -----------------------------------------------------------------------------------
2020-10-13 04:45:09 -04:00
while (no_of_arguments--) {
2022-11-21 08:31:26 -05:00
status = SSD1306_Send_Command (pgm_read_byte(commands++)); // send argument
if (SSD1306_SUCCESS != status) { // check status
return status; // error
2020-10-13 04:45:09 -04:00
}
}
2022-11-21 08:31:26 -05:00
no_of_commands--; // next command
}
// TWI STOP
// -------------------------------------------------------------------------------------
2022-11-22 14:38:14 -05:00
TWI_Stop ();
2020-10-13 04:45:09 -04:00
2022-11-21 08:31:26 -05:00
return SSD1306_SUCCESS; // success
2020-10-13 04:45:09 -04:00
}
/**
* @desc SSD1306 Send Start and SLAW request
*
2022-11-22 14:38:14 -05:00
* @param uint8_t
2020-10-13 04:45:09 -04:00
*
2022-11-22 14:38:14 -05:00
* @return uint8_t
2020-10-13 04:45:09 -04:00
*/
2022-11-22 14:38:14 -05:00
uint8_t SSD1306_Send_StartAndSLAW (uint8_t address)
2020-10-13 04:45:09 -04:00
{
2022-11-21 08:31:26 -05:00
uint8_t status = INIT_STATUS; // TWI init status 0xFF
2020-10-13 04:45:09 -04:00
2022-11-21 08:31:26 -05:00
// TWI START
// -------------------------------------------------------------------------------------
status = TWI_MT_Start (); // start
if (SSD1306_SUCCESS != status) { // check status
return status; // error
2020-10-13 04:45:09 -04:00
}
2022-11-21 08:31:26 -05:00
// TWI start & SLAW
// -------------------------------------------------------------------------------------
status = TWI_MT_Send_SLAW (address); // start & SLAW
if (SSD1306_SUCCESS != status) { // check status
return status; // error
2020-10-13 04:45:09 -04:00
}
2022-11-21 08:31:26 -05:00
return SSD1306_SUCCESS; // success
2020-10-13 04:45:09 -04:00
}
/**
* @desc SSD1306 Send command
*
2022-11-22 14:38:14 -05:00
* @param uint8_t command
2020-10-13 04:45:09 -04:00
*
2022-11-22 14:38:14 -05:00
* @return uint8_t
2020-10-13 04:45:09 -04:00
*/
2022-11-22 14:38:14 -05:00
uint8_t SSD1306_Send_Command (uint8_t command)
2020-10-13 04:45:09 -04:00
{
2022-11-21 08:31:26 -05:00
uint8_t status = INIT_STATUS; // TWI init status 0xFF
2020-10-13 04:45:09 -04:00
2022-11-21 08:31:26 -05:00
// TWI send control byte
// -------------------------------------------------------------------------------------
status = TWI_MT_Send_Data (SSD1306_COMMAND); // send control byte
if (SSD1306_SUCCESS != status) { // check status
return status; // error
2020-10-13 04:45:09 -04:00
}
2022-11-21 08:31:26 -05:00
// TWI send command
// -------------------------------------------------------------------------------------
status = TWI_MT_Send_Data (command); // send command
if (SSD1306_SUCCESS != status) { // check status
return status; // error
2020-10-13 04:45:09 -04:00
}
2022-11-21 08:31:26 -05:00
return SSD1306_SUCCESS; // success
2020-10-13 04:45:09 -04:00
}
2020-10-27 08:05:53 -04:00
/**
2022-11-22 14:38:14 -05:00
* @desc SSD1306 Normal colors
2020-10-27 08:05:53 -04:00
*
2022-11-22 14:38:14 -05:00
* @param uint8_t address
2020-10-27 08:05:53 -04:00
*
2022-11-22 14:38:14 -05:00
* @return uint8_t
2020-10-27 08:05:53 -04:00
*/
2022-11-22 14:38:14 -05:00
uint8_t SSD1306_NormalScreen (uint8_t address)
2020-10-27 08:05:53 -04:00
{
2022-11-21 08:31:26 -05:00
uint8_t status = INIT_STATUS; // TWI init status 0xFF
2020-10-27 08:05:53 -04:00
2022-11-21 08:31:26 -05:00
// TWI start & SLAW
// -------------------------------------------------------------------------------------
status = SSD1306_Send_StartAndSLAW (address); // start & SLAW
if (SSD1306_SUCCESS != status) { // check status
return status; // error
2020-10-27 08:05:53 -04:00
}
2022-11-21 08:31:26 -05:00
// TWI send command
// -------------------------------------------------------------------------------------
status = SSD1306_Send_Command (SSD1306_DIS_NORMAL); // command 0xA6
if (SSD1306_SUCCESS != status) { // check status
return status; // error
2020-10-27 08:05:53 -04:00
}
2022-11-21 08:31:26 -05:00
return SSD1306_SUCCESS; // success
2020-10-27 08:05:53 -04:00
}
/**
2022-11-22 14:38:14 -05:00
* @desc SSD1306 Inverse colors
2020-10-27 08:05:53 -04:00
*
2022-11-22 14:38:14 -05:00
* @param uint8_t address
2020-10-27 08:05:53 -04:00
*
2022-11-22 14:38:14 -05:00
* @return uint8_t
2020-10-27 08:05:53 -04:00
*/
2022-11-22 14:38:14 -05:00
uint8_t SSD1306_InverseScreen (uint8_t address)
2020-10-27 08:05:53 -04:00
{
2022-11-22 14:38:14 -05:00
uint8_t status = INIT_STATUS;
2020-10-27 08:05:53 -04:00
2022-11-21 08:31:26 -05:00
// TWI start & SLAW
// -------------------------------------------------------------------------------------
status = SSD1306_Send_StartAndSLAW (address); // start & SLAW
if (SSD1306_SUCCESS != status) { // check status
return status; // error
2020-10-27 08:05:53 -04:00
}
2022-11-21 08:31:26 -05:00
// TWI send command
// -------------------------------------------------------------------------------------
status = SSD1306_Send_Command (SSD1306_DIS_INVERSE); // command 0xA7
if (SSD1306_SUCCESS != status) { // check status
return status; // error
2020-10-27 08:05:53 -04:00
}
2022-11-21 08:31:26 -05:00
return SSD1306_SUCCESS; // success
2020-10-27 08:05:53 -04:00
}
/**
2022-11-22 14:38:14 -05:00
* @desc SSD1306 Update screen
2020-10-27 08:05:53 -04:00
*
2022-11-22 14:38:14 -05:00
* @param uint8_t address
2020-10-27 08:05:53 -04:00
*
2022-11-22 14:38:14 -05:00
* @return uint8_t
2020-10-27 08:05:53 -04:00
*/
2022-11-22 14:38:14 -05:00
uint8_t SSD1306_UpdateScreen (uint8_t address)
2020-10-27 08:05:53 -04:00
{
2022-11-21 08:31:26 -05:00
uint8_t status = INIT_STATUS; // TWI init status 0xFF
uint16_t i = 0; // counter
// TWI start & SLAW
// -------------------------------------------------------------------------------------
status = SSD1306_Send_StartAndSLAW (address); // start & SLAW
if (SSD1306_SUCCESS != status) { // check status
return status; // error
2020-10-13 04:45:09 -04:00
}
2022-11-21 08:31:26 -05:00
// 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
2020-10-13 04:45:09 -04:00
}
2022-11-21 08:31:26 -05:00
// TWI send cache memory lcd
// -------------------------------------------------------------------------------------
2022-11-22 14:38:14 -05:00
while (i < CACHE_SIZE_MEM) {
2022-11-21 08:31:26 -05:00
status = TWI_MT_Send_Data (cacheMemLcd[i]); // send data
if (SSD1306_SUCCESS != status) { // check status
return status; // error
2020-10-13 04:45:09 -04:00
}
2022-11-21 08:31:26 -05:00
i++; // next value
2020-10-13 04:45:09 -04:00
}
2022-11-21 08:31:26 -05:00
// TWI stop
// -------------------------------------------------------------------------------------
2022-11-22 14:38:14 -05:00
TWI_Stop ();
2020-10-13 04:45:09 -04:00
2022-11-21 08:31:26 -05:00
return SSD1306_SUCCESS; // success
2020-10-13 04:45:09 -04:00
}
2020-10-27 08:05:53 -04:00
/**
2022-11-22 14:38:14 -05:00
* @desc SSD1306 Clear screen
2020-10-27 08:05:53 -04:00
*
2022-11-22 14:38:14 -05:00
* @param void
2020-10-27 08:05:53 -04:00
*
2022-11-22 14:38:14 -05:00
* @return void
2020-10-27 08:05:53 -04:00
*/
2022-11-22 14:38:14 -05:00
void SSD1306_ClearScreen (void)
2020-10-27 08:05:53 -04:00
{
2022-11-21 08:31:26 -05:00
memset (cacheMemLcd, 0x00, CACHE_SIZE_MEM); // null cache memory lcd
2020-10-27 08:05:53 -04:00
}
2020-10-13 04:45:09 -04:00
/**
2022-11-22 14:38:14 -05:00
* @desc SSD1306 Set position
2020-10-13 04:45:09 -04:00
*
2022-11-21 08:31:26 -05:00
* @param uint8_t column -> 0 ... 127
2022-11-22 14:38:14 -05:00
* @param uint8_t page -> 0 ... 7
2020-10-13 04:45:09 -04:00
*
* @return void
*/
2022-11-21 08:31:26 -05:00
void SSD1306_SetPosition (uint8_t x, uint8_t y)
2020-10-13 04:45:09 -04:00
{
2022-11-21 08:31:26 -05:00
_counter = x + (y << 7); // calculate counter
2020-10-27 08:05:53 -04:00
}
/**
2022-11-21 08:31:26 -05:00
* @desc 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
2020-10-27 08:05:53 -04:00
*
2022-11-22 14:38:14 -05:00
* @param void
2020-10-27 08:05:53 -04:00
*
2022-11-22 14:38:14 -05:00
* @return uint8_t
2020-10-27 08:05:53 -04:00
*/
2022-11-21 08:31:26 -05:00
uint8_t SSD1306_UpdTxtPosition (void)
2020-10-27 08:05:53 -04:00
{
2022-11-21 08:31:26 -05:00
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
2022-11-22 14:38:14 -05:00
}
2020-10-27 08:05:53 -04:00
}
2022-11-21 08:31:26 -05:00
return SSD1306_SUCCESS; // success
2020-10-27 08:05:53 -04:00
}
/**
2022-11-22 14:38:14 -05:00
* @desc SSD1306 Draw character
2020-10-27 08:05:53 -04:00
*
2022-11-22 14:38:14 -05:00
* @param char character
2020-10-27 08:05:53 -04:00
*
2022-11-22 14:38:14 -05:00
* @return uint8_t
2020-10-27 08:05:53 -04:00
*/
2022-11-21 08:31:26 -05:00
uint8_t SSD1306_DrawChar (char ch)
2020-10-27 08:05:53 -04:00
{
2022-11-22 14:38:14 -05:00
uint8_t i = 0;
2020-10-27 08:05:53 -04:00
2022-11-22 14:38:14 -05:00
// 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_UpdTxtPosition () == SSD1306_ERROR) {
2022-11-21 08:31:26 -05:00
return SSD1306_ERROR; // error
2020-10-27 08:05:53 -04:00
}
2022-11-21 08:31:26 -05:00
while (i < CHARS_COLS_LENGTH) { // loop through 5 bits
cacheMemLcd[_counter++] = pgm_read_byte(&FONTS[ch-32][i++]); // read byte
2020-10-27 08:05:53 -04:00
}
2022-11-21 08:31:26 -05:00
_counter++; // update position
return SSD1306_SUCCESS; // success
2020-10-13 04:45:09 -04:00
}
/**
* @desc SSD1306 Draw String
*
2022-11-22 14:38:14 -05:00
* @param char * string
2020-10-13 04:45:09 -04:00
*
2022-11-22 14:51:50 -05:00
* @return uint8_t
2020-10-13 04:45:09 -04:00
*/
2022-11-22 14:38:14 -05:00
void SSD1306_DrawString (char *str)
2020-10-13 04:45:09 -04:00
{
2022-11-21 08:31:26 -05:00
int i = 0; // init
while (str[i] != '\0') { // loop through character of string
SSD1306_DrawChar (str[i++]); // draw string
2020-10-13 04:45:09 -04:00
}
}
2020-10-27 08:05:53 -04:00
/**
2022-11-22 14:38:14 -05:00
* @desc Draw pixel
2020-10-27 08:05:53 -04:00
*
2022-11-22 14:38:14 -05:00
* @param uint8_t x -> 0 ... MAX_X
* @param uint8_t y -> 0 ... MAX_Y
2020-10-27 08:05:53 -04:00
*
2022-11-22 14:38:14 -05:00
* @return uint8_t
2020-10-27 08:05:53 -04:00
*/
2022-11-22 14:38:14 -05:00
uint8_t SSD1306_DrawPixel (uint8_t x, uint8_t y)
2020-10-27 08:05:53 -04:00
{
2022-11-22 14:38:14 -05:00
uint8_t page = 0;
uint8_t pixel = 0;
2020-10-27 08:05:53 -04:00
2022-11-21 08:31:26 -05:00
if ((x > MAX_X) && (y > MAX_Y)) { // if out of range
return SSD1306_ERROR; // out of range
2020-10-27 08:05:53 -04:00
}
2022-11-21 08:31:26 -05:00
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
return SSD1306_SUCCESS; // success
2020-10-27 08:05:53 -04:00
}
2022-11-22 14:38:14 -05:00
/**
* @desc Draw line by Bresenham algoritm
2022-11-21 08:31:26 -05:00
*
2022-11-22 14:38:14 -05:00
* @param uint8_t x start position / 0 <= cols <= MAX_X-1
* @param uint8_t x end position / 0 <= cols <= MAX_X-1
2022-11-21 08:31:26 -05:00
* @param uint8_t y start position / 0 <= rows <= MAX_Y-1
2022-11-22 14:38:14 -05:00
* @param uint8_t y end position / 0 <= rows <= MAX_Y-1
*
* @return uint8_t
*/
uint8_t SSD1306_DrawLine (uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2)
{
2022-11-21 08:31:26 -05:00
int16_t D; // determinant
int16_t delta_x, delta_y; // deltas
int16_t trace_x = 1, trace_y = 1; // steps
2022-11-22 14:38:14 -05:00
2022-11-21 08:31:26 -05:00
delta_x = x2 - x1; // delta x
delta_y = y2 - y1; // delta y
2021-07-19 09:06:29 -04:00
2022-11-21 08:31:26 -05:00
if (delta_x < 0) { // check if x2 > x1
delta_x = -delta_x; // negate delta x
trace_x = -trace_x; // negate step x
2022-11-22 14:38:14 -05:00
}
2022-11-21 08:31:26 -05:00
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) { //
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) { // positive?
y1 += trace_y; // update y1
D -= 2*delta_x; // update determinant
2022-11-22 14:38:14 -05:00
}
2022-11-21 08:31:26 -05:00
D += 2*delta_y; // update deteminant
SSD1306_DrawPixel (x1, y1); // draw next pixel
2022-11-22 14:38:14 -05:00
}
2022-11-21 08:31:26 -05:00
// condition for m >= 1 (dy >= dx)
// -------------------------------------------------------------------------------------
2022-11-22 14:38:14 -05:00
} else {
2022-11-21 08:31:26 -05:00
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) { // positive?
x1 += trace_x; // update y1
D += 2*delta_y; // update determinant
2022-11-22 14:38:14 -05:00
}
2022-11-21 08:31:26 -05:00
D -= 2*delta_x; // update deteminant
SSD1306_DrawPixel (x1, y1); // draw next pixel
2022-11-22 14:38:14 -05:00
}
}
2022-11-21 08:31:26 -05:00
return SSD1306_SUCCESS; // success return
2022-11-22 14:38:14 -05:00
}