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  * This Library was originally written by Olivier Van den Eede (4ilo) in 2016.
18  * Some refactoring was done and SPI support was added by Aleksander Alekseev (afiskon) in 2018.
19  *
20  * https://github.com/afiskon/stm32-ssd1306
21  */
22 
23 #ifndef __SSD1306_H__
24 #define __SSD1306_H__
25 
26 #include <stddef.h>
27 #include <_ansi.h>
28 
29 _BEGIN_STD_C
30 
31 #include "ssd1306_conf.h"
32 
33 #if defined(STM32F0)
34 #include "stm32f0xx_hal.h"
35 #elif defined(STM32F1)
36 #include "stm32f1xx_hal.h"
37 #elif defined(STM32F4)
38 #include "stm32f4xx_hal.h"
39 #include "stm32f4xx_hal_gpio.h"
40 #elif defined(STM32L0)
41 #include "stm32l0xx_hal.h"
42 #elif defined(STM32L4)
43 #include "stm32l4xx_hal.h"
44 #elif defined(STM32F3)
45 #include "stm32f3xx_hal.h"
46 #elif defined(STM32H7)
47 #include "stm32h7xx_hal.h"
48 #elif defined(STM32F7)
49 #include "stm32f7xx_hal.h"
50 #else
51 /* #error "SSD1306 library was tested only on  STM32F0, STM32F1, STM32F3, STM32F4, STM32F7, STM32L0, STM32L4, \
52 STM32H7 MCU families. Please modify ssd1306.h if you know what you are doing. Also please send a pull request \
53 if it turns out the library works on other MCU's as well!"
54 */
55 #endif
56 
57 #include "ssd1306_fonts.h"
58 
59 /* vvv I2C config vvv */
60 
61 #ifndef SSD1306_I2C_PORT
62 #define SSD1306_I2C_PORT        hi2c1
63 #endif
64 
65 #ifndef SSD1306_I2C_ADDR
66 #define SSD1306_I2C_ADDR        (0x3C << 1)
67 #endif
68 
69 /* ^^^ I2C config ^^^ */
70 
71 /* vvv SPI config vvv */
72 
73 #ifndef SSD1306_SPI_PORT
74 #define SSD1306_SPI_PORT        hspi2
75 #endif
76 
77 #ifndef SSD1306_CS_Port
78 #define SSD1306_CS_Port         GPIOB
79 #endif
80 #ifndef SSD1306_CS_Pin
81 #define SSD1306_CS_Pin          GPIO_PIN_12
82 #endif
83 
84 #ifndef SSD1306_DC_Port
85 #define SSD1306_DC_Port         GPIOB
86 #endif
87 #ifndef SSD1306_DC_Pin
88 #define SSD1306_DC_Pin          GPIO_PIN_14
89 #endif
90 
91 #ifndef SSD1306_Reset_Port
92 #define SSD1306_Reset_Port      GPIOA
93 #endif
94 #ifndef SSD1306_Reset_Pin
95 #define SSD1306_Reset_Pin       GPIO_PIN_8
96 #endif
97 
98 /* ^^^ SPI config ^^^ */
99 
100 #if defined(SSD1306_USE_I2C)
101 #elif defined(SSD1306_USE_SPI)
102 extern SPI_HandleTypeDef SSD1306_SPI_PORT;
103 #else
104 #error "You should define SSD1306_USE_SPI or SSD1306_USE_I2C macro!"
105 #endif
106 
107 // SSD1306 OLED height in pixels
108 #ifndef SSD1306_HEIGHT
109 #define SSD1306_HEIGHT          64
110 #endif
111 
112 // SSD1306 width in pixels
113 #ifndef SSD1306_WIDTH
114 #define SSD1306_WIDTH           128
115 #endif
116 
117 // some LEDs don't display anything in first two columns
118 
119 #ifndef SSD1306_BUFFER_SIZE
120 #define SSD1306_BUFFER_SIZE   (SSD1306_WIDTH * SSD1306_HEIGHT / 8)
121 #endif
122 
123 // Enumeration for screen colors
124 typedef enum {
125     Black = 0x00, // Black color, no pixel
126     White = 0x01  // Pixel is set. Color depends on OLED
127 } SSD1306_COLOR;
128 
129 typedef enum {
130     SSD1306_OK = 0x00,
131     SSD1306_ERR = 0x01  // Generic error.
132 } SSD1306_Error_t;
133 
134 // Struct to store transformations
135 typedef struct {
136     uint16_t CurrentX;
137     uint16_t CurrentY;
138     uint8_t Inverted;
139     uint8_t Initialized;
140     uint8_t DisplayOn;
141 } SSD1306_t;
142 typedef struct {
143     uint8_t x;
144     uint8_t y;
145 } SSD1306_VERTEX;
146 
147 // Procedure definitions
148 void ssd1306_Init(void);
149 void ssd1306_Fill(SSD1306_COLOR color);
150 void ssd1306_SetCursor(uint8_t x, uint8_t y);
151 void ssd1306_UpdateScreen(void);
152 
153 char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color);
154 char ssd1306_DrawString(char* str, FontDef Font, SSD1306_COLOR color);
155 
156 void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color);
157 void ssd1306_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color);
158 void ssd1306_DrawPolyline(const SSD1306_VERTEX *par_vertex, uint16_t par_size, SSD1306_COLOR color);
159 void ssd1306_DrawRectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color);
160 void ssd1306_DrawArc(uint8_t x, uint8_t y, uint8_t radius, \
161                      uint16_t start_angle, uint16_t sweep, SSD1306_COLOR color);
162 void ssd1306_DrawCircle(uint8_t par_x, uint8_t par_y, uint8_t par_r, SSD1306_COLOR par_color);
163 void ssd1306_DrawBitmap(const uint8_t* bitmap, uint32_t size);
164 
165 void ssd1306_DrawRegion(uint8_t x, uint8_t y, uint8_t w, \
166                         uint8_t h, const uint8_t* data, uint32_t size, uint32_t stride);
167 
168 /**
169  * @brief Sets the contrast of the display.
170  * @param[in] value contrast to set.
171  * @note Contrast increases as the value increases.
172  * @note RESET = 7Fh.
173  */
174 void ssd1306_SetContrast(const uint8_t value);
175 /**
176  * @brief Set Display ON/OFF.
177  * @param[in] on 0 for OFF, any for ON.
178  */
179 void ssd1306_SetDisplayOn(const uint8_t on);
180 /**
181  * @brief Reads DisplayOn state.
182  * @return  0: OFF.
183  *          1: ON.
184  */
185 uint8_t ssd1306_GetDisplayOn(void);
186 
187 void HAL_Delay(uint32_t ms);
188 
189 uint32_t HAL_GetTick(void); // in ms
190 
191 // Low-level procedures
192 void ssd1306_Reset(void);
193 void ssd1306_WriteCommand(uint8_t byte);
194 void ssd1306_WriteData(uint8_t* buffer, size_t buff_size);
195 SSD1306_Error_t ssd1306_FillBuffer(uint8_t* buf, uint32_t len);
196 
197 _END_STD_C
198 
199 #endif // __SSD1306_H__
200