• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 HiHope Open Source Organization .
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http:// www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  *
14  * limitations under the License.
15  */
16 
17 
18 #include <stddef.h>
19 #include <stdio.h>
20 #include "wifiiot_gpio.h"
21 #include "wifiiot_gpio_ex.h"
22 #include "wifiiot_i2c.h"
23 #include "wifiiot_errno.h"
24 #include "oled_fonts.h"
25 #include "oled_ssd1306.h"
26 #define OLED_I2C_IDX WIFI_IOT_I2C_IDX_0
27 
28 #define OLED_WIDTH    (128)
29 #define OLED_I2C_ADDR 0x78 // 默认地址为 0x78
30 #define OLED_I2C_CMD 0x00 // 0000 0000       写命令
31 #define OLED_I2C_DATA 0x40 // 0100 0000(0x40) 写数据
32 #define OLED_I2C_BAUDRATE (400*1000) // 400k
33 
34 #define DELAY_100_MS (100*1000)
35 #define FOUR 4
36 #define EIGHT 8
37 #define TWO 2
38 #define SIX 6
39 #define SIXTEEN 16
40 #define ONE_HUNDRED_AND_TWENTY 120
41 #define ONE_HUNDRED_AND_TWENTY_EIGHT 128
42 
I2cWiteByte(uint8_t regAddr,uint8_t byte)43 static uint32_t I2cWiteByte(uint8_t regAddr, uint8_t byte)
44 {
45     WifiIotI2cIdx id = OLED_I2C_IDX;
46     uint8_t buffer[] = {regAddr, byte};
47     WifiIotI2cData i2cData = {0};
48 
49     i2cData.sendBuf = buffer;
50     i2cData.sendLen = sizeof(buffer)/sizeof(buffer[0]);
51 
52     return I2cWrite(id, OLED_I2C_ADDR, &i2cData);
53 }
54 
55 /**
56  * @brief Write a command byte to OLED device.
57  *
58  * @param cmd the commnad byte to be writen.
59  * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful;
60  * returns an error code defined in {@link wifiiot_errno.h} otherwise.
61  */
WriteCmd(uint8_t cmd)62 static uint32_t WriteCmd(uint8_t cmd)
63 {
64     return I2cWiteByte(OLED_I2C_CMD, cmd);
65 }
66 
67 /**
68  * @brief Write a data byte to OLED device.
69  *
70  * @param cmd the data byte to be writen.
71  * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful;
72  * returns an error code defined in {@link wifiiot_errno.h} otherwise.
73  */
WriteData(uint8_t data)74 static uint32_t WriteData(uint8_t data)
75 {
76     return I2cWiteByte(OLED_I2C_DATA, data);
77 }
78 
79 /**
80  * @brief ssd1306 OLED Initialize.
81  */
OledInit(void)82 uint32_t OledInit(void)
83 {
84     static const uint8_t initCmds[] = {
85         0xAE, // --display off
86         0x00, // ---set low column address
87         0x10, // ---set high column address
88         0x40, // --set start line address
89         0xB0, // --set page address
90         0x81, // contract control
91         0xFF, // --128
92         0xA1, // set segment remap
93         0xA6, // --normal / reverse
94         0xA8, // --set multiplex ratio(1 to 64)
95         0x3F, // --1/32 duty
96         0xC8, // Com scan direction
97         0xD3, // -set display offset
98         0x00, //
99         0xD5, // set osc division
100         0x80, //
101         0xD8, // set area color mode off
102         0x05, //
103         0xD9, // Set Pre-Charge Period
104         0xF1, //
105         0xDA, // set com pin configuration
106         0x12, //
107         0xDB, // set Vcomh
108         0x30, //
109         0x8D, // set charge pump enable
110         0x14, //
111         0xAF, // --turn on oled panel
112     };
113 
114     IoSetFunc(WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA);
115     IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL);
116 
117     I2cInit(WIFI_IOT_I2C_IDX_0, OLED_I2C_BAUDRATE);
118 
119     for (size_t i = 0; i < sizeof(initCmds)/sizeof(initCmds[0]); i++) {
120         uint32_t status = WriteCmd(initCmds[i]);
121         if (status != WIFI_IOT_SUCCESS) {
122             return status;
123         }
124     }
125     return WIFI_IOT_SUCCESS;
126 }
127 
OledSetPosition(uint8_t x,uint8_t y)128 void OledSetPosition(uint8_t x, uint8_t y)
129 {
130     WriteCmd(0xb0 + y);
131     WriteCmd(((x & 0xf0) >> FOUR) | 0x10);
132     WriteCmd(x & 0x0f);
133 }
134 
OledFillScreen(uint8_t fillData)135 void OledFillScreen(uint8_t fillData)
136 {
137     uint8_t m = 0;
138     uint8_t n = 0;
139 
140     for (m=0; m < EIGHT; m++) {
141         WriteCmd(0xb0 + m);
142         WriteCmd(0x00);
143         WriteCmd(0x10);
144 
145         for (n=0; n < ONE_HUNDRED_AND_TWENTY_EIGHT; n++) {
146             WriteData(fillData);
147         }
148     }
149 }
150 
151 /**
152  * @brief 8*16 typeface
153  * @param x: write positon start from x axis
154  * @param y: write positon start from y axis
155  * @param ch: write data
156  * @param font: selected font
157  */
OledShowChar(uint8_t x,uint8_t y,uint8_t ch,Font font)158 void OledShowChar(uint8_t x, uint8_t y, uint8_t ch, Font font)
159 {
160     uint8_t c = 0;
161     uint8_t i = 0;
162     int num_x = x;
163     int num_y = y;
164 
165     c = ch - ' '; // 得到偏移后的值
166     if (x > OLED_WIDTH - 1) {
167         num_x = 0;
168         num_y = y + TWO;
169     }
170 
171     if (font == FONT8x16) {
172         OledSetPosition(x, y);
173         for (i = 0; i < EIGHT; i++) {
174             WriteData(F8X16[c*SIXTEEN + i]);
175         }
176 
177         OledSetPosition(x, y+1);
178         for (i = 0; i < EIGHT; i++) {
179             WriteData(F8X16[c*SIXTEEN + i + EIGHT]);
180         }
181     } else {
182         OledSetPosition(x, y);
183         for (i = 0; i < SIX; i++) {
184             WriteData(F6x8[c][i]);
185         }
186     }
187 }
188 
OledShowString(uint8_t x,uint8_t y,const char * str,Font font)189 void OledShowString(uint8_t x, uint8_t y, const char* str, Font font)
190 {
191     uint8_t j = 0;
192     int num_x = x;
193     int num_y = y;
194     if (str == NULL) {
195         printf("param is NULL,Please check!!!\r\n");
196         return;
197     }
198 
199     while (str[j]) {
200         OledShowChar(x, y, str[j], font);
201     num_x += EIGHT;
202     if (x > ONE_HUNDRED_AND_TWENTY) {
203             num_x = 0;
204             num_y += TWO;
205         }
206     j++;
207     }
208 }
209