First Commit

This commit is contained in:
MindCreeper03
2025-02-27 19:31:50 +01:00
parent bcbb6aff9a
commit e490df1715
2470 changed files with 1479965 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
# MIT License
#
# Copyright (c) 2018-2019, Alexey Dynda
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
#################################################################
# Makefile containing common logic for all systems
default: all
DESTDIR ?=
BLD ?= ../../bld
# ************* Common defines ********************
CPPFLAGS += -I.
CPPFLAGS += -g -Os -Wall -Werror -ffunction-sections -fdata-sections \
-fno-exceptions -Wno-error=deprecated-declarations \
$(EXTRA_CPPFLAGS)
CFLAGS += -std=c99
.PHONY: clean ssd1306_sdl all
OBJS = \
sdl_core.o \
sdl_graphics.o \
sdl_ssd1306.o \
sdl_ssd1325.o \
sdl_ssd1331.o \
sdl_ssd1351.o \
sdl_il9163.o \
sdl_ili9341.o \
sdl_pcd8544.o \
####################### Compiling library #########################
$(BLD)/libssd1306_sdl.a: $(OBJS)
$(AR) rcs $@ $(OBJS)
ssd1306_sdl: $(BLD)/libssd1306_sdl.a
all: ssd1306_sdl
clean:
rm -rf $(BLD)
rm -rf $(OBJS)
rm -rf $(OBJS:%.o=%.d)
rm -rf $(OBJS:.o=.gcno) $(OBJS:.o=.gcda)

View File

@@ -0,0 +1,36 @@
# MIT License
#
# Copyright (c) 2018, Alexey Dynda
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
#################################################################
# Makefile containing common logic for all systems
#
# Accepts the following parameters:
# CC
# CXX
# STRIP
# AR
CC=gcc
MKDIR=mkdir
BACKSLASH=\\
include Makefile.linux

Binary file not shown.

View File

@@ -0,0 +1,60 @@
#!/bin/sh
prefix=/usr/local/i686-w64-mingw32
exec_prefix=${prefix}
exec_prefix_set=no
libdir=${exec_prefix}/lib
#usage="\
#Usage: $0 [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--cflags] [--libs]"
usage="\
Usage: $0 [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--cflags] [--libs] [--static-libs]"
if test $# -eq 0; then
echo "${usage}" 1>&2
exit 1
fi
while test $# -gt 0; do
case "$1" in
-*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) optarg= ;;
esac
case $1 in
--prefix=*)
prefix=$optarg
if test $exec_prefix_set = no ; then
exec_prefix=$optarg
fi
;;
--prefix)
echo $prefix
;;
--exec-prefix=*)
exec_prefix=$optarg
exec_prefix_set=yes
;;
--exec-prefix)
echo $exec_prefix
;;
--version)
echo 2.0.7
;;
--cflags)
echo -I${prefix}/include/SDL2 -Dmain=SDL_main
;;
--libs)
echo -L${exec_prefix}/lib -lmingw32 -lSDL2main -lSDL2 -mwindows
;;
--static-libs)
# --libs|--static-libs)
echo -L${exec_prefix}/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc
;;
*)
echo "${usage}" 1>&2
exit 1
;;
esac
shift
done

View File

