Skip to content

Commit 7ca9d06

Browse files
committed
added copyright message, added scrolling and dimming functions
1 parent e5d34e9 commit 7ca9d06

3 files changed

Lines changed: 218 additions & 72 deletions

File tree

test/oled-mini/oled-mini.c

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
/*
2+
* This is an example for using the i2c library with a monochrome OLED
3+
* display based on SSD1306 drivers.
4+
*
5+
* The display has 128x64 pixel and uses only SCL and SDA for communication,
6+
* there is no reset pin.
7+
*
8+
* The framebuffer needs to be kept in RAM as reading the display is not
9+
* supported by the driver chips. Since the STM8S103F3 has only 1kB RAM
10+
* total, we will see the stack contents in the lower part of the display
11+
* as a wild bit pattern. Using drawPixel() on this memory would mess up
12+
* the stack contents and would result in an immediate crash. So don't
13+
* use the lower lines on low memory devices!
14+
*
15+
* This code is adopted from the Adafruit example code contained in the
16+
* Adafruit_SSD1306 library.
17+
*
18+
* modified 2017 by Michael Mayer
19+
*/
20+
121
/*********************************************************************
222
This is an example for our Monochrome OLEDs based on SSD1306 drivers
323
@@ -18,41 +38,47 @@ All text above, and the splash screen must be included in any redistribution
1838

1939
#include "ssd1306.h"
2040

21-
#define OLED_RESET 6
41+
#define OLED_RESET -1
2242

2343
#if (SSD1306_LCDHEIGHT != 64)
2444
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
2545
#endif
2646

47+
// empty IRQ handler just to keep the linker happy as we are not using the
48+
// Hardware_Serial library
2749
void UART1_RX_IRQHandler(void) __interrupt(ITC_IRQ_UART1_RX){}
2850
void UART1_TX_IRQHandler(void) __interrupt(ITC_IRQ_UART1_TX){}
2951

30-
void setup() {
31-
// Serial_begin(9600);
3252

33-
Adafruit_SSD1306_Adafruit_SSD1306(OLED_RESET);
53+
void setup()
54+
{
55+
display_init(OLED_RESET);
3456

35-
// display_init(OLED_RESET);
36-
// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
37-
Adafruit_SSD1306_begin(SSD1306_SWITCHCAPVCC, 0x3C,1); // initialize with the I2C addr 0x3D (for the 128x64)
38-
// init done
57+
// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
58+
display_begin(SSD1306_SWITCHCAPVCC, 0x3C,0); // initialize with the I2C addr 0x3C
59+
// init done
3960

40-
// Show image buffer on the display hardware.
41-
// Since the buffer is intialized with an Adafruit splashscreen
42-
// internally, this will display the splashscreen.
43-
// Adafruit_SSD1306_display();
61+
// Show image buffer on the display hardware.
62+
// Since the buffer is intialized with an Adafruit splashscreen
63+
// internally, this will display the splashscreen.
64+
// display_display();
4465
}
4566

4667

4768
void loop()
4869
{
4970
uint8_t x,y;
5071

51-
Adafruit_SSD1306_display();
52-
delay (100);
72+
display_display(); // show the splash screen
73+
//display_startscrollright(4,6);
74+
75+
delay (1000);
76+
77+
// draw some dots in an 8x8 pattern
5378
for (x=0; x<WIDTH; x+=8)
5479
{
55-
for (y=0; y<HEIGHT; y+=8)
80+
// for (y=0; y<HEIGHT; y+=8)
81+
for (y=0; y<56; y+=8) // don't mess with the stack!
5682
{
5783
drawPixel(x,y,INVERSE);
5884
}

test/oled-mini/ssd1306.c

Lines changed: 161 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,51 @@
1+
/*
2+
* This is an example for using the i2c library with a monochrome OLED
3+
* display based on SSD1306 drivers.
4+
*
5+
* The display has 128x64 pixel and uses only SCL and SDA for communication,
6+
* there is no reset pin.
7+
*
8+
* The framebuffer needs to be kept in RAM as reading the display is not
9+
* supported by the driver chips. Since the STM8S103F3 has only 1kB RAM
10+
* total, we will see the stack contents in the lower part of the display
11+
* as a wild bit pattern. Using drawPixel() on this memory would mess up
12+
* the stack contents and would result in an immediate crash. So don't
13+
* use the lower lines on low memory devices!
14+
*
15+
* This code is adopted from the Adafruit example code contained in the
16+
* Adafruit_SSD1306 library.
17+
*
18+
* modified 2017 by Michael Mayer
19+
*/
20+
21+
22+
/*
23+
* This is an example for using the i2c library with a monochrome OLED
24+
* display based on SSD1306 drivers.
25+
*
26+
* The display has 128x64 pixel and uses only SCL and SDA for communication,
27+
* there is no reset pin.
28+
*
29+
* The framebuffer needs to be kept in RAM as reading the display is not
30+
* supported by the driver chips. Since the STM8S103F3 has only 1kB RAM
31+
* total, we will see the stack contents in the lower part of the display
32+
* as a wild bit pattern. Using drawPixel() on this memory would mess up
33+
* the stack contents and would result in an immediate crash. So don't
34+
* use the lower lines on low memory devices!
35+
*
36+
* This code is a stripped down version of the Adafruit_SSD1306 library
37+
* adoped for use with the STM8S.
38+
*
39+
* This library supports only I2C displays using the I2C library, all SPI
40+
* related code is removed.
41+
*
42+
* All dependencies on the Adafruit_GFX library are removed. This simple
43+
* code only supports pixel based operations using drawPixel().
44+
*
45+
* 2017 modified for the STM8S by Michael Mayer
46+
*/
47+
48+
149
/*********************************************************************
250
This is a library for our Monochrome OLEDs based on SSD1306 drivers
351
@@ -16,10 +64,6 @@ BSD license, check license.txt for more information
1664
All text above, and the splash screen below must be included in any redistribution
1765
*********************************************************************/
1866

