first time code commit
This commit is contained in:
parent
591e6e8625
commit
e672704de6
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*.o
|
||||||
|
ssd1306_bin
|
15
Makefile
Normal file
15
Makefile
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
CC=gcc
|
||||||
|
CFLAGS=-I ./
|
||||||
|
LDFLAGS=-static
|
||||||
|
OBJS=main.o ssd1306.o linux_i2c.o
|
||||||
|
BIN=ssd1306_bin
|
||||||
|
|
||||||
|
%.o:%.c
|
||||||
|
$(CC) -c -o $@ $< $(CFLAGS)
|
||||||
|
|
||||||
|
$(BIN):$(OBJS)
|
||||||
|
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f ./*.o $(BIN)
|
||||||
|
|
118
Readme.md
Normal file
118
Readme.md
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
# OLED SSD1306 Linux driver
|
||||||
|
This is plain c code using linux I2C device node (/dev/i2c-X X for 0,1,2,3...).
|
||||||
|
Please make sure the linux has run "modprobe i2c-dev".
|
||||||
|
128x64 and 128x32 are supporting and using I2C interface ONLY
|
||||||
|
## Files
|
||||||
|
**linux_i2c.c** source code for i2c control in linux device node.
|
||||||
|
**linux_i2c.h** header file for i2c control in linux.
|
||||||
|
**ssd1306.c** i2c protocol functions to control oled SSD1306.
|
||||||
|
**ssd1306.h** header file for i2c protocol functions and defined commands in SSD1306.
|
||||||
|
**font.h** font header file define 5x7 small font and 8x8 normal font. ascii value from 0x20(SPACE) to 0x7e(~).
|
||||||
|
**main.c** main file to take params and control oled SSD1306.
|
||||||
|
**Makefile** plain Makefile to build the source code. It works in raspberry pi.
|
||||||
|
**Readme.md** this readme file.
|
||||||
|
## How to compile
|
||||||
|
Require make and gcc. If you use cross compile, please self define $(CC).
|
||||||
|
Type "make" to build binary "ssd1306_bin".
|
||||||
|
Type "make clean" to clean the project.
|
||||||
|
## How to use
|
||||||
|
- always init oled module ONCE when power up.
|
||||||
|
- set the device node address EVERYTIME if not using default value /dev/i2c-0
|
||||||
|
- the init oled module always reset XY cursor to (0,0)
|
||||||
|
- all params can set together
|
||||||
|
- clear screen if new text need to write, otherwise wording overlapping happened
|
||||||
|
- resolution value stored in /tmp/.ssd1306_oled_type with format like "128x64" or "128x32" or "64x48"
|
||||||
|
- always do display rotation first and then filling text. otherwise the text cause mirror
|
||||||
|
- make sure the XY cursor setting in correct location before printing text
|
||||||
|
### Params
|
||||||
|
```sh
|
||||||
|
-I init oled (128x32 or 128x64 or 64x48)
|
||||||
|
-c clear (line number or all)
|
||||||
|
-d 0/display off 1/display on
|
||||||
|
-f 0/small font 5x7 1/normal font 8x8 (default small font)
|
||||||
|
-h help message
|
||||||
|
-i 0/normal oled 1/invert oled
|
||||||
|
-l put your line to display
|
||||||
|
-m put your strings to oled
|
||||||
|
-n I2C device node address (0,1,2..., default 0)
|
||||||
|
-r 0/normal 180/rotate
|
||||||
|
-x x position
|
||||||
|
-y y position
|
||||||
|
```
|
||||||
|
## Example
|
||||||
|
### init the OLED once
|
||||||
|
- resolution 128x64
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -I 128x64
|
||||||
|
```
|
||||||
|
- resolution 128x32
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -I 128x32
|
||||||
|
```
|
||||||
|
- resolution 64x48
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -I 64x48
|
||||||
|
```
|
||||||
|
### clear display
|
||||||
|
- clear 1st line
|
||||||
|
```sh
|
||||||
|
./ssd1306_bin -c 0
|
||||||
|
```
|
||||||
|
- clear 2nd line
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -c 1
|
||||||
|
```
|
||||||
|
- clear 4th line
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -c 3
|
||||||
|
```
|
||||||
|
- clear whole screen
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -c
|
||||||
|
```
|
||||||
|
### display on/off
|
||||||
|
- turn off display
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -d 0
|
||||||
|
```
|
||||||
|
- turn on display
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -d 1
|
||||||
|
```
|
||||||
|
### inverting display
|
||||||
|
- normal oled (0 is off, 1 is on)
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -i 0
|
||||||
|
```
|
||||||
|
- invert oled (0 is on, 1 is off)
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -i 1
|
||||||
|
```
|
||||||
|
### print words
|
||||||
|
- write line "Hello World"
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -l "Hello World"
|
||||||
|
```
|
||||||
|
- write message "alpha\nbravo\ncharlie\ndelta" (please place \n for next line)
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -m "alpha\nbravo\ncharlie\ndelta"
|
||||||
|
```
|
||||||
|
### I2C device address (default is /dev/i2c-0)
|
||||||
|
- using /dev/i2c-1
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -n 1
|
||||||
|
```
|
||||||
|
### rotate display
|
||||||
|
- normal orientation
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -r 0
|
||||||
|
```
|
||||||
|
- turn 180 orientation
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -r 180
|
||||||
|
```
|
||||||
|
### set cursor location
|
||||||
|
- set XY cursor 8,1(x is column, 8 columns skipping, y is row, 2nd line)
|
||||||
|
```sh
|
||||||
|
$ ./ssd1306_bin -x 8 -y 1
|
||||||
|
```
|
213
font.h
Normal file
213
font.h
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
#ifndef __FONT_H
|
||||||
|
#define __FONT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
const uint8_t font5x7[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, // SPACE
|
||||||
|
0x00, 0x00, 0x5F, 0x00, 0x00, // !
|
||||||
|
0x00, 0x03, 0x00, 0x03, 0x00, // "
|
||||||
|
0x14, 0x3E, 0x14, 0x3E, 0x14, // #
|
||||||
|
0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
|
||||||
|
0x43, 0x33, 0x08, 0x66, 0x61, // %
|
||||||
|
0x36, 0x49, 0x55, 0x22, 0x50, // &
|
||||||
|
0x00, 0x05, 0x03, 0x00, 0x00, // '
|
||||||
|
0x00, 0x1C, 0x22, 0x41, 0x00, // (
|
||||||
|
0x00, 0x41, 0x22, 0x1C, 0x00, // )
|
||||||
|
0x14, 0x08, 0x3E, 0x08, 0x14, // *
|
||||||
|
0x08, 0x08, 0x3E, 0x08, 0x08, // +
|
||||||
|
0x00, 0x50, 0x30, 0x00, 0x00, // ,
|
||||||
|
0x08, 0x08, 0x08, 0x08, 0x08, // -
|
||||||
|
0x00, 0x60, 0x60, 0x00, 0x00, // .
|
||||||
|
0x20, 0x10, 0x08, 0x04, 0x02, // /
|
||||||
|
|
||||||
|
0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
|
||||||
|
0x00, 0x04, 0x02, 0x7F, 0x00, // 1
|
||||||
|
0x42, 0x61, 0x51, 0x49, 0x46, // 2
|
||||||
|
0x22, 0x41, 0x49, 0x49, 0x36, // 3
|
||||||
|
0x18, 0x14, 0x12, 0x7F, 0x10, // 4
|
||||||
|
0x27, 0x45, 0x45, 0x45, 0x39, // 5
|
||||||
|
0x3E, 0x49, 0x49, 0x49, 0x32, // 6
|
||||||
|
0x01, 0x01, 0x71, 0x09, 0x07, // 7
|
||||||
|
0x36, 0x49, 0x49, 0x49, 0x36, // 8
|
||||||
|
0x26, 0x49, 0x49, 0x49, 0x3E, // 9
|
||||||
|
0x00, 0x36, 0x36, 0x00, 0x00, // :
|
||||||
|
0x00, 0x56, 0x36, 0x00, 0x00, // ;
|
||||||
|
0x08, 0x14, 0x22, 0x41, 0x00, // <
|
||||||
|
0x14, 0x14, 0x14, 0x14, 0x14, // =
|
||||||
|
0x00, 0x41, 0x22, 0x14, 0x08, // >
|
||||||
|
0x02, 0x01, 0x51, 0x09, 0x06, // ?
|
||||||
|
|
||||||
|
0x3E, 0x41, 0x59, 0x55, 0x5E, // @
|
||||||
|
0x7E, 0x09, 0x09, 0x09, 0x7E, // A
|
||||||
|
0x7F, 0x49, 0x49, 0x49, 0x36, // B
|
||||||
|
0x3E, 0x41, 0x41, 0x41, 0x22, // C
|
||||||
|
0x7F, 0x41, 0x41, 0x41, 0x3E, // D
|
||||||
|
0x7F, 0x49, 0x49, 0x49, 0x41, // E
|
||||||
|
0x7F, 0x09, 0x09, 0x09, 0x01, // F
|
||||||
|
0x3E, 0x41, 0x41, 0x49, 0x3A, // G
|
||||||
|
0x7F, 0x08, 0x08, 0x08, 0x7F, // H
|
||||||
|
0x00, 0x41, 0x7F, 0x41, 0x00, // I
|
||||||
|
0x30, 0x40, 0x40, 0x40, 0x3F, // J
|
||||||
|
0x7F, 0x08, 0x14, 0x22, 0x41, // K
|
||||||
|
0x7F, 0x40, 0x40, 0x40, 0x40, // L
|
||||||
|
0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
|
||||||
|
0x7F, 0x02, 0x04, 0x08, 0x7F, // N
|
||||||
|
0x3E, 0x41, 0x41, 0x41, 0x3E, // O
|
||||||
|
|
||||||
|
0x7F, 0x09, 0x09, 0x09, 0x06, // P
|
||||||
|
0x1E, 0x21, 0x21, 0x21, 0x5E, // Q
|
||||||
|
0x7F, 0x09, 0x09, 0x09, 0x76, // R
|
||||||
|
0x26, 0x49, 0x49, 0x49, 0x32, // S
|
||||||
|
0x01, 0x01, 0x7F, 0x01, 0x01, // T
|
||||||
|
0x3F, 0x40, 0x40, 0x40, 0x3F, // U
|
||||||
|
0x1F, 0x20, 0x40, 0x20, 0x1F, // V
|
||||||
|
0x7F, 0x20, 0x10, 0x20, 0x7F, // W
|
||||||
|
0x41, 0x22, 0x1C, 0x22, 0x41, // X
|
||||||
|
0x07, 0x08, 0x70, 0x08, 0x07, // Y
|
||||||
|
0x61, 0x51, 0x49, 0x45, 0x43, // Z
|
||||||
|
0x00, 0x7F, 0x41, 0x00, 0x00, // [
|
||||||
|
0x02, 0x04, 0x08, 0x10, 0x20, // backslash
|
||||||
|
0x00, 0x00, 0x41, 0x7F, 0x00, // ]
|
||||||
|
0x04, 0x02, 0x01, 0x02, 0x04, // ^
|
||||||
|
0x40, 0x40, 0x40, 0x40, 0x40, // _
|
||||||
|
|
||||||
|
0x00, 0x01, 0x02, 0x04, 0x00, // `
|
||||||
|
0x20, 0x54, 0x54, 0x54, 0x78, // a
|
||||||
|
0x7F, 0x44, 0x44, 0x44, 0x38, // b
|
||||||
|
0x38, 0x44, 0x44, 0x44, 0x44, // c
|
||||||
|
0x38, 0x44, 0x44, 0x44, 0x7F, // d
|
||||||
|
0x38, 0x54, 0x54, 0x54, 0x18, // e
|
||||||
|
0x04, 0x04, 0x7E, 0x05, 0x05, // f
|
||||||
|
0x08, 0x54, 0x54, 0x54, 0x3C, // g
|
||||||
|
0x7F, 0x08, 0x04, 0x04, 0x78, // h
|
||||||
|
0x00, 0x44, 0x7D, 0x40, 0x00, // i
|
||||||
|
0x20, 0x40, 0x44, 0x3D, 0x00, // j
|
||||||
|
0x7F, 0x10, 0x28, 0x44, 0x00, // k
|
||||||
|
0x00, 0x41, 0x7F, 0x40, 0x00, // l
|
||||||
|
0x7C, 0x04, 0x78, 0x04, 0x78, // m
|
||||||
|
0x7C, 0x08, 0x04, 0x04, 0x78, // n
|
||||||
|
0x38, 0x44, 0x44, 0x44, 0x38, // o
|
||||||
|
|
||||||
|
0x7C, 0x14, 0x14, 0x14, 0x08, // p
|
||||||
|
0x08, 0x14, 0x14, 0x14, 0x7C, // q
|
||||||
|
0x00, 0x7C, 0x08, 0x04, 0x04, // r
|
||||||
|
0x48, 0x54, 0x54, 0x54, 0x20, // s
|
||||||
|
0x04, 0x04, 0x3F, 0x44, 0x44, // t
|
||||||
|
0x3C, 0x40, 0x40, 0x20, 0x7C, // u
|
||||||
|
0x1C, 0x20, 0x40, 0x20, 0x1C, // v
|
||||||
|
0x3C, 0x40, 0x30, 0x40, 0x3C, // w
|
||||||
|
0x44, 0x28, 0x10, 0x28, 0x44, // x
|
||||||
|
0x0C, 0x50, 0x50, 0x50, 0x3C, // y
|
||||||
|
0x44, 0x64, 0x54, 0x4C, 0x44, // z
|
||||||
|
0x00, 0x08, 0x36, 0x41, 0x41, // {
|
||||||
|
0x00, 0x00, 0x7F, 0x00, 0x00, // |
|
||||||
|
0x41, 0x41, 0x36, 0x08, 0x00, // }
|
||||||
|
0x02, 0x01, 0x02, 0x04, 0x02 // ~
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t font8x8[] = {
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // <space>
|
||||||
|
0x00,0x00,0x00,0x00,0x5F,0x00,0x00,0x00, // !
|
||||||
|
0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x00, // "
|
||||||
|
0x00,0x24,0x7E,0x24,0x24,0x7E,0x24,0x00, // #
|
||||||
|
0x00,0x2E,0x2A,0x7F,0x2A,0x3A,0x00,0x00, // $
|
||||||
|
0x00,0x46,0x26,0x10,0x08,0x64,0x62,0x00, // %
|
||||||
|
0x00,0x20,0x54,0x4A,0x54,0x20,0x50,0x00, // &
|
||||||
|
0x00,0x00,0x00,0x04,0x02,0x00,0x00,0x00, // '
|
||||||
|
0x00,0x00,0x00,0x3C,0x42,0x00,0x00,0x00, // (
|
||||||
|
0x00,0x00,0x00,0x42,0x3C,0x00,0x00,0x00, // )
|
||||||
|
0x00,0x10,0x54,0x38,0x54,0x10,0x00,0x00, // *
|
||||||
|
0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00, // +
|
||||||
|
0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00, // ,
|
||||||
|
0x00,0x10,0x10,0x10,0x10,0x10,0x00,0x00, // -
|
||||||
|
0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, // .
|
||||||
|
0x00,0x40,0x20,0x10,0x08,0x04,0x00,0x00, // /
|
||||||
|
|
||||||
|
0x3C,0x62,0x52,0x4A,0x46,0x3C,0x00,0x00, // 0
|
||||||
|
0x44,0x42,0x7E,0x40,0x40,0x00,0x00,0x00, // 1
|
||||||
|
0x64,0x52,0x52,0x52,0x52,0x4C,0x00,0x00, // 2
|
||||||
|
0x24,0x42,0x42,0x4A,0x4A,0x34,0x00,0x00, // 3
|
||||||
|
0x30,0x28,0x24,0x7E,0x20,0x20,0x00,0x00, // 4
|
||||||
|
0x2E,0x4A,0x4A,0x4A,0x4A,0x32,0x00,0x00, // 5
|
||||||
|
0x3C,0x4A,0x4A,0x4A,0x4A,0x30,0x00,0x00, // 6
|
||||||
|
0x02,0x02,0x62,0x12,0x0A,0x06,0x00,0x00, // 7
|
||||||
|
0x34,0x4A,0x4A,0x4A,0x4A,0x34,0x00,0x00, // 8
|
||||||
|
0x0C,0x52,0x52,0x52,0x52,0x3C,0x00,0x00, // 9
|
||||||
|
0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00, // :
|
||||||
|
0x00,0x00,0x80,0x64,0x00,0x00,0x00,0x00, // ;
|
||||||
|
0x00,0x00,0x10,0x28,0x44,0x00,0x00,0x00, // <
|
||||||
|
0x00,0x28,0x28,0x28,0x28,0x28,0x00,0x00, // =
|
||||||
|
0x00,0x00,0x44,0x28,0x10,0x00,0x00,0x00, // >
|
||||||
|
0x00,0x04,0x02,0x02,0x52,0x0A,0x04,0x00, // ?
|
||||||
|
|
||||||
|
0x00,0x3C,0x42,0x5A,0x56,0x5A,0x1C,0x00, // @
|
||||||
|
0x7C,0x12,0x12,0x12,0x12,0x7C,0x00,0x00, // A
|
||||||
|
0x7E,0x4A,0x4A,0x4A,0x4A,0x34,0x00,0x00, // B
|
||||||
|
0x3C,0x42,0x42,0x42,0x42,0x24,0x00,0x00, // C
|
||||||
|
0x7E,0x42,0x42,0x42,0x24,0x18,0x00,0x00, // D
|
||||||
|
0x7E,0x4A,0x4A,0x4A,0x4A,0x42,0x00,0x00, // E
|
||||||
|
0x7E,0x0A,0x0A,0x0A,0x0A,0x02,0x00,0x00, // F
|
||||||
|
0x3C,0x42,0x42,0x52,0x52,0x34,0x00,0x00, // G
|
||||||
|
0x7E,0x08,0x08,0x08,0x08,0x7E,0x00,0x00, // H
|
||||||
|
0x00,0x42,0x42,0x7E,0x42,0x42,0x00,0x00, // I
|
||||||
|
0x30,0x40,0x40,0x40,0x40,0x3E,0x00,0x00, // J
|
||||||
|
0x7E,0x08,0x08,0x14,0x22,0x40,0x00,0x00, // K
|
||||||
|
0x7E,0x40,0x40,0x40,0x40,0x40,0x00,0x00, // L
|
||||||
|
0x7E,0x04,0x08,0x08,0x04,0x7E,0x00,0x00, // M
|
||||||
|
0x7E,0x04,0x08,0x10,0x20,0x7E,0x00,0x00, // N
|
||||||
|
0x3C,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, // O
|
||||||
|
|
||||||
|
0x7E,0x12,0x12,0x12,0x12,0x0C,0x00,0x00, // P
|
||||||
|
0x3C,0x42,0x52,0x62,0x42,0x3C,0x00,0x00, // Q
|
||||||
|
0x7E,0x12,0x12,0x12,0x32,0x4C,0x00,0x00, // R
|
||||||
|
0x24,0x4A,0x4A,0x4A,0x4A,0x30,0x00,0x00, // S
|
||||||
|
0x02,0x02,0x02,0x7E,0x02,0x02,0x02,0x00, // T
|
||||||
|
0x3E,0x40,0x40,0x40,0x40,0x3E,0x00,0x00, // U
|
||||||
|
0x1E,0x20,0x40,0x40,0x20,0x1E,0x00,0x00, // V
|
||||||
|
0x3E,0x40,0x20,0x20,0x40,0x3E,0x00,0x00, // W
|
||||||
|
0x42,0x24,0x18,0x18,0x24,0x42,0x00,0x00, // X
|
||||||
|
0x02,0x04,0x08,0x70,0x08,0x04,0x02,0x00, // Y
|
||||||
|
0x42,0x62,0x52,0x4A,0x46,0x42,0x00,0x00, // Z
|
||||||
|
0x00,0x00,0x7E,0x42,0x42,0x00,0x00,0x00, // [
|
||||||
|
0x00,0x04,0x08,0x10,0x20,0x40,0x00,0x00, // <backslash>
|
||||||
|
0x00,0x00,0x42,0x42,0x7E,0x00,0x00,0x00, // ]
|
||||||
|
0x00,0x08,0x04,0x7E,0x04,0x08,0x00,0x00, // ^
|
||||||
|
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, // _
|
||||||
|
|
||||||
|
0x3C,0x42,0x99,0xA5,0xA5,0x81,0x42,0x3C, // `
|
||||||
|
0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00, // a
|
||||||
|
0x00,0x7E,0x48,0x48,0x48,0x30,0x00,0x00, // b
|
||||||
|
0x00,0x00,0x38,0x44,0x44,0x44,0x00,0x00, // c
|
||||||
|
0x00,0x30,0x48,0x48,0x48,0x7E,0x00,0x00, // d
|
||||||
|
0x00,0x38,0x54,0x54,0x54,0x48,0x00,0x00, // e
|
||||||
|
0x00,0x00,0x00,0x7C,0x0A,0x02,0x00,0x00, // f
|
||||||
|
0x00,0x18,0xA4,0xA4,0xA4,0xA4,0x7C,0x00, // g
|
||||||
|
0x00,0x7E,0x08,0x08,0x08,0x70,0x00,0x00, // h
|
||||||
|
0x00,0x00,0x00,0x48,0x7A,0x40,0x00,0x00, // i
|
||||||
|
0x00,0x00,0x40,0x80,0x80,0x7A,0x00,0x00, // j
|
||||||
|
0x00,0x7E,0x18,0x24,0x40,0x00,0x00,0x00, // k
|
||||||
|
0x00,0x00,0x00,0x3E,0x40,0x40,0x00,0x00, // l
|
||||||
|
0x00,0x7C,0x04,0x78,0x04,0x78,0x00,0x00, // m
|
||||||
|
0x00,0x7C,0x04,0x04,0x04,0x78,0x00,0x00, // n
|
||||||
|
0x00,0x38,0x44,0x44,0x44,0x38,0x00,0x00, // o
|
||||||
|
|
||||||
|
0x00,0xFC,0x24,0x24,0x24,0x18,0x00,0x00, // p
|
||||||
|
0x00,0x18,0x24,0x24,0x24,0xFC,0x80,0x00, // q
|
||||||
|
0x00,0x00,0x78,0x04,0x04,0x04,0x00,0x00, // r
|
||||||
|
0x00,0x48,0x54,0x54,0x54,0x20,0x00,0x00, // s
|
||||||
|
0x00,0x00,0x04,0x3E,0x44,0x40,0x00,0x00, // t
|
||||||
|
0x00,0x3C,0x40,0x40,0x40,0x3C,0x00,0x00, // u
|
||||||
|
0x00,0x0C,0x30,0x40,0x30,0x0C,0x00,0x00, // v
|
||||||
|
0x00,0x3C,0x40,0x38,0x40,0x3C,0x00,0x00, // w
|
||||||
|
0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00, // x
|
||||||
|
0x00,0x1C,0xA0,0xA0,0xA0,0x7C,0x00,0x00, // y
|
||||||
|
0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00, // z
|
||||||
|
0x00,0x08,0x08,0x76,0x42,0x42,0x00,0x00, // {
|
||||||
|
0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, // |
|
||||||
|
0x00,0x42,0x42,0x76,0x08,0x08,0x00,0x00, // }
|
||||||
|
0x00,0x00,0x04,0x02,0x04,0x02,0x00,0x00 // ~
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
70
linux_i2c.c
Normal file
70
linux_i2c.c
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <linux/i2c-dev.h>
|
||||||
|
|
||||||
|
static int file_i2c = 0;
|
||||||
|
|
||||||
|
uint8_t _i2c_init(int i2c, int dev_addr)
|
||||||
|
{
|
||||||
|
if (file_i2c == 0)
|
||||||
|
{
|
||||||
|
char filename[32];
|
||||||
|
sprintf(filename, "/dev/i2c-%d", i2c); // I2C bus number passed
|
||||||
|
file_i2c = open(filename, O_RDWR);
|
||||||
|
if (file_i2c < 0)
|
||||||
|
{
|
||||||
|
file_i2c = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (ioctl(file_i2c, I2C_SLAVE, dev_addr) < 0) // set slave address
|
||||||
|
{
|
||||||
|
close(file_i2c);
|
||||||
|
file_i2c = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assume done init already
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t _i2c_close()
|
||||||
|
{
|
||||||
|
if (file_i2c != 0)
|
||||||
|
{
|
||||||
|
close(file_i2c);
|
||||||
|
file_i2c = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t _i2c_write(uint8_t* ptr, int16_t len)
|
||||||
|
{
|
||||||
|
if (file_i2c == 0 || ptr == 0 || len <= 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
int32_t rc;
|
||||||
|
rc = write(file_i2c, ptr, len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t _i2c_read(uint8_t *ptr, int16_t len)
|
||||||
|
{
|
||||||
|
if (file_i2c == 0 || ptr == 0 || len <= 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
int32_t rc;
|
||||||
|
rc = read(file_i2c, ptr, len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
8
linux_i2c.h
Normal file
8
linux_i2c.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef __LINUX_I2C_H__
|
||||||
|
#define __LINUX_I2C_H__
|
||||||
|
|
||||||
|
uint8_t _i2c_init(int i2c, int dev_addr);
|
||||||
|
uint8_t _i2c_close();
|
||||||
|
uint8_t _i2c_write(uint8_t* ptr, int16_t len);
|
||||||
|
uint8_t _i2c_read(uint8_t *ptr, int16_t len);
|
||||||
|
#endif
|
224
main.c
Normal file
224
main.c
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <ssd1306.h>
|
||||||
|
|
||||||
|
void print_help()
|
||||||
|
{
|
||||||
|
printf("help message\n\n");
|
||||||
|
printf("-I\t\tinit oled (128x32 or 128x64 or 64x48)\n");
|
||||||
|
printf("-c\t\tclear (line number or all)\n");
|
||||||
|
printf("-d\t\t0/display off 1/display on\n");
|
||||||
|
printf("-f\t\t0/small font 5x7 1/normal font 8x8 (default normal font)\n");
|
||||||
|
printf("-h\t\thelp message\n");
|
||||||
|
printf("-i\t\t0/normal oled 1/invert oled\n");
|
||||||
|
printf("-l\t\tput your line to display\n");
|
||||||
|
printf("-m\t\tput your strings to oled\n");
|
||||||
|
printf("-n\t\tI2C device node address (0,1,2..., default 0)\n");
|
||||||
|
printf("-r\t\t0/normal 180/rotate\n");
|
||||||
|
printf("-x\t\tx position\n");
|
||||||
|
printf("-y\t\ty position\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
uint8_t i2c_node_address = 0;
|
||||||
|
int x = -1;
|
||||||
|
int y = -1;
|
||||||
|
uint8_t line[25] = {0};
|
||||||
|
uint8_t msg[200] = {0};
|
||||||
|
uint8_t oled_type[10] = {0};
|
||||||
|
int clear_line = -1;
|
||||||
|
int clear_all = -1;
|
||||||
|
int orientation = -1;
|
||||||
|
int inverted = -1;
|
||||||
|
int display = -1;
|
||||||
|
int font = 0;
|
||||||
|
|
||||||
|
int cmd_opt = 0;
|
||||||
|
|
||||||
|
while(cmd_opt != -1)
|
||||||
|
{
|
||||||
|
cmd_opt = getopt(argc, argv, "I:c::d:f:hi:l:m:n:r:x:y:");
|
||||||
|
|
||||||
|
/* Lets parse */
|
||||||
|
switch (cmd_opt) {
|
||||||
|
case 'I':
|
||||||
|
strncpy(oled_type, optarg, sizeof(oled_type));
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
if (optarg)
|
||||||
|
{
|
||||||
|
clear_line = atoi(optarg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clear_all = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
display = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
font = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
print_help();
|
||||||
|
return 0;
|
||||||
|
case 'i':
|
||||||
|
inverted = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
strncpy(line, optarg, sizeof(line));
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
strncpy(msg, optarg, sizeof(msg));
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
i2c_node_address = (uint8_t)atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
orientation = atoi(optarg);
|
||||||
|
if (orientation != 0 && orientation != 180)
|
||||||
|
{
|
||||||
|
printf("orientation value must be 0 or 180\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
x = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'y':
|
||||||
|
y = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
// just ignore
|
||||||
|
break;
|
||||||
|
/* Error handle: Mainly missing arg or illegal option */
|
||||||
|
case '?':
|
||||||
|
if (optopt == 'I')
|
||||||
|
{
|
||||||
|
printf("prams -%c missing oled type (128x64/128x32/64x48)\n", optopt);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (optopt == 'd' || optopt == 'f' || optopt == 'i')
|
||||||
|
{
|
||||||
|
printf("prams -%c missing 0 or 1 fields\n", optopt);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (optopt == 'l' || optopt == 'm')
|
||||||
|
{
|
||||||
|
printf("prams -%c missing string\n", optopt);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (optopt == 'n')
|
||||||
|
{
|
||||||
|
printf("prams -%c missing 0,1,2... I2C device node number\n", optopt);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (optopt == 'r')
|
||||||
|
{
|
||||||
|
printf("prams -%c missing 0 or 180 fields\n", optopt);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (optopt == 'x' || optopt == 'y')
|
||||||
|
{
|
||||||
|
printf("prams -%c missing coordinate values\n", optopt);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_help();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t rc = 0;
|
||||||
|
|
||||||
|
// open the I2C device node
|
||||||
|
rc = ssd1306_init(i2c_node_address);
|
||||||
|
|
||||||
|
if (rc != 0)
|
||||||
|
{
|
||||||
|
printf("no oled attached to /dev/i2c-%d\n", i2c_node_address);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init oled module
|
||||||
|
if (oled_type[0] != 0)
|
||||||
|
{
|
||||||
|
if (strcmp(oled_type, "128x64") == 0)
|
||||||
|
rc += ssd1306_oled_default_config(64, 128);
|
||||||
|
else if (strcmp(oled_type, "128x32") == 0)
|
||||||
|
rc += ssd1306_oled_default_config(32, 128);
|
||||||
|
else if (strcmp(oled_type, "64x48") == 0)
|
||||||
|
rc += ssd1306_oled_default_config(48, 64);
|
||||||
|
}
|
||||||
|
else if (ssd1306_oled_load_resolution() != 0)
|
||||||
|
{
|
||||||
|
printf("please do init oled module with correction resolution first!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear display
|
||||||
|
if (clear_all > -1)
|
||||||
|
{
|
||||||
|
rc += ssd1306_oled_clear_screen();
|
||||||
|
}
|
||||||
|
else if (clear_line > -1)
|
||||||
|
{
|
||||||
|
rc += ssd1306_oled_clear_line(clear_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set rotate orientation
|
||||||
|
if (orientation > -1)
|
||||||
|
{
|
||||||
|
rc += ssd1306_oled_set_rotate(orientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set oled inverted
|
||||||
|
if (inverted > -1)
|
||||||
|
{
|
||||||
|
rc += ssd1306_oled_display_flip(inverted);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set display on off
|
||||||
|
if (display > -1)
|
||||||
|
{
|
||||||
|
rc += ssd1306_oled_onoff(display);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set cursor XY
|
||||||
|
if (x > -1 && y > -1)
|
||||||
|
{
|
||||||
|
rc += ssd1306_oled_set_XY(x, y);
|
||||||
|
}
|
||||||
|
else if (x > -1)
|
||||||
|
{
|
||||||
|
rc += ssd1306_oled_set_X(x);
|
||||||
|
}
|
||||||
|
else if (y > -1)
|
||||||
|
{
|
||||||
|
rc += ssd1306_oled_set_Y(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// print text
|
||||||
|
if (msg[0] != 0)
|
||||||
|
{
|
||||||
|
rc += ssd1306_oled_write_string(font, msg);
|
||||||
|
}
|
||||||
|
else if (line[0] != 0)
|
||||||
|
{
|
||||||
|
rc += ssd1306_oled_write_line(font, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// close the I2C device node
|
||||||
|
ssd1306_end();
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
463
ssd1306.c
Normal file
463
ssd1306.c
Normal file
@ -0,0 +1,463 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <linux_i2c.h>
|
||||||
|
#include <ssd1306.h>
|
||||||
|
#include <font.h>
|
||||||
|
|
||||||
|
const uint8_t init_oled_type_file[] = "/tmp/.ssd1306_oled_type";
|
||||||
|
|
||||||
|
static uint8_t data_buf[1024];
|
||||||
|
static int16_t data_len = 0;
|
||||||
|
static uint8_t max_lines = 0;
|
||||||
|
static uint8_t max_columns = 0;
|
||||||
|
static uint8_t global_x = 0;
|
||||||
|
static uint8_t global_y = 0;
|
||||||
|
|
||||||
|
uint8_t ssd1306_init(uint8_t i2c_dev)
|
||||||
|
{
|
||||||
|
uint8_t rc;
|
||||||
|
rc = _i2c_init(i2c_dev, SSD1306_I2C_ADDR);
|
||||||
|
if (rc > 0)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
// test i2c connection
|
||||||
|
uint8_t cmd = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
uint8_t result = 0;
|
||||||
|
_i2c_write(&cmd, 1);
|
||||||
|
_i2c_read(&result, 1);
|
||||||
|
if (result == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_end()
|
||||||
|
{
|
||||||
|
return _i2c_close();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_onoff(uint8_t onoff)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
if (onoff == 0)
|
||||||
|
data_buf[1] = SSD1306_COMM_DISPLAY_OFF;
|
||||||
|
else
|
||||||
|
data_buf[1] = SSD1306_COMM_DISPLAY_ON;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_horizontal_flip(uint8_t flip)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
if (flip == 0)
|
||||||
|
data_buf[1] = SSD1306_COMM_HORIZ_NORM;
|
||||||
|
else
|
||||||
|
data_buf[1] = SSD1306_COMM_HORIZ_FLIP;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_display_flip(uint8_t flip)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
if (flip == 0)
|
||||||
|
data_buf[1] = SSD1306_COMM_DISP_NORM;
|
||||||
|
else
|
||||||
|
data_buf[1] = SSD1306_COMM_DISP_INVERSE;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 128x32 please use value 32
|
||||||
|
// 128x64 please use value 64
|
||||||
|
uint8_t ssd1306_oled_multiplex(uint8_t row)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
data_buf[1] = SSD1306_COMM_MULTIPLEX;
|
||||||
|
data_buf[2] = row - 1;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// offset range 0x00~0x3f
|
||||||
|
uint8_t ssd1306_oled_vert_shift(uint8_t offset)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
data_buf[1] = SSD1306_COMM_VERT_OFFSET;
|
||||||
|
data_buf[2] = offset;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// default value for clk is 0x80
|
||||||
|
uint8_t ssd1306_oled_set_clock(uint8_t clk)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
data_buf[1] = SSD1306_COMM_CLK_SET;
|
||||||
|
data_buf[2] = clk;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// default value for precharge is 0xf1
|
||||||
|
uint8_t ssd1306_oled_set_precharge(uint8_t precharge)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
data_buf[1] = SSD1306_COMM_PRECHARGE;
|
||||||
|
data_buf[2] = precharge;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// default value for deselect is 0x40
|
||||||
|
uint8_t ssd1306_oled_set_deselect(uint8_t voltage)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
data_buf[1] = SSD1306_COMM_DESELECT_LV;
|
||||||
|
data_buf[2] = voltage;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// default value for com pin is 0x02
|
||||||
|
uint8_t ssd1306_oled_set_com_pin(uint8_t value)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
data_buf[1] = SSD1306_COMM_COM_PIN;
|
||||||
|
data_buf[2] = value;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// default value use SSD1306_PAGE_MODE
|
||||||
|
uint8_t ssd1306_oled_set_mem_mode(uint8_t mode)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
data_buf[1] = SSD1306_COMM_MEMORY_MODE;
|
||||||
|
data_buf[2] = mode;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_set_col(uint8_t start, uint8_t end)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
data_buf[1] = SSD1306_COMM_SET_COL_ADDR;
|
||||||
|
data_buf[2] = start;
|
||||||
|
data_buf[3] = end;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_set_page(uint8_t start, uint8_t end)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
data_buf[1] = SSD1306_COMM_SET_PAGE_ADDR;
|
||||||
|
data_buf[2] = start;
|
||||||
|
data_buf[3] = end;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// default contrast value is 0x7f
|
||||||
|
uint8_t ssd1306_oled_set_constrast(uint8_t value)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
data_buf[1] = SSD1306_COMM_CONTRAST;
|
||||||
|
data_buf[2] = value;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_scroll_onoff(uint8_t onoff)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
if (onoff == 0)
|
||||||
|
data_buf[1] = SSD1306_COMM_DISABLE_SCROLL;
|
||||||
|
else
|
||||||
|
data_buf[1] = SSD1306_COMM_ENABLE_SCROLL;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_set_X(uint8_t x)
|
||||||
|
{
|
||||||
|
if (x >= max_columns)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
global_x = x;
|
||||||
|
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
data_buf[1] = SSD1306_COMM_LOW_COLUMN | (x & 0x0f);
|
||||||
|
data_buf[2] = SSD1306_COMM_HIGH_COLUMN | ((x >> 4) & 0x0f);
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_set_Y(uint8_t y)
|
||||||
|
{
|
||||||
|
if (y >= (max_lines / 8))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
global_y = y;
|
||||||
|
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
data_buf[1] = SSD1306_COMM_PAGE_NUMBER | (y & 0x0f);
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_set_XY(uint8_t x, uint8_t y)
|
||||||
|
{
|
||||||
|
if (x >= max_columns || y >= (max_lines / 8))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
global_x = x;
|
||||||
|
global_y = y;
|
||||||
|
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
data_buf[1] = SSD1306_COMM_PAGE_NUMBER | (y & 0x0f);
|
||||||
|
|
||||||
|
data_buf[2] = SSD1306_COMM_LOW_COLUMN | (x & 0x0f);
|
||||||
|
|
||||||
|
data_buf[3] = SSD1306_COMM_HIGH_COLUMN | ((x >> 4) & 0x0f);
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_set_rotate(uint8_t degree)
|
||||||
|
{
|
||||||
|
// only degree 0 and 180
|
||||||
|
if (degree == 0)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
data_buf[1] = SSD1306_COMM_HORIZ_FLIP;
|
||||||
|
data_buf[2] = SSD1306_COMM_SCAN_REVS;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 3);
|
||||||
|
}
|
||||||
|
else if (degree == 180)
|
||||||
|
{
|
||||||
|
data_buf[0] = SSD1306_COMM_CONTROL_BYTE;
|
||||||
|
data_buf[1] = SSD1306_COMM_HORIZ_NORM;
|
||||||
|
data_buf[2] = SSD1306_COMM_SCAN_NORM;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_default_config(uint8_t oled_lines, uint8_t oled_columns)
|
||||||
|
{
|
||||||
|
if (oled_lines != SSD1306_128_64_LINES && oled_lines != SSD1306_128_32_LINES && SSD1306_64_48_LINES)
|
||||||
|
oled_lines = SSD1306_128_64_LINES;
|
||||||
|
|
||||||
|
if (oled_columns != SSD1306_128_64_COLUMNS && oled_lines != SSD1306_128_32_COLUMNS && SSD1306_64_48_COLUMNS)
|
||||||
|
oled_columns = SSD1306_128_64_COLUMNS;
|
||||||
|
|
||||||
|
max_lines = oled_lines;
|
||||||
|
max_columns = oled_columns;
|
||||||
|
global_x = 0;
|
||||||
|
global_y = 0;
|
||||||
|
|
||||||
|
if (ssd1306_oled_save_resolution(max_columns, max_lines) != 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
uint16_t i = 0;
|
||||||
|
data_buf[i++] = SSD1306_COMM_CONTROL_BYTE; //command control byte
|
||||||
|
data_buf[i++] = SSD1306_COMM_DISPLAY_OFF; //display off
|
||||||
|
data_buf[i++] = SSD1306_COMM_DISP_NORM; //Set Normal Display (default)
|
||||||
|
data_buf[i++] = SSD1306_COMM_CLK_SET; //SETDISPLAYCLOCKDIV
|
||||||
|
data_buf[i++] = 0x80; // the suggested ratio 0x80
|
||||||
|
data_buf[i++] = SSD1306_COMM_MULTIPLEX; //SSD1306_SETMULTIPLEX
|
||||||
|
data_buf[i++] = oled_lines - 1; // height is 32 or 64 (always -1)
|
||||||
|
data_buf[i++] = SSD1306_COMM_VERT_OFFSET; //SETDISPLAYOFFSET
|
||||||
|
data_buf[i++] = 0; //no offset
|
||||||
|
data_buf[i++] = SSD1306_COMM_START_LINE; //SETSTARTLINE
|
||||||
|
data_buf[i++] = SSD1306_COMM_CHARGE_PUMP; //CHARGEPUMP
|
||||||
|
data_buf[i++] = 0x14; //turn on charge pump
|
||||||
|
data_buf[i++] = SSD1306_COMM_MEMORY_MODE; //MEMORYMODE
|
||||||
|
data_buf[i++] = SSD1306_PAGE_MODE; // page mode
|
||||||
|
data_buf[i++] = SSD1306_COMM_HORIZ_NORM; //SEGREMAP Mirror screen horizontally (A0)
|
||||||
|
data_buf[i++] = SSD1306_COMM_SCAN_NORM; //COMSCANDEC Rotate screen vertically (C0)
|
||||||
|
data_buf[i++] = SSD1306_COMM_COM_PIN; //HARDWARE PIN
|
||||||
|
data_buf[i++] = 0x02; //normal
|
||||||
|
data_buf[i++] = SSD1306_COMM_CONTRAST; //SETCONTRAST
|
||||||
|
data_buf[i++] = 0x7f; // default contract value
|
||||||
|
data_buf[i++] = SSD1306_COMM_PRECHARGE; //SETPRECHARGE
|
||||||
|
data_buf[i++] = 0xf1; // default precharge value
|
||||||
|
data_buf[i++] = SSD1306_COMM_DESELECT_LV; //SETVCOMDETECT
|
||||||
|
data_buf[i++] = 0x40; // default deselect value
|
||||||
|
data_buf[i++] = SSD1306_COMM_RESUME_RAM; //DISPLAYALLON_RESUME
|
||||||
|
data_buf[i++] = SSD1306_COMM_DISP_NORM; //NORMALDISPLAY
|
||||||
|
data_buf[i++] = SSD1306_COMM_DISPLAY_ON; //DISPLAY ON
|
||||||
|
data_buf[i++] = SSD1306_COMM_DISABLE_SCROLL;//Stop scroll
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_write_line(uint8_t size, uint8_t* ptr)
|
||||||
|
{
|
||||||
|
uint16_t i = 0;
|
||||||
|
uint16_t index = 0;
|
||||||
|
uint8_t* font_table = 0;
|
||||||
|
uint8_t font_table_width = 0;
|
||||||
|
|
||||||
|
if (ptr == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (size == SSD1306_FONT_SMALL) // 5x7
|
||||||
|
{
|
||||||
|
font_table = (uint8_t*)font5x7;
|
||||||
|
font_table_width = 5;
|
||||||
|
}
|
||||||
|
else if (size == SSD1306_FONT_NORMAL) // 8x8
|
||||||
|
{
|
||||||
|
font_table = (uint8_t*)font8x8;
|
||||||
|
font_table_width = 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
data_buf[i++] = SSD1306_DATA_CONTROL_BYTE;
|
||||||
|
|
||||||
|
// font table range in ascii table is from 0x20(space) to 0x7e(~)
|
||||||
|
while (ptr[index] != 0 && i <= 1024)
|
||||||
|
{
|
||||||
|
if ((ptr[index] < ' ') || (ptr[index] > '~'))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
uint8_t* font_ptr = &font_table[(ptr[index] - 0x20) * font_table_width];
|
||||||
|
uint8_t j = 0;
|
||||||
|
for (j = 0; j < font_table_width; j++)
|
||||||
|
{
|
||||||
|
data_buf[i++] = font_ptr[j];
|
||||||
|
if (i > 1024)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// insert 1 col space for small font size)
|
||||||
|
if (size == SSD1306_FONT_SMALL)
|
||||||
|
data_buf[i++] = 0x00;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_write_string(uint8_t size, uint8_t* ptr)
|
||||||
|
{
|
||||||
|
uint8_t rc = 0;
|
||||||
|
|
||||||
|
if (ptr == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
uint8_t* line = 0;
|
||||||
|
uint8_t* cr = 0;
|
||||||
|
uint8_t buf[20];
|
||||||
|
|
||||||
|
line = ptr;
|
||||||
|
do {
|
||||||
|
memset(buf, 0, 20);
|
||||||
|
cr = strstr(line, "\\n");
|
||||||
|
if (cr != NULL)
|
||||||
|
{
|
||||||
|
strncpy(buf, line, cr - line);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(buf, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set cursor position
|
||||||
|
ssd1306_oled_set_XY(global_x, global_y);
|
||||||
|
rc += ssd1306_oled_write_line(size, buf);
|
||||||
|
|
||||||
|
if (cr != NULL)
|
||||||
|
{
|
||||||
|
line = &cr[2];
|
||||||
|
global_x = 0;
|
||||||
|
global_y++;
|
||||||
|
if (global_y >= (max_lines / 8))
|
||||||
|
global_y = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
line = NULL;
|
||||||
|
|
||||||
|
}while (line != NULL);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_clear_line(uint8_t row)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
if (row >= (max_lines / 8))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ssd1306_oled_set_XY(0, row);
|
||||||
|
data_buf[0] = SSD1306_DATA_CONTROL_BYTE;
|
||||||
|
for (i = 0; i < max_columns; i++)
|
||||||
|
data_buf[i+1] = 0x00;
|
||||||
|
|
||||||
|
return _i2c_write(data_buf, 1 + max_columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_clear_screen()
|
||||||
|
{
|
||||||
|
uint8_t rc = 0;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < (max_lines / 8); i++)
|
||||||
|
{
|
||||||
|
rc += ssd1306_oled_clear_line(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_save_resolution(uint8_t column, uint8_t row)
|
||||||
|
{
|
||||||
|
FILE* fp;
|
||||||
|
|
||||||
|
fp = fopen(init_oled_type_file, "w");
|
||||||
|
|
||||||
|
if (fp == NULL)
|
||||||
|
{
|
||||||
|
// file create failed
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "%hhux%hhu", column, row);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ssd1306_oled_load_resolution()
|
||||||
|
{
|
||||||
|
FILE* fp;
|
||||||
|
|
||||||
|
fp = fopen(init_oled_type_file, "r");
|
||||||
|
|
||||||
|
if (fp == NULL)
|
||||||
|
{
|
||||||
|
// file not exists
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// file exists
|
||||||
|
fscanf(fp, "%hhux%hhu", &max_columns, &max_lines);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
85
ssd1306.h
Normal file
85
ssd1306.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#ifndef __SSD1306_H__
|
||||||
|
#define __SSD1306_H__
|
||||||
|
|
||||||
|
#define SSD1306_I2C_ADDR 0x3c
|
||||||
|
|
||||||
|
#define SSD1306_COMM_CONTROL_BYTE 0x00
|
||||||
|
#define SSD1306_DATA_CONTROL_BYTE 0x40
|
||||||
|
|
||||||
|
#define SSD1306_COMM_DISPLAY_OFF 0xae
|
||||||
|
#define SSD1306_COMM_DISPLAY_ON 0xaf
|
||||||
|
#define SSD1306_COMM_HORIZ_NORM 0xa0
|
||||||
|
#define SSD1306_COMM_HORIZ_FLIP 0xa1
|
||||||
|
#define SSD1306_COMM_RESUME_RAM 0xa4
|
||||||
|
#define SSD1306_COMM_IGNORE_RAM 0xa5
|
||||||
|
#define SSD1306_COMM_DISP_NORM 0xa6
|
||||||
|
#define SSD1306_COMM_DISP_INVERSE 0xa7
|
||||||
|
#define SSD1306_COMM_MULTIPLEX 0xa8
|
||||||
|
#define SSD1306_COMM_VERT_OFFSET 0xd3
|
||||||
|
#define SSD1306_COMM_CLK_SET 0xd5
|
||||||
|
#define SSD1306_COMM_PRECHARGE 0xd9
|
||||||
|
#define SSD1306_COMM_COM_PIN 0xda
|
||||||
|
#define SSD1306_COMM_DESELECT_LV 0xdb
|
||||||
|
#define SSD1306_COMM_CONTRAST 0x81
|
||||||
|
#define SSD1306_COMM_DISABLE_SCROLL 0x2e
|
||||||
|
#define SSD1306_COMM_ENABLE_SCROLL 0x2f
|
||||||
|
#define SSD1306_COMM_PAGE_NUMBER 0xb0
|
||||||
|
#define SSD1306_COMM_LOW_COLUMN 0x00
|
||||||
|
#define SSD1306_COMM_HIGH_COLUMN 0x10
|
||||||
|
|
||||||
|
#define SSD1306_COMM_START_LINE 0x40
|
||||||
|
|
||||||
|
#define SSD1306_COMM_CHARGE_PUMP 0x8d
|
||||||
|
|
||||||
|
#define SSD1306_COMM_SCAN_NORM 0xc0
|
||||||
|
#define SSD1306_COMM_SCAN_REVS 0xc8
|
||||||
|
|
||||||
|
#define SSD1306_COMM_MEMORY_MODE 0x20
|
||||||
|
#define SSD1306_COMM_SET_COL_ADDR 0x21
|
||||||
|
#define SSD1306_COMM_SET_PAGE_ADDR 0x22
|
||||||
|
|
||||||
|
#define SSD1306_HORI_MODE 0x00
|
||||||
|
#define SSD1306_VERT_MODE 0x01
|
||||||
|
#define SSD1306_PAGE_MODE 0x02
|
||||||
|
|
||||||
|
#define SSD1306_FONT_SMALL 0x00
|
||||||
|
#define SSD1306_FONT_NORMAL 0x01
|
||||||
|
|
||||||
|
#define SSD1306_128_64_LINES 64
|
||||||
|
#define SSD1306_128_32_LINES 32
|
||||||
|
#define SSD1306_64_48_LINES 48
|
||||||
|
|
||||||
|
#define SSD1306_128_64_COLUMNS 128
|
||||||
|
#define SSD1306_128_32_COLUMNS 128
|
||||||
|
#define SSD1306_64_48_COLUMNS 64
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t ssd1306_init(uint8_t i2c_dev);
|
||||||
|
uint8_t ssd1306_end();
|
||||||
|
uint8_t ssd1306_oled_onoff(uint8_t onoff);
|
||||||
|
uint8_t ssd1306_oled_horizontal_flip(uint8_t flip);
|
||||||
|
uint8_t ssd1306_oled_display_flip(uint8_t flip);
|
||||||
|
uint8_t ssd1306_oled_multiplex(uint8_t row);
|
||||||
|
uint8_t ssd1306_oled_vert_shift(uint8_t offset);
|
||||||
|
uint8_t ssd1306_oled_set_clock(uint8_t clk);
|
||||||
|
uint8_t ssd1306_oled_set_precharge(uint8_t precharge);
|
||||||
|
uint8_t ssd1306_oled_set_deselect(uint8_t voltage);
|
||||||
|
uint8_t ssd1306_oled_set_com_pin(uint8_t value);
|
||||||
|
uint8_t ssd1306_oled_set_mem_mode(uint8_t mode);
|
||||||
|
uint8_t ssd1306_oled_set_col(uint8_t start, uint8_t end);
|
||||||
|
uint8_t ssd1306_oled_set_page(uint8_t start, uint8_t end);
|
||||||
|
uint8_t ssd1306_oled_set_constrast(uint8_t value);
|
||||||
|
uint8_t ssd1306_oled_scroll_onoff(uint8_t onoff);
|
||||||
|
uint8_t ssd1306_oled_set_X(uint8_t x);
|
||||||
|
uint8_t ssd1306_oled_set_Y(uint8_t y);
|
||||||
|
uint8_t ssd1306_oled_set_XY(uint8_t x, uint8_t y);
|
||||||
|
uint8_t ssd1306_oled_set_rotate(uint8_t degree);
|
||||||
|
uint8_t ssd1306_oled_default_config(uint8_t oled_lines, uint8_t oled_columns);
|
||||||
|
uint8_t ssd1306_oled_write_line(uint8_t size, uint8_t* ptr);
|
||||||
|
uint8_t ssd1306_oled_write_string(uint8_t size, uint8_t* ptr);
|
||||||
|
uint8_t ssd1306_oled_clear_line(uint8_t row);
|
||||||
|
uint8_t ssd1306_oled_clear_screen();
|
||||||
|
uint8_t ssd1306_oled_save_resolution(uint8_t column, uint8_t row);
|
||||||
|
uint8_t ssd1306_oled_load_resolution();
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user