@@ -0,0 +1,276 @@
/*
MIT License
Copyright (c) 2018, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "sdl_core.h"
#include "sdl_graphics.h"
#include "sdl_oled_basic.h"
#include "sdl_ssd1306.h"
#include "sdl_ssd1325.h"
#include "sdl_ssd1331.h"
#include "sdl_ssd1351.h"
#include "sdl_il9163.h"
#include "sdl_ili9341.h"
#include "sdl_pcd8544.h"
#include <unistd.h>
#include <SDL2/SDL.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define CANVAS_REFRESH_RATE 60
enum
{
SDL_AUTODETECT,
SDL_DETECTED,
};
static int s_analogInput[128];
static int s_digitalPins[128];
static int s_dcPin = -1;
static uint8_t s_gpioKeys[6] = {0};
static sdl_oled_info *p_oled_db[128] = { NULL };
static sdl_oled_info *p_active_driver = NULL;
int s_commandId = SSD_COMMAND_NONE;
int s_cmdArgIndex;
static int s_ssdMode = SSD_MODE_NONE;
static sdl_data_mode s_active_data_mode = SDM_COMMAND_ARG;
static int s_oled = SDL_AUTODETECT;
static void register_oled(sdl_oled_info *oled_info)
{
sdl_oled_info **p = p_oled_db;
while (*p) (p++);
*p = oled_info;
if ( oled_info->reset )
{
oled_info->reset();
}
}
static void unregister_oleds(void)
{
memset( p_oled_db, 0, sizeof( p_oled_db ) );
p_active_driver = NULL;
}
void sdl_core_init(void)
{
s_commandId = SSD_COMMAND_NONE;
s_ssdMode = SSD_MODE_NONE;
s_active_data_mode = SDM_COMMAND_ARG;
s_oled = SDL_AUTODETECT;
s_dcPin = -1;
memset(s_gpioKeys, 0, sizeof(s_gpioKeys));
register_oled( &sdl_ssd1306 );
register_oled( &sdl_ssd1325 );
register_oled( &sdl_ssd1331x8 );
register_oled( &sdl_ssd1331x16 );
register_oled( &sdl_ssd1351 );
register_oled( &sdl_il9163 );
register_oled( &sdl_ili9341 );
register_oled( &sdl_pcd8544 );
sdl_graphics_init();
}
static void sdl_poll_event(void)
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT) exit(0);
switch (event.type)
{
case SDL_KEYDOWN:
if (event.key.keysym.scancode == SDL_SCANCODE_DOWN) { s_analogInput[0] = 300; s_digitalPins[s_gpioKeys[0]] = 1; }
if (event.key.keysym.scancode == SDL_SCANCODE_UP) { s_analogInput[0] = 150; s_digitalPins[s_gpioKeys[3]] = 1; }
if (event.key.keysym.scancode == SDL_SCANCODE_LEFT) { s_analogInput[0] = 500; s_digitalPins[s_gpioKeys[1]] = 1; }
if (event.key.keysym.scancode == SDL_SCANCODE_RIGHT) { s_analogInput[0] = 50; s_digitalPins[s_gpioKeys[2]] = 1; }
if (event.key.keysym.scancode == SDL_SCANCODE_SPACE) { s_analogInput[0] = 700; s_digitalPins[s_gpioKeys[4]] = 1; }
if (event.key.keysym.scancode == SDL_SCANCODE_Z) { s_analogInput[0] = 700; s_digitalPins[s_gpioKeys[4]] = 1; }
if (event.key.keysym.scancode == SDL_SCANCODE_X) { s_digitalPins[s_gpioKeys[5]] = 1; }
break;
case SDL_KEYUP:
if (event.key.keysym.scancode == SDL_SCANCODE_DOWN) { s_analogInput[0] = 1023; s_digitalPins[s_gpioKeys[0]] = 0; }
if (event.key.keysym.scancode == SDL_SCANCODE_UP) { s_analogInput[0] = 1023; s_digitalPins[s_gpioKeys[3]] = 0; }
if (event.key.keysym.scancode == SDL_SCANCODE_LEFT) { s_analogInput[0] = 1023; s_digitalPins[s_gpioKeys[1]] = 0; }
if (event.key.keysym.scancode == SDL_SCANCODE_RIGHT) { s_analogInput[0] = 1023; s_digitalPins[s_gpioKeys[2]] = 0; }
if (event.key.keysym.scancode == SDL_SCANCODE_SPACE) { s_analogInput[0] = 1023; s_digitalPins[s_gpioKeys[4]] = 0; }
if (event.key.keysym.scancode == SDL_SCANCODE_Z) { s_analogInput[0] = 1023; s_digitalPins[s_gpioKeys[4]] = 0; }
if (event.key.keysym.scancode == SDL_SCANCODE_X) { s_digitalPins[s_gpioKeys[5]] = 0; }
break;
default:
break;
};
}
}
void sdl_set_dc_pin(int pin)
{
s_dcPin = pin;
}
void sdl_set_gpio_keys(const uint8_t * pins)
{
memcpy(s_gpioKeys, pins, sizeof(s_gpioKeys));
}
int sdl_read_analog(int pin)
{
sdl_poll_event();
return s_analogInput[pin];
}
void sdl_write_digital(int pin, int value)
{
s_digitalPins[pin] = value;
}
int sdl_read_digital(int pin)
{
return s_digitalPins[pin];
}
void sdl_core_close(void)
{
sdl_graphics_close();
SDL_Quit();
unregister_oleds();
}
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
void sdl_send_init()
{
s_active_data_mode = SDM_COMMAND_ARG;
s_ssdMode = SSD_MODE_NONE;
// s_commandId = SSD_COMMAND_NONE;
}
static void sdl_send_command_or_arg(uint8_t data)
{
if (s_commandId == SSD_COMMAND_NONE)
{
s_commandId = data;
s_cmdArgIndex = -1; // no argument
}
else
{
s_cmdArgIndex++;
}
if (p_active_driver)
{
p_active_driver->run_cmd( data );
}
}
static void sdl_write_data(uint8_t data)
{
if (p_active_driver)
{
p_active_driver->run_data( data );
}
}
void sdl_send_byte(uint8_t data)
{
if (s_dcPin>=0)
{
// for spi
s_ssdMode = s_digitalPins[s_dcPin] ? SSD_MODE_DATA : SSD_MODE_COMMAND;
}
else if (s_ssdMode == SSD_MODE_NONE)
{
// for i2c
s_ssdMode = data == 0x00 ? SSD_MODE_COMMAND : SSD_MODE_DATA;
return;
}
if (s_ssdMode == SSD_MODE_COMMAND)
{
if (s_oled == SDL_AUTODETECT)
{
sdl_oled_info **p = p_oled_db;
while (*p)
{
if ((*p)->detect(data))
{
p_active_driver = *p;
s_oled = SDL_DETECTED;
s_commandId = SSD_COMMAND_NONE;
sdl_graphics_set_oled_params(
p_active_driver->width,
p_active_driver->height,
p_active_driver->bpp,
p_active_driver->pixfmt);
break;
}
p++;
}
}
else
{
sdl_send_command_or_arg( data );
}
}
else
{
if (p_active_driver)
{
if (p_active_driver->dataMode == SDMS_AUTO)
{
s_active_data_mode = SDM_WRITE_DATA;
}
switch ( s_active_data_mode )
{
case SDM_COMMAND_ARG:
sdl_send_command_or_arg( data );
break;
case SDM_WRITE_DATA:
sdl_write_data( data );
break;
default:
break;
}
}
}
}
void sdl_send_stop()
{
sdl_poll_event();
sdl_graphics_refresh();
s_ssdMode = -1;
}
void sdl_set_data_mode(sdl_data_mode mode)
{
s_active_data_mode = mode;
}

View File

@@ -0,0 +1,83 @@
/*
MIT License
Copyright (c) 2018-2019, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef _SDL_CORE_H_
#define _SDL_CORE_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
enum
{
SDL_LCD_TEMPLATE,
SDL_LCD_SSD1306,
SDL_LCD_SH1106,
SDL_LCD_PCD8544,
SDL_LCD_SSD1325,
SDL_LCD_SSD1327,
SDL_LCD_SSD1331_X8,
SDL_LCD_SSD1331_X16,
SDL_LCD_SSD1351,
SDL_LCD_IL9163,
SDL_LCD_ST7735,
SDL_LCD_ILI9341,
};
/** ssd1325 / ssd1327 types */
enum
{
SDL_LCD_SSD1325_GENERIC,
SDL_LCD_SSD1327_GENERIC,
SDL_LCD_SSD1327_NO_COM_SPLIT,
};
extern void sdl_core_init(void);
extern void sdl_core_draw(void);
extern void sdl_set_dc_pin(int pin);
// Accepts pointer to six-elements array
extern void sdl_set_gpio_keys(const uint8_t * pins);
extern void sdl_send_init();
extern void sdl_send_byte(uint8_t data);
extern void sdl_send_stop();
extern int sdl_read_analog(int pin);
extern void sdl_write_digital(int pin, int value);
extern int sdl_read_digital(int pin);
/** Allocates buffer, returns number of bytes allocated */
extern void sdl_core_get_pixels_data( uint8_t *pixels, uint8_t target_bpp );
/** Returns length in bytes, required to hold the data */
extern int sdl_core_get_pixels_len( uint8_t target_bpp );
extern void sdl_core_set_unittest_mode(void);
extern void sdl_core_close(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,326 @@
/*
MIT License
Copyright (c) 2018-2019, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "sdl_graphics.h"
#include "sdl_oled_basic.h"
#include <unistd.h>
#include <SDL2/SDL.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#define CANVAS_REFRESH_RATE 60
static SDL_Window *g_window = NULL;
static SDL_Renderer *g_renderer = NULL;
static SDL_Texture *g_texture = NULL;
void *g_pixels = NULL;
static int s_width = 128;
static int s_height = 64;
static int s_bpp = 16;
static uint32_t s_pixfmt = SDL_PIXELFORMAT_RGB565;
static bool s_unittest_mode = false;
static int windowWidth() { return s_width * PIXEL_SIZE + BORDER_SIZE * 2; };
static int windowHeight() { return s_height * PIXEL_SIZE + BORDER_SIZE * 2 + TOP_HEADER; };
void sdl_graphics_init(void)
{
if ((g_window != NULL) && (g_renderer != NULL))
{
/* SDL engine is already initialize */
return;
}
if ( s_unittest_mode )
{
SDL_Init(0);
return;
}
SDL_Init(SDL_INIT_EVERYTHING);
g_window = SDL_CreateWindow
(
"AVR SIMULATOR", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
windowWidth(),
windowHeight(),
SDL_WINDOW_SHOWN
);
g_renderer = SDL_CreateRenderer( g_window, -1, SDL_RENDERER_ACCELERATED );
// Set render color to black ( background will be rendered in this color )
SDL_SetRenderDrawColor( g_renderer, 20, 20, 20, 255 );
// Clear window
SDL_RenderClear( g_renderer );
// Render the rect to the screen
SDL_RenderPresent(g_renderer);
SDL_Rect r;
r.x = 0;
r.y = 0;
r.w = windowWidth();
r.h = windowHeight();
SDL_RenderFillRect( g_renderer, &r );
}
static void sdl_draw_oled_frame(void)
{
SDL_Rect r;
SDL_SetRenderDrawColor( g_renderer, 60, 128, 192, 255 );
r.x = 0; r.y = 0;
r.w = windowWidth();
r.h = TOP_HEADER + BORDER_SIZE - RECT_THICKNESS;
SDL_RenderFillRect( g_renderer, &r );
r.x = 0; r.y = TOP_HEADER + BORDER_SIZE - RECT_THICKNESS;
r.w = BORDER_SIZE - RECT_THICKNESS;
r.h = windowHeight() - ((BORDER_SIZE - RECT_THICKNESS)*2 + TOP_HEADER);
SDL_RenderFillRect( g_renderer, &r );
r.x = windowWidth() - (BORDER_SIZE - RECT_THICKNESS); r.y = TOP_HEADER + BORDER_SIZE - RECT_THICKNESS;
r.w = BORDER_SIZE - RECT_THICKNESS;
r.h = windowHeight() - ((BORDER_SIZE - RECT_THICKNESS)*2 + TOP_HEADER);
SDL_RenderFillRect( g_renderer, &r );
r.x = 0; r.y = windowHeight() - ((BORDER_SIZE - RECT_THICKNESS));
r.w = windowWidth();
r.h = BORDER_SIZE - RECT_THICKNESS;
SDL_RenderFillRect( g_renderer, &r );
SDL_SetRenderDrawColor( g_renderer, 0, 0, 0, 255 );
for (int i=0; i<RECT_THICKNESS; i++)
{
r.x = BORDER_SIZE - RECT_THICKNESS + i;
r.y = BORDER_SIZE - RECT_THICKNESS + TOP_HEADER + i;
r.w = windowWidth() - (BORDER_SIZE - RECT_THICKNESS + i)*2;
r.h = windowHeight() - ((BORDER_SIZE - RECT_THICKNESS + i)*2 + TOP_HEADER);
SDL_RenderDrawRect( g_renderer, &r );
}
#if !defined(SDL_NO_BORDER)
SDL_SetRenderDrawColor( g_renderer, 200, 200, 200, 255 );
r.x = 4;
r.y = 4;
r.w = 16;
r.h = 12;
SDL_RenderFillRect( g_renderer, &r );
r.x = windowWidth() - 4 - 16;
r.y = 4;
r.w = 16;
r.h = 12;
SDL_RenderFillRect( g_renderer, &r );
#endif
}
void sdl_graphics_refresh(void)
{
if ( s_unittest_mode )
{
return;
}
sdl_draw_oled_frame();
if (g_texture)
{
SDL_Rect r;
void * l_pixels;
int pitch;
if (SDL_LockTexture(g_texture, NULL, &l_pixels, &pitch) == 0)
{
if (pitch != s_width * (s_bpp/8))
{
fprintf(stderr, "Warning, pitch %d is not expected\n", pitch);
}
memcpy(l_pixels, g_pixels, s_width * s_height * (s_bpp/8));
SDL_UnlockTexture(g_texture);
}
else
{
fprintf(stderr, "Something bad happened to SDL texture\n");
exit(1);
}
r.x = BORDER_SIZE;
r.y = BORDER_SIZE + TOP_HEADER;
r.w = windowWidth() - BORDER_SIZE * 2;
r.h = windowHeight() - BORDER_SIZE * 2 - TOP_HEADER;
SDL_RenderCopy(g_renderer, g_texture, NULL, &r);
}
SDL_RenderPresent(g_renderer);
}
void sdl_graphics_set_oled_params(int width, int height, int bpp, uint32_t pixfmt)
{
SDL_Rect r;
s_bpp = bpp;
s_pixfmt = pixfmt;
s_width = width;
s_height = height;
if (g_texture)
{
SDL_DestroyTexture( g_texture );
g_texture = NULL;
free(g_pixels);
g_pixels = NULL;
}
g_pixels = malloc(s_width * s_height * (s_bpp / 8));
if ( s_unittest_mode )
{
return;
}
g_texture = SDL_CreateTexture( g_renderer, s_pixfmt,
SDL_TEXTUREACCESS_STREAMING,
width, height );
if (g_texture == NULL)
{
fprintf(stderr, "Error creating back buffer: %s\n", SDL_GetError());
exit(1);
}
SDL_SetWindowSize(g_window, windowWidth(), windowHeight());
SDL_SetRenderDrawColor( g_renderer, 20, 20, 20, 255 );
r.x = RECT_THICKNESS;
r.y = RECT_THICKNESS;
r.w = windowWidth() - RECT_THICKNESS*2;
r.h = windowHeight() - RECT_THICKNESS*2;
SDL_RenderFillRect( g_renderer, &r );
sdl_draw_oled_frame();
}
void sdl_put_pixel(int x, int y, uint32_t color)
{
while (x >= s_width) x-= s_width;
while (y >= s_height) y-= s_height;
if (x<0) x = 0;
if (y<0) y = 0;
if (g_pixels)
{
int index = x + y * s_width;
switch (s_bpp)
{
case 8:
((uint8_t *)g_pixels)[ index ] = color;
break;
case 16:
((uint16_t *)g_pixels)[ index ] = color;
break;
case 32:
((uint32_t *)g_pixels)[ index ] = color;
break;
default:
break;
}
}
}
uint32_t sdl_get_pixel(int x, int y)
{
uint32_t pixel = 0;
while (x >= s_width) x-= s_width;
while (y >= s_height) y-= s_height;
if (x<0) x = 0;
if (y<0) y = 0;
if (g_pixels)
{
int index = x + y * s_width;
switch (s_bpp)
{
case 8:
pixel = ((uint8_t *)g_pixels)[ index ];
break;
case 16:
pixel = ((uint16_t *)g_pixels)[ index ];
break;
case 32:
pixel = ((uint32_t *)g_pixels)[ index ];
break;
default:
break;
}
}
return pixel;
}
void sdl_graphics_close(void)
{
if ( s_unittest_mode )
{
return;
}
SDL_DestroyWindow(g_window);
}
static uint32_t convert_pixel( uint32_t value, uint8_t target_bpp )
{
uint32_t pixel;
switch ( s_pixfmt )
{
case SDL_PIXELFORMAT_RGB332: pixel = ((value & 0xE0) << 24) | ((value & 0x1C) << 19) | ((value & 0x03) << 14) | ( 0xFF ); break;
case SDL_PIXELFORMAT_RGB565: pixel = ((value & 0xF800) << 16) | ((value & 0x07E0) << 13) | ((value & 0x001F) << 11) | ( 0xFF ); break;
case SDL_PIXELFORMAT_RGBX8888: pixel = value;
default: pixel = 0; break;
}
switch ( target_bpp )
{
case 1: pixel = (pixel & 0xFFFFFF00) ? 1 : 0; break;
case 4: pixel = (pixel & 0x000000F0) >> 4; break;
case 8: pixel = ((pixel & 0xE0000000) >> 24) | ((pixel & 0x00E00000) >> 19) | ((pixel & 0x0000C000) >> 14); break;
case 16: pixel = ((pixel & 0xF8000000) >> 16) | ((pixel & 0x00FC0000) >> 13) | ((pixel & 0x0000F800) >> 11); break;
case 32: break;
default: break;
}
return pixel;
}
void sdl_core_get_pixels_data( uint8_t *pixels, uint8_t target_bpp )
{
for (int x = 0; x < s_width; x++)
for (int y = 0; y < s_height; y++)
{
uint32_t pixel = sdl_get_pixel( x, y );
pixel = convert_pixel( pixel, target_bpp );
switch ( target_bpp )
{
case 1: ((uint8_t *)pixels)[x + (y / 8)*s_width] |= (pixel << (y & 0x7)); break;
case 4: ((uint8_t *)pixels)[x / 2 + y * s_width / 2] |= (pixel << ((x & 1) * 4)); break;
case 8: ((uint8_t *)pixels)[x + y * s_width] = pixel; break;
case 16: ((uint16_t *)pixels)[x + y * s_width] = pixel; break;
case 32: ((uint32_t *)pixels)[x + y * s_width] = pixel; break;
default: break;
}
}
}
int sdl_core_get_pixels_len( uint8_t target_bpp )
{
int size = s_width * s_height * target_bpp / 8;
return size;
}
void sdl_core_set_unittest_mode(void)
{
s_unittest_mode = true;
}

