• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
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  * limitations under the License.
14  */
15 
16 #include <stddef.h>
17 #include <stdio.h>
18 #include "ohos_types.h"
19 #include "iot_errno.h"
20 #include "iot_gpio.h"
21 #include "iot_i2c.h"
22 #include "iot_gpio_ex.h"
23 #include "oled_fonts.h"
24 #include "oled_ssd1306.h"
25 
26 #define OLED_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 
36 typedef struct {
37     /** Pointer to the buffer storing data to send */
38     unsigned char *sendBuf;
39     /** Length of data to send */
40     unsigned int  sendLen;
41     /** Pointer to the buffer for storing data to receive */
42     unsigned char *receiveBuf;
43     /** Length of data received */
44     unsigned int  receiveLen;
45 } IotI2cData;
46 
I2cWiteByte(uint8_t regAddr,uint8_t byte)47 static uint32_t I2cWiteByte(uint8_t regAddr, uint8_t byte)
48 {
49     unsigned int id = OLED_I2C_IDX;
50     uint8_t buffer[] = {regAddr, byte};
51     IotI2cData i2cData = {0};
52 
53     i2cData.sendBuf = buffer;
54     i2cData.sendLen = sizeof(buffer) / sizeof(buffer[0]);
55 
56     return IoTI2cWrite(id, OLED_I2C_ADDR, i2cData.sendBuf, i2cData.sendLen);
57 }
58 
59 /**
60  * @brief Write a command byte to OLED device.
61  *
62  * @param cmd the commnad byte to be writen.
63  * @return Returns {@link IOT_SUCCESS} if the operation is successful;
64  * returns an error code defined in {@link wifiiot_errno.h} otherwise.
65  */
WriteCmd(uint8_t cmd)66 static uint32_t WriteCmd(uint8_t cmd)
67 {
68     return I2cWiteByte(OLED_I2C_CMD, cmd);
69 }
70 
71 /**
72  * @brief Write a data byte to OLED device.
73  *
74  * @param cmd the data byte to be writen.
75  * @return Returns {@link IOT_SUCCESS} if the operation is successful;
76  * returns an error code defined in {@link wifiiot_errno.h} otherwise.
77  */
WriteData(uint8_t data)78 static uint32_t WriteData(uint8_t data)
79 {
80     return I2cWiteByte(OLED_I2C_DATA, data);
81 }
82 
83 /**
84  * @brief ssd1306 OLED Initialize.
85  */
OledInit(void)86 uint32_t OledInit(void)
87 {
88     static const uint8_t initCmds[] = {
89         0xAE, // --display off
90         0x00, // ---set low column address
91         0x10, // ---set high column address
92         0x40, // --set start line address
93         0xB0, // --set page address
94         0x81, // contract control
95         0xFF, // --128
96         0xA1, // set segment remap
97         0xA6, // --normal / reverse
98         0xA8, // --set multiplex ratio(1 to 64)
99         0x3F, // --1/32 duty
100         0xC8, // Com scan direction
101         0xD3, // -set display offset
102         0x00,
103         0xD5, // set osc division
104         0x80,
105         0xD8, // set area color mode off
106         0x05,
107         0xD9, // Set Pre-Charge Period
108         0xF1,
109         0xDA, // set com pin configuration
110         0x12,
111         0xDB, // set Vcomh
112         0x30,
113         0x8D, // set charge pump enable
114         0x14,
115         0xAF, // --turn on oled panel
116     };
117 
118     IoTGpioInit(13); /* 初始化gpio13 */
119     IoSetFunc(13, 6); /* gpio13使用6功能 */
120     IoTGpioInit(14); /* 初始化gpio14 */
121     IoSetFunc(14, 6); /* gpio14使用6功能 */
122 
123     IoTI2cInit(0, OLED_I2C_BAUDRATE);
124 
125     for (size_t i = 0; i < ARRAY_SIZE(initCmds); i++) {
126         uint32_t status = WriteCmd(initCmds[i]);
127         if (status != IOT_SUCCESS) {
128             return status;
129         }
130     }
131     return IOT_SUCCESS;
132 }
133 
OledSetPosition(uint8_t x,uint8_t y)134 void OledSetPosition(uint8_t x, uint8_t y)
135 {
136     WriteCmd(0xb0 + y);
137     WriteCmd(((x & 0xf0) >> 4) | 0x10); /* 在0xf0右移4位,与0x10或,实现了写数据 */
138     WriteCmd(x & 0x0f);
139 }
140 
141 /* 全屏填充 */
OledFillScreen(uint8_t fillData)142 void OledFillScreen(uint8_t fillData)
143 {
144     for (uint8_t m = 0; m < 8; m++) { /* 循环8次实现横屏填充 */
145         WriteCmd(0xb0 + m);
146         WriteCmd(0x00);
147         WriteCmd(0x10);
148 
149         for (uint8_t n = 0; n < 128; n++) { /* 循环128次实现竖屏填充 */
150             WriteData(fillData);
151         }
152     }
153 }
154 
155 /**
156  * @brief 8*16 typeface
157  * @param x: write positon start from x axis
158  * @param y: write positon start from y axis
159  * @param ch: write data
160  * @param font: selected font
161  */
OledShowChar(uint8_t x,uint8_t y,uint8_t ch,Font font)162 void OledShowChar(uint8_t x, uint8_t y, uint8_t ch, Font font)
163 {
164     uint8_t c = ch - ' '; // 得到偏移后的值
165     uint8_t b = x;
166     uint8_t d = y;
167     if (b > OLED_WIDTH - 1) {
168         b = 0;
169         d = d + 2; /* 得到偏移后的值2 */
170     }
171 
172     if (font == FONT8_X16) {
173         OledSetPosition(b, d);
174         for (uint8_t i = 0; i < 8; i++) { /* 循环8次实现横屏填充 */
175             WriteData(g_f8X16[c * 16 + i]); /* 循环16次实现横屏填充 */
176         }
177 
178         OledSetPosition(b, d + 1);
179         for (uint8_t i = 0; i < 8; i++) { /* 循环8次实现横屏填充 */
180             WriteData(g_f8X16[c * 16 + i + 8]); /* 循环16次实现横屏填充8列 */
181         }
182     } else {
183         OledSetPosition(b, d);
184         for (uint8_t i = 0; i < 6; i++) { /* 循环6次实现横屏填充 */
185             WriteData(g_f6X8[c][i]);
186         }
187     }
188 }
189 
OledShowString(uint8_t x,uint8_t y,const char * str,Font font)190 void OledShowString(uint8_t x, uint8_t y, const char* str, Font font)
191 {
192     uint8_t j = 0;
193     uint8_t b = x;
194     uint8_t d = y;
195     if (str == NULL) {
196         printf("param is NULL,Please check!!!\r\n");
197         return;
198     }
199 
200     while (str[j]) {
201         OledShowChar(b, d, str[j], font);
202         b += 8; /* 循环8次实现横屏填充 */
203         if (b > 120) { /* 循环120次实现横屏填充 */
204             b = 0;
205             d += 2; /* 循环2次实现横屏填充 */
206         }
207         j++;
208     }
209 }