Add drawLine horizontal, vertical lines

This commit is contained in:
Matiasus 2024-09-05 13:27:38 +02:00
parent f18ec22fd1
commit 6def203ae8
3 changed files with 721 additions and 182 deletions

View File

@ -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,7 +240,6 @@ 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
// -------------------------------------------------------------------------------------
@ -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<CACHE_SIZE_MEM; i++) {
status = TWI_MT_Send_Data (CLEAR_COLOR); // send data 0x00
if (SSD1306_SUCCESS != status) { // check status
return status; // error
}
}
// TWI STOP
// -------------------------------------------------------------------------------------
TWI_Stop ();
return SSD1306_SUCCESS; // success
}
/**
* @desc SSD1306 Clear screen
*
* @param uint8_t page
*
* @return uint8_t
*/
uint8_t SSD1306_ClearPage (uint8_t page)
{
uint8_t status = INIT_STATUS; // TWI init status 0xFF
// 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 (0); // start COLUMN
if (SSD1306_SUCCESS != status) { // check status
return status; // error
}
status = SSD1306_Send_Command (END_COLUMN_ADDR); // end COLUMN
if (SSD1306_SUCCESS != status) { // check status
return status; // error
}
_indexCol = 0; // 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 (page); // start PAGE
if (SSD1306_SUCCESS != status) { // check status
return status; // error
}
status = SSD1306_Send_Command (page); // end PAGE
if (SSD1306_SUCCESS != status) { // check status
return status; // error
}
_indexPage = 0; // update column index
// TWI control byte data stream
// -------------------------------------------------------------------------------------
status = TWI_MT_Send_Data (SSD1306_DATA_STREAM); // send data 0x40
@ -361,12 +353,80 @@ uint8_t SSD1306_ClearScreen (void)
}
// send clear byte to memory lcd
// -------------------------------------------------------------------------------------
while (i < CACHE_SIZE_MEM) {
for (uint16_t i=0; i<=END_COLUMN_ADDR; i++) {
status = TWI_MT_Send_Data (CLEAR_COLOR); // send data 0x00
if (SSD1306_SUCCESS != status) { // check status
return status; // error
}
}
// TWI STOP
// -------------------------------------------------------------------------------------
TWI_Stop ();
return SSD1306_SUCCESS; // success
}
/**
* @desc SSD1306 Clear screen
*
* @param uint8_t page
* @param uint8_t margin
*
* @return uint8_t
*/
uint8_t SSD1306_ClearPageFromToEnd (uint8_t page, uint8_t margin)
{
uint8_t status = INIT_STATUS; // TWI init status 0xFF
// 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 (margin); // start COLUMN
if (SSD1306_SUCCESS != status) { // check status
return status; // error
}
status = SSD1306_Send_Command (END_COLUMN_ADDR-margin); // end COLUMN
if (SSD1306_SUCCESS != status) { // check status
return status; // error
}
_indexCol = margin; // 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 (page); // start PAGE
if (SSD1306_SUCCESS != status) { // check status
return status; // error
}
status = SSD1306_Send_Command (END_PAGE_ADDR); // end PAGE
if (SSD1306_SUCCESS != status) { // check status
return status; // error
}
_indexPage = 0; // update column index
// TWI control byte data stream
// -------------------------------------------------------------------------------------
status = TWI_MT_Send_Data (SSD1306_DATA_STREAM); // send data 0x40
if (SSD1306_SUCCESS != status) { // check status
return status; // error
}
// send clear byte to memory lcd
// -------------------------------------------------------------------------------------
for (uint16_t i=0; i<=((END_PAGE_ADDR-page) * (END_COLUMN_ADDR - 2*margin)); i++) {
status = TWI_MT_Send_Data (CLEAR_COLOR); // send data 0x00
if (SSD1306_SUCCESS != status) { // check status
return status; // error
}
i++; // update counter
}
// TWI STOP
// -------------------------------------------------------------------------------------
@ -474,7 +534,7 @@ uint8_t SSD1306_UpdatePosition (uint8_t x, uint8_t p)
// last page not reached
// -----------------------------------------------------------------------------------
if (p < END_PAGE_ADDR) {
_indexCol = 0; // update column
_indexCol = 2; // update column
_indexPage = _indexPage + 1; // update page
status = SSD1306_SetPosition (_indexCol, _indexPage); // update position
if (SSD1306_SUCCESS != status) { // check status
@ -625,3 +685,366 @@ uint8_t SSD1306_DrawString (char *str, enum E_Font font)
return SSD1306_SUCCESS; // success
}
/**
* @desc SSD1306 Draw String
*
* @param char * string
* @param E_Font
*
* @return uint8_t
*/
uint8_t SSD1306_DrawSongName (char * str, enum E_Font font)
{
uint8_t i = 0; // char counter
uint8_t n = 8;
// send characters of string
// -------------------------------------------------------------------------------------
while (i < n) {
if (str[i] == ' ') {
i++;
} else {
SSD1306_DrawChar (str[i++], font); // send char
}
}
return SSD1306_SUCCESS; // success
}
/**
* @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 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;
}

View File

@ -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 <util/delay.h>
#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);
/**
* @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

14
main.c
View File

@ -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;