19-
// #include <avr/pgmspace.h>
20-
// #include <util/delay.h>
21-
22-
//#include <stdlib.h>
2367
#define USE_WIRE 0
2468

2569
#if USE_WIRE
@@ -123,8 +167,11 @@ static uint8_t buffer[SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8] = {
123167
#define rotation (0)
124168
#define getRotation() (0)
125169

170+
static void ssd1306_command(uint8_t c);
171+
172+
126173
// the most basic function, set a single pixel
127-
void drawPixel(int16_t x, int16_t y, uint16_t color) {
174+
void drawPixel(int16_t x, int16_t y, uint8_t color) {
128175
// if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
129176
// return;
130177

@@ -155,25 +202,20 @@ void drawPixel(int16_t x, int16_t y, uint16_t color) {
155202
}
156203

157204
// initializer for I2C - we only indicate the reset pin!
158-
void Adafruit_SSD1306_Adafruit_SSD1306(int8_t reset) {
205+
void display_init(int8_t reset) {
159206
sclk = dc = cs = sid = -1;
160207
rst = reset;
161208
}
162209

163210
#if 1
164-
void Adafruit_SSD1306_begin(uint8_t vccstate, uint8_t i2caddr, bool reset) {
211+
void display_begin(uint8_t vccstate, uint8_t i2caddr, bool reset) {
165212
_vccstate = vccstate;
166213
_i2caddr = i2caddr;
167214

168215
// set pin directions
169216
{
170217
// I2C Init
171218
i2c_begin();
172-
#ifdef __SAM3X8E__
173-
// Force 400 KHz I2C, rawr! (Uses pins 20, 21 for SDA, SCL)
174-
TWI1->TWI_CWGR = 0;
175-
TWI1->TWI_CWGR = ((VARIANT_MCK / (2 * 400000)) - 4) * 0x101;
176-
#endif
177219
}
178220
if ((reset) && (rst >= 0)) {
179221
// Setup reset pin direction (used by both SPI and I2C)
@@ -253,8 +295,15 @@ void Adafruit_SSD1306_begin(uint8_t vccstate, uint8_t i2caddr, bool reset) {
253295
}
254296
#endif
255297

256-
#if 1
257-
void ssd1306_command(uint8_t c) {
298+
void display_invertDisplay(uint8_t i) {
299+
if (i) {
300+
ssd1306_command(SSD1306_INVERTDISPLAY);
301+
} else {
302+
ssd1306_command(SSD1306_NORMALDISPLAY);
303+
}
304+
}
305+
306+
static void ssd1306_command(uint8_t c) {
258307
{
259308
// I2C
260309
#if USE_WIRE
@@ -268,10 +317,100 @@ void ssd1306_command(uint8_t c) {
268317
#endif
269318
}
270319
}
271-
#endif
272320

273-
#if 1
274-
void Adafruit_SSD1306_display(void) {
321+
322+
323+
// startscrollright
324+
// Activate a right handed scroll for rows start through stop
325+
// Hint, the display is 16 rows tall. To scroll the whole display, run:
326+
// display.scrollright(0x00, 0x0F)
327+
void display_startscrollright(uint8_t start, uint8_t stop){
328+
ssd1306_command(SSD1306_RIGHT_HORIZONTAL_SCROLL);
329+
ssd1306_command(0X00);
330+
ssd1306_command(start);
331+
ssd1306_command(0X00);
332+
ssd1306_command(stop);
333+
ssd1306_command(0X00);
334+
ssd1306_command(0XFF);
335+
ssd1306_command(SSD1306_ACTIVATE_SCROLL);
336+
}
337+
338+
// startscrollleft
339+
// Activate a right handed scroll for rows start through stop
340+
// Hint, the display is 16 rows tall. To scroll the whole display, run:
341+
// display.scrollright(0x00, 0x0F)
342+
void display_startscrollleft(uint8_t start, uint8_t stop){
343+
ssd1306_command(SSD1306_LEFT_HORIZONTAL_SCROLL);
344+
ssd1306_command(0X00);
345+
ssd1306_command(start);
346+
ssd1306_command(0X00);
347+
ssd1306_command(stop);
348+
ssd1306_command(0X00);
349+
ssd1306_command(0XFF);
350+
ssd1306_command(SSD1306_ACTIVATE_SCROLL);
351+
}
352+
353+
// startscrolldiagright
354+
// Activate a diagonal scroll for rows start through stop
355+
// Hint, the display is 16 rows tall. To scroll the whole display, run:
356+
// display.scrollright(0x00, 0x0F)
357+
void display_startscrolldiagright(uint8_t start, uint8_t stop){
358+
ssd1306_command(SSD1306_SET_VERTICAL_SCROLL_AREA);
359+
ssd1306_command(0X00);
360+
ssd1306_command(SSD1306_LCDHEIGHT);
361+
ssd1306_command(SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL);
362+
ssd1306_command(0X00);
363+
ssd1306_command(start);
364+
ssd1306_command(0X00);
365+
ssd1306_command(stop);
366+
ssd1306_command(0X01);
367+
ssd1306_command(SSD1306_ACTIVATE_SCROLL);
368+
}
369+
370+
// startscrolldiagleft
371+
// Activate a diagonal scroll for rows start through stop
372+
// Hint, the display is 16 rows tall. To scroll the whole display, run:
373+
// display.scrollright(0x00, 0x0F)
374+
void display_startscrolldiagleft(uint8_t start, uint8_t stop){
375+
ssd1306_command(SSD1306_SET_VERTICAL_SCROLL_AREA);
376+
ssd1306_command(0X00);
377+
ssd1306_command(SSD1306_LCDHEIGHT);
378+
ssd1306_command(SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL);
379+
ssd1306_command(0X00);
380+
ssd1306_command(start);
381+
ssd1306_command(0X00);
382+
ssd1306_command(stop);
383+
ssd1306_command(0X01);
384+
ssd1306_command(SSD1306_ACTIVATE_SCROLL);
385+
}
386+
387+
void display_stopscroll(void){
388+
ssd1306_command(SSD1306_DEACTIVATE_SCROLL);
389+
}
390+
391+
// Dim the display
392+
// dim = true: display is dimmed
393+
// dim = false: display is normal
394+
void display_dim(boolean dim) {
395+
uint8_t contrast;
396+
397+
if (dim) {
398+
contrast = 0; // Dimmed display
399+
} else {
400+
if (_vccstate == SSD1306_EXTERNALVCC) {
401+
contrast = 0x9F;
402+
} else {
403+
contrast = 0xCF;
404+
}
405+
}
406+
// the range of contrast to too small to be really useful
407+
// it is useful to dim the display
408+
ssd1306_command(SSD1306_SETCONTRAST);
409+
ssd1306_command(contrast);
410+
}
411+
412+
413+
void display_display(void) {
275414
ssd1306_command(SSD1306_COLUMNADDR);
276415
ssd1306_command(0); // Column start address (0 = reset)
277416
ssd1306_command(SSD1306_LCDWIDTH-1); // Column end address (127 = reset)
@@ -289,15 +428,6 @@ void Adafruit_SSD1306_display(void) {
289428
#endif
290429

291430
{
292-
// save I2C bitrate
293-
#ifdef TWBR
294-
uint8_t twbrbackup = TWBR;
295-
TWBR = 12; // upgrade to 400KHz!
296-
#endif
297-
298-
//Serial.println(TWBR, DEC);
299-
//Serial.println(TWSR & 0x3, DEC);
300-
301431
// I2C
302432
for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) {
303433
// send a bunch of data in one xmission
@@ -315,9 +445,10 @@ void Adafruit_SSD1306_display(void) {
315445
i+=15;
316446
#endif
317447
}
318-
#ifdef TWBR
319-
TWBR = twbrbackup;
320-
#endif
321448
}
322449
}
323-
#endif
450+
451+
// clear everything
452+
void display_clearDisplay(void) {
453+
memset(buffer, 0, (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8));
454+
}

0 commit comments

Comments
 (0)