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/*********************************************************************
250This is a library for our Monochrome OLEDs based on SSD1306 drivers
351
@@ -16,10 +64,6 @@ BSD license, check license.txt for more information
1664All 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