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