1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
/*
* oled.h
*
* Created on: Oct 22, 2019
* Author: mmalex
*/
#ifndef OLED_H_
#define OLED_H_
#define W 128
#define H 32
void oled_flip(const u8* vram_with_offset);
void oled_init(void);
#ifdef IMPL
#define SSD1306_COLUMNADDR 0x21
#define SSD1306_DISPLAYOFF 0xAE
#define SSD1306_DISPLAYON 0xAF
#define SSD1306_PAGEADDR 0x22
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
#define SSD1306_SETPRECHARGE 0xD9
#define SSD1306_SETCONTRAST 0x81
#define SSD1306_SETDISPLAYOFFSET 0xD3
#define SSD1306_SETMULTIPLEX 0xA8
#define SSD1306_SETSTARTLINE 0x40
#define SSD1306_CHARGEPUMP 0x8D
#define SSD1306_SEGREMAP 0xA0
#define SSD1306_COMSCANDEC 0xC8
#define SSD1306_COMSCANINC 0xC0
#define SSD1306_MEMORYMODE 0x20
#define SSD1306_SETCOMPINS 0xDA
#define SSD1306_SETVCOMDETECT 0xDB
#define SSD1306_DISPLAYALLON_RESUME 0xA4
#define SSD1306_NORMALDISPLAY 0xA6
#define SSD1306_DEACTIVATE_SCROLL 0x2E
#define SSD1306_EXTERNALVCC 0x1
#define SSD1306_SWITCHCAPVCC 0x2
#define SSD1306_DISPLAYALLON 0xA5
#define SSD1306_INVERTDISPLAY 0xA7
#define SSD1306_SETLOWCOLUMN 0x00
#define SSD1306_SETHIGHCOLUMN 0x10
#include "logo.h"
const static unsigned char oled_i2caddr = 0x3c << 1;
static inline void ssd1306_command(unsigned char c) {
#ifndef EMU
u8 buf[2] = { 0, c };
HAL_StatusTypeDef r = HAL_I2C_Master_Transmit(&hi2c2, oled_i2caddr, buf, 2, I2C_TIMEOUT);
if (r != HAL_OK)
DebugLog("error in ssd1306 command %d\r\n", (int) r);
HAL_Delay(1);
#endif
}
static inline bool oled_busy(void) {
#ifndef EMU
return HAL_I2C_GetState(&hi2c2) == HAL_I2C_STATE_BUSY_TX;
#else
return false;
#endif
}
static inline void oled_wait(void) {
while (oled_busy()) ;
}
bool update_accelerometer_raw(void);
void oled_flip(const u8* vram_with_offset) {
// HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
// send a bunch of data in one xmission
oled_wait();
#ifndef EMU
ssd1306_command(0); // Page start address (0 = reset)
// ssd1306_command(3); // Page end address - 32 pixels. 1=16 pixels
HAL_StatusTypeDef r = HAL_I2C_Master_Transmit(&hi2c2, oled_i2caddr, (u8*)vram_with_offset, W * H / 8+1, 500);
if (r != HAL_OK)
DebugLog("error in ssd1306 data %d\r\n", (int) r);
update_accelerometer_raw();
#else
void OledFlipEmu(const u8 *vram);
OledFlipEmu(vram_with_offset);
#endif
}
void oled_init(void) {
// Init sequence
ssd1306_command(SSD1306_DISPLAYOFF); // 0xAE
ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
ssd1306_command(0x80); // the suggested ratio 0x80
ssd1306_command(SSD1306_SETMULTIPLEX); // 0xA8
ssd1306_command(H - 1);
ssd1306_command(SSD1306_SETDISPLAYOFFSET); // 0xD3
ssd1306_command(0x0); // no offset
ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0
ssd1306_command(SSD1306_CHARGEPUMP); // 0x8D
ssd1306_command(0x14); // switchcap
ssd1306_command(SSD1306_MEMORYMODE); // 0x20
ssd1306_command(0x00); // 0x0 act like ks0108
ssd1306_command(SSD1306_SEGREMAP | 0x1);
ssd1306_command(SSD1306_COMSCANDEC);
ssd1306_command(SSD1306_SETCOMPINS); // 0xDA
ssd1306_command(0x02);
ssd1306_command(SSD1306_SETCONTRAST); // 0x81
ssd1306_command(0x8F);
ssd1306_command(SSD1306_SETPRECHARGE); // 0xd9
ssd1306_command(0xF1); // switchcap
ssd1306_command(SSD1306_SETVCOMDETECT); // 0xDB
ssd1306_command(0x40);
ssd1306_command(SSD1306_DISPLAYALLON_RESUME); // 0xA4
ssd1306_command(SSD1306_NORMALDISPLAY); // 0xA6
ssd1306_command(SSD1306_DEACTIVATE_SCROLL);
// put the plinky logo up before switching on the screen
// prepare flip
ssd1306_command(SSD1306_COLUMNADDR);
ssd1306_command(0); // Column start address (0 = reset)
ssd1306_command(W - 1); // Column end address (127 = reset)
ssd1306_command(SSD1306_PAGEADDR);
ssd1306_command(0); // Page start address (0 = reset)
ssd1306_command(3); // Page end address - 32 pixels. 1=16 pixels
ssd1306_command(SSD1306_DISPLAYON); //--turn on oled panel
oled_flip(logobuf);
oled_wait();
}
#endif
#endif /* OLED_H_ */
|