View File

@@ -0,0 +1,47 @@
/*
MIT License
Copyright (c) 2018, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef _SDL_GRAPHICS_H_
#define _SDL_GRAPHICS_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern void sdl_graphics_init(void);
extern void sdl_graphics_refresh(void);
extern void sdl_graphics_close(void);
extern void sdl_graphics_set_oled_params(int width, int height, int bpp, uint32_t pixfmt);
extern void sdl_put_pixel(int x, int y, uint32_t color);
extern uint32_t sdl_get_pixel(int x, int y);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,261 @@
/*
MIT License
Copyright (c) 2018-2019, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "sdl_il9163.h"
#include "sdl_oled_basic.h"
#include "sdl_graphics.h"
#include "sdl_core.h"
static int s_activeColumn = 0;
static int s_activePage = 0;
static int s_columnStart = 0;
static int s_columnEnd = 127;
static int s_pageStart = 0;
static int s_pageEnd = 7;
static uint8_t detected = 0;
static uint8_t s_lcd_type;
static void sdl_il9163_reset(void)
{
detected = 0;
}
static int sdl_il9163_detect(uint8_t data)
{
if (detected)
{
switch (data)
{
case 0b00000000:
sdl_il9163.width = 128;
sdl_il9163.height = 128;
break;
case 0b00000011:
sdl_il9163.width = 128;
sdl_il9163.height = 160;
break;
default:
break;
}
return 1;
}
s_lcd_type = data;
detected = (data == SDL_LCD_IL9163) || (data == SDL_LCD_ST7735);
return 0;
}
static uint8_t s_verticalMode = 0;
static void sdl_il9163_commands(uint8_t data)
{
// if ((s_verticalMode & 0b00100000) && (s_cmdArgIndex < 0))
// {
// if (s_commandId == 0x2A) s_commandId = 0x2B;
// else if (s_commandId == 0x2B) s_commandId = 0x2A;
// }
switch (s_commandId)
{
case 0x36:
if (s_cmdArgIndex == 0)
{
s_verticalMode = data;
s_commandId = SSD_COMMAND_NONE;
}
break;
case 0x2A:
switch (s_cmdArgIndex)
{
case 0:
case 2:
break;
case 1:
if (!(s_verticalMode & 0b00100000))
{
s_columnStart = data;
s_activeColumn = data;
}
else
{
s_pageStart = data;
s_activePage = data;
}
break;
case 3:
if (!(s_verticalMode & 0b00100000))
{
s_columnEnd = data;
}
else
{
s_pageEnd = data;
}
s_commandId = SSD_COMMAND_NONE;
break;
default: break;
}
break;
case 0x2B:
switch (s_cmdArgIndex)
{
case 0:
case 2:
break;
case 1:
if (!(s_verticalMode & 0b00100000))
{
if ( s_lcd_type == SDL_LCD_ST7735 )
s_activePage = data;
else
// emulating bug in IL9163 Black display
s_activePage = (s_verticalMode & 0b10000000) ? data - 32 : data;
s_pageStart = s_activePage;
}
else
{
s_columnStart = data;
s_activeColumn = data;
}
break;
case 3:
if (!(s_verticalMode & 0b00100000))
{
if ( s_lcd_type == SDL_LCD_ST7735 )
s_pageEnd = data;
else
// emulating bug in IL9163 Black display
s_pageEnd = (s_verticalMode & 0b10000000) ? data - 32 : data;
}
else
{
s_columnEnd = data;
}
s_commandId = SSD_COMMAND_NONE;
break;
default: break;
}
break;
case 0x2C:
sdl_set_data_mode( SDM_WRITE_DATA );
s_commandId = SSD_COMMAND_NONE;
break;
case 0xC1: // PWCTR2
case 0xB4: // INVCTR display inversion, use by default
case 0xC5: // VMCTR vcom control 1
case 0x3A: // COLMOD set 16-bit pixel format
if (s_cmdArgIndex == 0) s_commandId = SSD_COMMAND_NONE;
break;
case 0xC2: // PWCTR3 power control 3
case 0xC3: // PWCTR4 (C3h): Power Control 4 (in Idle mode/ 8-colors)
case 0xC4: // PWCTR5 (C4h): Power Control 5 (in Partial mode/ full-colors)
case 0xB6: // DISSET5
if (s_cmdArgIndex == 1) s_commandId = SSD_COMMAND_NONE;
break;
case 0xB1: // FRMCTR1 frame rate control 1, use by default
case 0xB2: // FRMCTR2, Frame Rate Control (In Idle mode/ 8-colors)
case 0xC0: // PWCTR1 power control 1
if (s_cmdArgIndex == 2) s_commandId = SSD_COMMAND_NONE;
break;
case 0xB3: // FRMCTR3 (B3h): Frame Rate Control (In Partial mode/ full colors)
if (s_cmdArgIndex == 5) s_commandId = SSD_COMMAND_NONE;
break;
case 0xE0: // GMCTRP1 positive gamma correction
case 0xE1: // GMCTRN1 negative gamma correction
if (s_cmdArgIndex == 15) s_commandId = SSD_COMMAND_NONE;
break;
case 0x01: // SWRESET
case 0x11: // SLPOUT
case 0x20: // INVOFF (20h): Display Inversion Off
default:
s_commandId = SSD_COMMAND_NONE;
break;
}
}
void sdl_il9163_data(uint8_t data)
{
int y = s_activePage;
int x = s_activeColumn;
static uint8_t firstByte = 1; /// il9163
static uint8_t dataFirst = 0x00; /// il9163
if (firstByte)
{
dataFirst = data;
firstByte = 0;
return;
}
firstByte = 1;
int rx, ry;
if (s_verticalMode & 0b00100000)
{
rx = (s_verticalMode & 0b01000000) ? (sdl_il9163.width - 1 - x) : x;
ry = (s_verticalMode & 0b10000000) ? (sdl_il9163.height - 1 - y) : y;
}
else
{
rx = (s_verticalMode & 0b10000000) ? (sdl_il9163.width - 1 - x) : x;
ry = (s_verticalMode & 0b01000000) ? (sdl_il9163.height - 1 - y) : y;
}
sdl_put_pixel(rx, ry, (dataFirst<<8) | data);
if (s_verticalMode & 0b00100000)
{
s_activePage++;
if (s_activePage > s_pageEnd)
{
s_activePage = s_pageStart;
s_activeColumn++;
if (s_activeColumn > s_columnEnd)
{
s_activeColumn = s_columnStart;
}
}
}
else
{
s_activeColumn++;
if (s_activeColumn > s_columnEnd)
{
s_activeColumn = s_columnStart;
s_activePage++;
if (s_activePage > s_pageEnd)
{
s_activePage = s_pageStart;
}
}
}
}
sdl_oled_info sdl_il9163 =
{
.width = 128,
.height = 128,
.bpp = 16,
.pixfmt = SDL_PIXELFORMAT_RGB565,
.dataMode = SDMS_CONTROLLER,
.detect = sdl_il9163_detect,
.run_cmd = sdl_il9163_commands,
.run_data = sdl_il9163_data,
.reset = sdl_il9163_reset,
};

View File

@@ -0,0 +1,42 @@
/*
MIT License
Copyright (c) 2018, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef _SDL_IL9163_H_
#define _SDL_IL9163_H_
#include <stdint.h>
#include "sdl_oled_basic.h"
#ifdef __cplusplus
extern "C" {
#endif
extern sdl_oled_info sdl_il9163;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,243 @@
/*
MIT License
Copyright (c) 2018, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "sdl_ili9341.h"
#include "sdl_oled_basic.h"
#include "sdl_graphics.h"
#include "sdl_core.h"
static int s_activeColumn = 0;
static int s_activePage = 0;
static int s_columnStart = 0;
static int s_columnEnd = 127;
static int s_pageStart = 0;
static int s_pageEnd = 7;
static uint8_t detected = 0;
static int sdl_ili9341_detect(uint8_t data)
{
if (detected)
{
return 1;
}
detected = (data == SDL_LCD_ILI9341);
return 0;
}
static uint8_t s_verticalMode = 0;
static void sdl_ili9341_commands(uint8_t data)
{
// if ((s_verticalMode & 0b00100000) && (s_cmdArgIndex < 0))
// {
// if (s_commandId == 0x2A) s_commandId = 0x2B;
// else if (s_commandId == 0x2B) s_commandId = 0x2A;
// }
switch (s_commandId)
{
case 0x36:
if (s_cmdArgIndex == 0)
{
s_verticalMode = data;
s_commandId = SSD_COMMAND_NONE;
}
break;
case 0x2A:
switch (s_cmdArgIndex)
{
case 0:
if (!(s_verticalMode & 0b00100000))
{
s_columnStart = data;
s_activeColumn = data;
}
else
{
s_pageStart = data;
s_activePage = data;
}
break;
case 1:
if (!(s_verticalMode & 0b00100000))
{
s_columnStart = data | (s_columnStart<<8);
s_activeColumn = data | (s_activeColumn<<8);
}
else
{
s_pageStart = data | (s_pageStart<<8);
s_activePage = data | (s_activePage<<8);
}
break;
case 2:
if (!(s_verticalMode & 0b00100000))
{
s_columnEnd = data;
}
else
{
s_pageEnd = data;
}
break;
case 3:
if (!(s_verticalMode & 0b00100000))
{
s_columnEnd = data | (s_columnEnd << 8);
}
else
{
s_pageEnd = data | (s_pageEnd << 8);
}
s_commandId = SSD_COMMAND_NONE;
break;
default: break;
}
break;
case 0x2B:
switch (s_cmdArgIndex)
{
case 0:
if (!(s_verticalMode & 0b00100000))
{
s_activePage = data;
s_pageStart = s_activePage;
}
else
{
s_columnStart = data;
s_activeColumn = data;
}
break;
case 1:
if (!(s_verticalMode & 0b00100000))
{
s_activePage = data | (s_activePage << 8);
s_pageStart = s_activePage;
}
else
{
s_columnStart = data | (s_columnStart << 8);
s_activeColumn = data | (s_activeColumn << 8);
}
break;
case 2:
if (!(s_verticalMode & 0b00100000))
{
s_pageEnd = data;
}
else
{
s_columnEnd = data;
}
break;
case 3:
if (!(s_verticalMode & 0b00100000))
{
s_pageEnd = data | (s_pageEnd << 8);
}
else
{
s_columnEnd = data | (s_columnEnd << 8);
}
s_commandId = SSD_COMMAND_NONE;
break;
default: break;
}
break;
case 0x2C:
sdl_set_data_mode( SDM_WRITE_DATA );
s_commandId = SSD_COMMAND_NONE;
break;
default:
s_commandId = SSD_COMMAND_NONE;
break;
}
}
void sdl_ili9341_data(uint8_t data)
{
int y = s_activePage;
int x = s_activeColumn;
static uint8_t firstByte = 1; /// ili9341
static uint8_t dataFirst = 0x00; /// ili9341
if (firstByte)
{
dataFirst = data;
firstByte = 0;
return;
}
firstByte = 1;
int rx, ry;
if (s_verticalMode & 0b00100000)
{
rx = (s_verticalMode & 0b01000000) ? x: (sdl_ili9341.width - 1 - x);
ry = (s_verticalMode & 0b10000000) ? (sdl_ili9341.height - 1 - y) : y;
}
else
{
rx = (s_verticalMode & 0b10000000) ? x: (sdl_ili9341.width - 1 - x);
ry = (s_verticalMode & 0b01000000) ? (sdl_ili9341.height - 1 - y) : y;
}
sdl_put_pixel(rx, ry, (dataFirst<<8) | data);
if (s_verticalMode & 0b00100000)
{
s_activePage++;
if (s_activePage > s_pageEnd)
{
s_activePage = s_pageStart;
s_activeColumn++;
if (s_activeColumn > s_columnEnd)
{
s_activeColumn = s_columnStart;
}
}
}
else
{
s_activeColumn++;
if (s_activeColumn > s_columnEnd)
{
s_activeColumn = s_columnStart;
s_activePage++;
if (s_activePage > s_pageEnd)
{
s_activePage = s_pageStart;
}
}
}
}
sdl_oled_info sdl_ili9341 =
{
.width = 240,
.height = 320,
.bpp = 16,
.pixfmt = SDL_PIXELFORMAT_RGB565,
.dataMode = SDMS_CONTROLLER,
.detect = sdl_ili9341_detect,
.run_cmd = sdl_ili9341_commands,
.run_data = sdl_ili9341_data,
};

View File

@@ -0,0 +1,42 @@
/*
MIT License
Copyright (c) 2018, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef _SDL_ILI9341_H_
#define _SDL_ILI9341_H_
#include <stdint.h>
#include "sdl_oled_basic.h"
#ifdef __cplusplus
extern "C" {
#endif
extern sdl_oled_info sdl_ili9341;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,91 @@
/*
MIT License
Copyright (c) 2018, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef _SDL_OLED_BASIC_H_
#define _SDL_OLED_BASIC_H_
#include <stdint.h>
#include <SDL2/SDL.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SSD_COMMAND_NONE -1
enum
{
SSD_MODE_NONE,
SSD_MODE_COMMAND,
SSD_MODE_DATA,
};
typedef enum
{
SDMS_AUTO, // Command arg/write data mode is selected by DC pin or i2c command
SDMS_CONTROLLER, // Command arg/write data mode is controlled by LCD controller special command
} sdl_data_mode_selection;
typedef enum
{
SDM_COMMAND_ARG, // data mode interprets all data as command args
SDM_WRITE_DATA, // data mode sends all data to GDRAM
} sdl_data_mode;
typedef struct
{
int width;
int height;
int bpp;
uint32_t pixfmt;
sdl_data_mode_selection dataMode;
int (*detect)(uint8_t data);
void (*run_cmd)(uint8_t data);
void (*run_data)(uint8_t data);
void (*reset)(void);
} sdl_oled_info;
#if defined(SDL_NO_BORDER)
const static int BORDER_SIZE = 0;
const static int TOP_HEADER = 0;
const static int RECT_THICKNESS = 0;
#else
const static int BORDER_SIZE = 8;
const static int TOP_HEADER = 16;
const static int RECT_THICKNESS = 2;
#endif
const static int PIXEL_SIZE = 2;
extern int s_commandId;
extern int s_cmdArgIndex;
extern uint8_t s_detected;
extern void sdl_set_data_mode(sdl_data_mode mode);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,122 @@
/*
MIT License
Copyright (c) 2018, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "sdl_pcd8544.h"
#include "sdl_oled_basic.h"
#include "sdl_graphics.h"
#include "sdl_core.h"
static int s_activeColumn = 0;
static int s_activePage = 0;
const static int s_columnStart = 0;
const static int s_columnEnd = 83;
const static int s_pageStart = 0;
const static int s_pageEnd = 5;
static int s_verticalMode = 0;
static uint8_t detected = 0;
static int sdl_pcd8544_detect(uint8_t data)
{
if (detected)
{
return 1;
}
detected = (data == SDL_LCD_PCD8544);
return 0;
}
static void sdl_pcd8544_commands(uint8_t data)
{
// printf("%02X\n", data);
switch (s_commandId)
{
case 0x20:
s_verticalMode = 0;
s_commandId = SSD_COMMAND_NONE;
break;
case 0x22:
s_verticalMode = 1;
s_commandId = SSD_COMMAND_NONE;
break;
default:
if ((s_commandId & 0x80) == 0x80 )
{
s_activeColumn = s_commandId & 0x7F;
if (s_activeColumn > s_columnEnd) s_activeColumn = s_columnEnd;
}
if ((s_commandId & 0xC0) == 0x40 )
{
s_activePage = s_commandId & 0x3F;
if (s_activePage > s_pageEnd) s_activePage = s_pageEnd;
}
s_commandId = SSD_COMMAND_NONE;
break;
}
}
void sdl_pcd8544_data(uint8_t data)
{
int x = s_activeColumn;
int y = s_activePage;
for (int i=0; i<8; i++)
{
if (data & (1<<i))
{
sdl_put_pixel(x, (y<<3) + i, 0xAD59);
}
else
{
sdl_put_pixel(x, (y<<3) + i, 0x0000);
}
}
if (s_verticalMode)
{
s_activePage++;
if (s_activePage > s_pageEnd)
{
s_activePage = s_pageStart;
}
}
else
{
s_activeColumn++;
if (s_activeColumn > s_columnEnd)
{
s_activeColumn = s_columnStart;
}
}
}
sdl_oled_info sdl_pcd8544 =
{
.width = 84,
.height = 48,
.bpp = 16,
.pixfmt = SDL_PIXELFORMAT_RGB565,
.dataMode = SDMS_AUTO,
.detect = sdl_pcd8544_detect,
.run_cmd = sdl_pcd8544_commands,
.run_data = sdl_pcd8544_data,
};

View File

@@ -0,0 +1,42 @@
/*
MIT License
Copyright (c) 2018, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef _SDL_PCD8544_H_
#define _SDL_PCD8544_H_
#include <stdint.h>
#include "sdl_oled_basic.h"
#ifdef __cplusplus
extern "C" {
#endif
extern sdl_oled_info sdl_pcd8544;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,222 @@
/*
MIT License
Copyright (c) 2018-2019, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "sdl_ssd1306.h"
#include "sdl_oled_basic.h"
#include "sdl_graphics.h"
#include "sdl_core.h"
#define SSD1306_MAX_BANKS 8
static int s_activeColumn = 0;
static int s_activePage = 0;
static int s_columnStart = 0;
static int s_columnEnd = 127;
static int s_pageStart = 0;
static int s_pageEnd = 7;
static uint8_t detected = 0;
static uint8_t gdram[128][64];
static uint8_t displayRemap = 0;
static uint8_t displayStartLine = 0;
static uint8_t displayOffset = 0;
static uint8_t multiplexRatio = 15;
static uint8_t displayOn = 0;
static void blt_single_pixel(uint8_t x, uint8_t y, uint8_t color)
{
uint16_t sdl_color = color ? 0xAD59: 0x0000;
gdram[x & 0x7F ][y & 0x3F] = color;
uint8_t line = (y - displayOffset - displayStartLine) & 0x3F;
if ( displayRemap )
{
line = multiplexRatio - line;
}
if ( line < sdl_ssd1306.height )
{
sdl_put_pixel(x, line, sdl_color);
}
}
static void blt_content()
{
for(uint8_t line = 0; line < sdl_ssd1306.height; line++)
{
uint8_t row = line;
uint8_t ram = line;
if ( displayRemap )
{
row = multiplexRatio - row;
ram = multiplexRatio - ram;
}
ram = (row + displayOffset + displayStartLine) & 0x3F;
row = (row + displayOffset) & 0x3F;
for(uint8_t column = 0; column < sdl_ssd1306.width; column++)
{
uint16_t color = (gdram[column][ram]) ? 0xAD59: 0x0000;
if ( row > (multiplexRatio + displayStartLine) ) color = 0x0000;
sdl_put_pixel(column, line, color);
}
}
}
static void sdl_ssd1306_reset(void)
{
detected = 0;
}
static int sdl_ssd1306_detect(uint8_t data)
{
if (detected)
{
return 1;
}
detected = (data == SDL_LCD_SSD1306) || (data == SDL_LCD_SH1106);
return 0;
}
static void sdl_ssd1306_commands(uint8_t data)
{
// printf("%02X (CMD: %02X)\n", data, s_commandId);
switch (s_commandId)
{
case 0x21:
switch (s_cmdArgIndex)
{
case 0:
s_columnStart = ( data >= sdl_ssd1306.width ? sdl_ssd1306.width - 1: data );
s_activeColumn = s_columnStart;
break;
case 1:
s_columnEnd = ( data >= sdl_ssd1306.width ? sdl_ssd1306.width - 1: data );
s_commandId = SSD_COMMAND_NONE;
break;
default: break;
}
break;
case 0x22:
switch (s_cmdArgIndex)
{
case 0:
s_pageStart = (data >= SSD1306_MAX_BANKS ? SSD1306_MAX_BANKS - 1 : data);
s_activePage = s_pageStart;
break;
case 1:
s_pageEnd = (data >= SSD1306_MAX_BANKS ? SSD1306_MAX_BANKS - 1 : data);
s_commandId = SSD_COMMAND_NONE;
break;
default: break;
}
break;
case 0xA8:
if (s_cmdArgIndex == 0)
{
multiplexRatio = data;
sdl_ssd1306.height = data + 1;
sdl_graphics_set_oled_params(sdl_ssd1306.width,
sdl_ssd1306.height,
sdl_ssd1306.bpp,
sdl_ssd1306.pixfmt);
if ( displayOn ) blt_content();
s_commandId = SSD_COMMAND_NONE;
}
break;
case 0xAF:
displayOn = 1;
blt_content();
s_commandId = SSD_COMMAND_NONE;
break;
case 0x81:
if ( s_cmdArgIndex == 0 )
{
// Just skip contrast command
s_commandId = SSD_COMMAND_NONE;
}
break;
case 0xD3: // Display offset
if ( s_cmdArgIndex == 0 )
{
displayOffset = data;
if ( displayOn ) blt_content();
s_commandId = SSD_COMMAND_NONE;
}
break;
default:
/* Other ssd1306 commands, many commands are combined with data */
if ((s_commandId >= 0xb0) && (s_commandId <= 0xbf))
{
s_activePage = (uint16_t)(s_commandId & 0x0F);
}
if ((s_commandId <= 0x0F))
{
s_activeColumn = (s_activeColumn & 0xFFF0) | (uint16_t)s_commandId;
}
if ((s_commandId >= 0x40) && (s_commandId <= 0x7F))
{
displayStartLine = s_commandId & 0x3F;
if ( displayOn ) blt_content();
}
if ((s_commandId <= 0x1F) && (s_commandId >= 0x10))
{
s_activeColumn = (s_activeColumn & 0x000F) | ((int16_t)(s_commandId & 0x0F) << 4);
}
s_commandId = SSD_COMMAND_NONE;
break;
}
}
void sdl_ssd1306_data(uint8_t data)
{
int y = s_activePage;
int x = s_activeColumn;
for (int i=0; i<8; i++)
{
blt_single_pixel( x, (y<<3) + i, data & (1<<i) );
}
s_activeColumn++;
if (s_activeColumn > s_columnEnd)
{
s_activeColumn = s_columnStart;
s_activePage++;
if (s_activePage > s_pageEnd)
{
s_activePage = s_pageStart;
}
}
}
sdl_oled_info sdl_ssd1306 =
{
.width = 128,
.height = 64,
.bpp = 16,
.pixfmt = SDL_PIXELFORMAT_RGB565,
.dataMode = SDMS_AUTO,
.detect = sdl_ssd1306_detect,
.run_cmd = sdl_ssd1306_commands,
.run_data = sdl_ssd1306_data,
.reset = sdl_ssd1306_reset,
};

View File

@@ -0,0 +1,42 @@
/*
MIT License
Copyright (c) 2018, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef _SDL_SSD1306_H_
#define _SDL_SSD1306_H_
#include <stdint.h>
#include "sdl_oled_basic.h"
#ifdef __cplusplus
extern "C" {
#endif
extern sdl_oled_info sdl_ssd1306;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,252 @@
/*
MIT License
Copyright (c) 2018-2019, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "sdl_ssd1325.h"
#include "sdl_oled_basic.h"
#include "sdl_graphics.h"
#include "sdl_core.h"
static int s_activeColumn = 0;
static int s_activeRow = 0;
static int s_columnStart = 0;
static int s_columnEnd = 127;
static int s_rowStart = 0;
static int s_rowEnd = 7;
static int s_newColumn;
static int s_newPage;
static uint8_t detected = 0;
static uint8_t s_subtype = SDL_LCD_SSD1325_GENERIC;
static uint8_t s_hwComSplit = 0;
static void copyBlock()
{
if ( s_newColumn < s_columnStart )
{
for( int y = s_rowStart; y <= s_rowEnd; y++)
for( int x = s_newColumn; x <= s_newColumn + s_columnEnd - s_columnStart; x++)
sdl_put_pixel(x, y, sdl_get_pixel( x + s_columnStart - s_newColumn, y ));
}
else
{
for( int y = s_rowStart; y <= s_rowEnd; y++)
for( int x = s_newColumn + s_columnEnd - s_columnStart; x >= s_newColumn; x--)
sdl_put_pixel(x, y, sdl_get_pixel( x + s_columnStart - s_newColumn, y ));
}
}
static int sdl_ssd1325_detect(uint8_t data)
{
if (detected)
{
switch (data)
{
case SDL_LCD_SSD1325_GENERIC:
s_hwComSplit = 1;
sdl_ssd1325.height = 64;
break;
case SDL_LCD_SSD1327_GENERIC:
s_hwComSplit = 1;
sdl_ssd1325.height = 128;
break;
case SDL_LCD_SSD1327_NO_COM_SPLIT:
s_hwComSplit = 0;
sdl_ssd1325.height = 128;
break;
default:
break;
}
s_subtype = data;
return 1;
}
detected = (data == SDL_LCD_SSD1325 || data == SDL_LCD_SSD1327);
return 0;
}
static uint8_t s_verticalMode = 1;
static uint8_t s_nimbleMapping = 0;
static uint8_t s_leftToRight = 0;
static uint8_t s_topToBottom = 0;
static uint8_t s_comSplit = 0;
static void sdl_ssd1325_commands(uint8_t data)
{
switch (s_commandId)
{
case 0xA0:
if (s_cmdArgIndex == 0)
{
// A[0] = Enable column address re-map
// A[1] = Enable Nibble remap
// A[2] = Enable Vertical Address increment
// A[4] = Enable COM-remap
// A[6] = Splitting ODD / Even signals
s_verticalMode = data & 0x04;
s_nimbleMapping = data & 0x02;
s_leftToRight = data & 0x01;
s_topToBottom = data & 0x10;
s_comSplit = data & 0x40;
s_commandId = SSD_COMMAND_NONE;
}
break;
case 0x15:
switch (s_cmdArgIndex)
{
case 0:
s_columnStart = data * 2;
s_activeColumn = data * 2;
break;
case 1:
s_columnEnd = data * 2 + 1;
s_commandId = SSD_COMMAND_NONE;
break;
default: break;
}
break;
case 0x23: // MOVE BLOCK
switch (s_cmdArgIndex)
{
case 0: s_columnStart = data * 2; break;
case 1: s_rowStart = data; break;
case 2: s_columnEnd = data * 2 + 1; break;
case 3: s_rowEnd = data; break;
case 4: s_newColumn = data * 2; break;
case 5:
s_newPage = data;
copyBlock();
s_commandId = SSD_COMMAND_NONE;
break;
default:
break;
}
break;
case 0x75:
switch (s_cmdArgIndex)
{
case 0:
s_activeRow = data;
s_rowStart = data;
break;
case 1:
s_rowEnd = data;
s_commandId = SSD_COMMAND_NONE;
break;
default: break;
}
break;
case 0xA8: // Multiplex
if ( s_cmdArgIndex == 0 )
{
s_columnEnd = data + 1;
s_commandId = SSD_COMMAND_NONE;
}
break;
case 0xAE: // OFF /* display off */
case 0xA4: // NORMAL
case 0x2E: // Deactivate scroll
case 0xAF: // Display ON
s_commandId = SSD_COMMAND_NONE;
break;
case 0xFD: // Unlock OLED
case 0xA1: // Start line
case 0xA2: // Display offset
case 0xAB: // VDD internal
case 0x81: // CONTRAST
case 0xB1: // PHASE 0x51
case 0xB3: // CLK
case 0xBC: // PRECHARGE
case 0xBE: // VCOMH voltage
case 0xB6: // Second pre-charge
if (s_cmdArgIndex == 0) s_commandId = SSD_COMMAND_NONE;
break;
default:
s_commandId = SSD_COMMAND_NONE;
break;
}
}
static void sdl_ssd1325_data(uint8_t data)
{
for (int i=0; i<2; i++)
{
int y = s_topToBottom ? s_activeRow : (sdl_ssd1325.height - s_activeRow - 1);
int x = s_leftToRight ? s_activeColumn: (sdl_ssd1325.width - s_activeColumn - 1);
if ( (s_comSplit && !s_hwComSplit) || (!s_comSplit && s_hwComSplit) )
{
y = ((y & 0x3F) * 2) + ((y > 0x3F) ? 1: 0);
}
sdl_put_pixel(x, y, ((data & 0x0F) << 28) |
((data & 0x0F) << 20) |
((data & 0x0F) << 12) |
((data & 0x0F) << 4) );
if (s_verticalMode)
{
if (i == 1)
{
s_activeColumn--;
s_activeRow++;
if (s_activeRow > s_rowEnd)
{
s_activeRow = s_rowStart;
s_activeColumn += 2;
}
}
if (i == 0)
{
s_activeColumn++;
}
if (s_activeColumn > s_columnEnd)
{
s_activeColumn = s_columnStart;
}
}
else
{
s_activeColumn++;
if (s_activeColumn > s_columnEnd)
{
s_activeColumn = s_columnStart;
s_activeRow++;
if (s_activeRow > s_rowEnd)
{
s_activeRow = s_rowStart;
}
}
}
data >>= 4;
}
}
sdl_oled_info sdl_ssd1325 =
{
.width = 128,
.height = 64,
.bpp = 32,
.pixfmt = SDL_PIXELFORMAT_RGBX8888,
.dataMode = SDMS_AUTO,
.detect = sdl_ssd1325_detect,
.run_cmd = sdl_ssd1325_commands,
.run_data = sdl_ssd1325_data,
};

View File

@@ -0,0 +1,42 @@
/*
MIT License
Copyright (c) 2018, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef _SDL_SSD1325_H_
#define _SDL_SSD1325_H_
#include <stdint.h>
#include "sdl_oled_basic.h"
#ifdef __cplusplus
extern "C" {
#endif
extern sdl_oled_info sdl_ssd1325;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,295 @@
/*
MIT License
Copyright (c) 2018-2019, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "sdl_ssd1331.h"
#include "sdl_oled_basic.h"
#include "sdl_graphics.h"
#include "sdl_core.h"
#include <stdlib.h>
static int s_activeColumn = 0;
static int s_activePage = 0;
static int s_columnStart = 0;
static int s_columnEnd = 127;
static int s_pageStart = 0;
static int s_pageEnd = 7;
static int s_newColumn;
static int s_newPage;
static uint32_t s_color = 0;
static uint8_t s_verticalMode = 1;
static uint8_t s_leftToRight = 0;
static uint8_t s_topToBottom = 0;
static uint8_t s_16bitmode = 0;
static uint8_t detected_x8 = 0;
static uint8_t detected_x16 = 0;
static void copyBlock()
{
int x_start = s_newColumn;
int x_end = s_newColumn + s_columnEnd - s_columnStart;
int x_dir = s_newColumn < s_columnStart ? 1 : -1;
int y_start = s_newPage;
int y_end = s_newPage + s_pageEnd - s_pageStart;
int y_dir = s_newPage < s_pageStart ? 1 : -1;
for( int y = y_dir > 0 ? y_start: y_end;
((y_dir > 0) && (y <= y_end)) || ((y_dir < 0) && (y >= y_start));
y = y + y_dir)
{
for( int x = x_dir > 0 ? x_start : x_end;
((x_dir > 0) && (x <= x_end)) || ((x_dir < 0) && (x >= x_start));
x = x + x_dir)
{
sdl_put_pixel(x, y, sdl_get_pixel( x + s_columnStart - s_newColumn,
y + s_pageStart - s_newPage ));
}
}
}
static void drawLine()
{
if ( abs(s_columnStart - s_columnEnd) > abs(s_pageStart - s_pageEnd) )
{
int x = s_columnStart;
while (x != s_columnEnd)
{
int y = s_pageStart + (s_pageEnd - s_pageStart)*(x - s_columnStart)/(s_columnEnd - s_columnStart);
sdl_put_pixel(x, y, s_color);
x += (s_columnEnd > s_columnStart ? 1: -1);
}
}
else
{
int y = s_pageStart;
while (y != s_pageEnd)
{
int x = s_columnStart + (s_columnEnd - s_columnStart)*(y - s_pageStart)/(s_pageEnd - s_pageStart);
sdl_put_pixel(x, y, s_color);
y += (s_pageEnd > s_pageStart ? 1: -1);
}
}
}
static void sdl_ssd1331_reset(void)
{
detected_x8 = 0;
detected_x16 = 0;
}
static int sdl_ssd1331_detect_x8(uint8_t data)
{
if (detected_x8)
{
return 1;
}
detected_x8 = (data == SDL_LCD_SSD1331_X8);
return 0;
}
static int sdl_ssd1331_detect_x16(uint8_t data)
{
if (detected_x16)
{
return 1;
}
detected_x16 = (data == SDL_LCD_SSD1331_X16);
return 0;
}
static void sdl_ssd1331_commands(uint8_t data)
{
switch (s_commandId)
{
case 0xA0:
if (s_cmdArgIndex == 0)
{
s_verticalMode = data & 0x01;
s_leftToRight = data & 0x02;
s_topToBottom = data & 0x10;
s_16bitmode = data & 0x40;
s_commandId = SSD_COMMAND_NONE;
}
break;
case 0x15:
switch (s_cmdArgIndex)
{
case 0:
s_columnStart = data;
s_activeColumn = data;
break;
case 1:
s_columnEnd = data;
s_commandId = SSD_COMMAND_NONE;
break;
default: break;
}
break;
case 0x21: // DRAW LINE
switch (s_cmdArgIndex)
{
case 0: s_columnStart = data; s_color = 0; break;
case 1: s_pageStart = data; break;
case 2: s_columnEnd = data; break;
case 3: s_pageEnd = data; break;
case 4:
if (s_16bitmode)
s_color |= ((data & 0x3F) >> 1);
else
s_color |= ((data & 0x30) >> 4);
break;
case 5:
if (s_16bitmode)
s_color |= ((data & 0x3F) << 5);
else
s_color |= ((data & 0x30) >> 1);
break;
case 6:
if (s_16bitmode)
s_color |= ((data & 0x3E) << 10);
else
s_color |= ((data & 0x38) << 2);
drawLine();
s_commandId = SSD_COMMAND_NONE;
break;
default:
break;
}
break;
case 0x23: // MOVE BLOCK
switch (s_cmdArgIndex)
{
case 0: s_columnStart = data; break;
case 1: s_pageStart = data; break;
case 2: s_columnEnd = data; break;
case 3: s_pageEnd = data; break;
case 4: s_newColumn = data; break;
case 5:
s_newPage = data;
copyBlock();
s_commandId = SSD_COMMAND_NONE;
break;
default:
break;
}
break;
case 0x75:
switch (s_cmdArgIndex)
{
case 0:
s_activePage = data;
s_pageStart = data;
break;
case 1:
s_pageEnd = data;
s_commandId = SSD_COMMAND_NONE;
break;
default: break;
}
break;
default:
s_commandId = SSD_COMMAND_NONE;
break;
}
}
static void sdl_ssd1331_data(uint8_t data)
{
int y = s_topToBottom ? s_activePage : (sdl_ssd1331x8.height - s_activePage - 1);
int x = s_leftToRight ? s_activeColumn: (sdl_ssd1331x8.width - s_activeColumn - 1);
static uint8_t firstByte = 1; /// SSD1331
static uint8_t dataFirst = 0x00; /// SSD1331
if (firstByte && s_16bitmode)
{
dataFirst = data;
firstByte = 0;
return;
}
firstByte = 1;
if ( s_16bitmode )
{
sdl_put_pixel(x, y, (dataFirst<<8) | data);
}
else
{
sdl_put_pixel(x, y, data);
}
if (s_verticalMode)
{
s_activePage++;
if (s_activePage > s_pageEnd)
{
s_activePage = s_pageStart;
s_activeColumn++;
if (s_activeColumn > s_columnEnd)
{
s_activeColumn = s_columnStart;
}
}
}
else
{
s_activeColumn++;
if (s_activeColumn > s_columnEnd)
{
s_activeColumn = s_columnStart;
s_activePage++;
if (s_activePage > s_pageEnd)
{
s_activePage = s_pageStart;
}
}
}
}
sdl_oled_info sdl_ssd1331x8 =
{
.width = 96,
.height = 64,
.bpp = 8,
.pixfmt = SDL_PIXELFORMAT_RGB332,
.dataMode = SDMS_AUTO,
.detect = sdl_ssd1331_detect_x8,
.run_cmd = sdl_ssd1331_commands,
.run_data = sdl_ssd1331_data,
.reset = sdl_ssd1331_reset,
};
sdl_oled_info sdl_ssd1331x16 =
{
.width = 96,
.height = 64,
.bpp = 16,
.pixfmt = SDL_PIXELFORMAT_RGB565,
.dataMode = SDMS_AUTO,
.detect = sdl_ssd1331_detect_x16,
.run_cmd = sdl_ssd1331_commands,
.run_data = sdl_ssd1331_data,
.reset = sdl_ssd1331_reset,
};

View File

@@ -0,0 +1,43 @@
/*
MIT License
Copyright (c) 2018-2019, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef _SDL_SSD1331_H_
#define _SDL_SSD1331_H_
#include <stdint.h>
#include "sdl_oled_basic.h"
#ifdef __cplusplus
extern "C" {
#endif
extern sdl_oled_info sdl_ssd1331x8;
extern sdl_oled_info sdl_ssd1331x16;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,160 @@
/*
MIT License
Copyright (c) 2018-2019, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "sdl_ssd1351.h"
#include "sdl_oled_basic.h"
#include "sdl_graphics.h"
#include "sdl_core.h"
static int s_activeColumn = 0;
static int s_activePage = 0;
static int s_columnStart = 0;
static int s_columnEnd = 127;
static int s_pageStart = 0;
static int s_pageEnd = 7;
static uint8_t detected = 0;
static int sdl_ssd1351_detect(uint8_t data)
{
if (detected)
{
return 1;
}
detected = (data == SDL_LCD_SSD1351);
return 0;
}
static uint8_t s_verticalMode = 0;
static void sdl_ssd1351_commands(uint8_t data)
{
switch (s_commandId)
{
case 0xA0:
if (s_cmdArgIndex == 0)
{
s_verticalMode = data & 0x01;
s_commandId = SSD_COMMAND_NONE;
}
break;
case 0x15:
switch (s_cmdArgIndex)
{
case 0:
s_columnStart = data;
s_activeColumn = data;
break;
case 1:
s_columnEnd = data;
s_commandId = SSD_COMMAND_NONE;
break;
default: break;
}
break;
case 0x75:
switch (s_cmdArgIndex)
{
case 0:
s_activePage = data;
s_pageStart = data;
break;
case 1:
s_pageEnd = data;
s_commandId = SSD_COMMAND_NONE;
break;
default: break;
}
break;
case 0x5C:
sdl_set_data_mode( SDM_WRITE_DATA );
s_commandId = SSD_COMMAND_NONE;
break;
case 0xB4:
if ( s_cmdArgIndex == 2)
{
s_commandId = SSD_COMMAND_NONE;
}
break;
default:
s_commandId = SSD_COMMAND_NONE;
break;
}
}
void sdl_ssd1351_data(uint8_t data)
{
int y = s_activePage;
int x = s_activeColumn;
static uint8_t firstByte = 1; /// SSD1351
static uint8_t dataFirst = 0x00; /// SSD1351
if (firstByte)
{
dataFirst = data;
firstByte = 0;
return;
}
firstByte = 1;
sdl_put_pixel(x, y, (dataFirst<<8) | data);
if (s_verticalMode)
{
s_activePage++;
if (s_activePage > s_pageEnd)
{
s_activePage = s_pageStart;
s_activeColumn++;
if (s_activeColumn > s_columnEnd)
{
s_activeColumn = s_columnStart;
}
}
}
else
{
s_activeColumn++;
if (s_activeColumn > s_columnEnd)
{
s_activeColumn = s_columnStart;
s_activePage++;
if (s_activePage > s_pageEnd)
{
s_activePage = s_pageStart;
}
}
}
}
sdl_oled_info sdl_ssd1351 =
{
.width = 128,
.height = 128,
.bpp = 16,
.pixfmt = SDL_PIXELFORMAT_RGB565,
.dataMode = SDMS_CONTROLLER,
.detect = sdl_ssd1351_detect,
.run_cmd = sdl_ssd1351_commands,
.run_data = sdl_ssd1351_data,
};

View File

@@ -0,0 +1,42 @@
/*
MIT License
Copyright (c) 2018, Alexey Dynda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef _SDL_SSD1351_H_
#define _SDL_SSD1351_H_
#include <stdint.h>
#include "sdl_oled_basic.h"
#ifdef __cplusplus
extern "C" {
#endif
extern sdl_oled_info sdl_ssd1351;
#ifdef __cplusplus
}
#endif
#endif