esp32-warm-water
esp32 based project for the control of a heating element based on temperature
ssd1306_spi.c
Go to the documentation of this file.
1 /*
2  * MIT License
3  *
4  * Copyright (c) 2020 nopnop2002
5  * Copyright (c) 2021 wolffshots
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  */
25 
31 #include <string.h>
32 
33 #include "freertos/FreeRTOS.h"
34 #include "freertos/task.h"
35 
36 #include "driver/spi_master.h"
37 #include "driver/gpio.h"
38 #include "esp_log.h"
39 
40 #include "ssd1306.h"
41 
42 #define tag CONFIG_SSD1306_SPI_TAG
43 
44 #ifdef CONFIG_IDF_TARGET_ESP32
45 #define LCD_HOST HSPI_HOST
46 #define DMA_CHAN 2
47 #elif defined CONFIG_IDF_TARGET_ESP32S2
48 #define LCD_HOST SPI2_HOST
49 #define DMA_CHAN LCD_HOST
50 #endif
51 
52 static const int SPI_Command_Mode = 0;
53 static const int SPI_Data_Mode = 1;
54 static const int SPI_Frequency = 1000000;
55 
65 void spi_master_init(SSD1306_t *dev, int16_t GPIO_MOSI, int16_t GPIO_SCLK, int16_t GPIO_CS, int16_t GPIO_DC, int16_t GPIO_RESET)
66 {
67  esp_err_t ret;
68 
69  gpio_pad_select_gpio(GPIO_CS);
70  gpio_set_direction(GPIO_CS, GPIO_MODE_OUTPUT);
71  gpio_set_level(GPIO_CS, 0);
72 
73  gpio_pad_select_gpio(GPIO_DC);
74  gpio_set_direction(GPIO_DC, GPIO_MODE_OUTPUT);
75  gpio_set_level(GPIO_DC, 0);
76 
77  if (GPIO_RESET >= 0)
78  {
79  gpio_pad_select_gpio(GPIO_RESET);
80  gpio_set_direction(GPIO_RESET, GPIO_MODE_OUTPUT);
81  gpio_set_level(GPIO_RESET, 0);
82  vTaskDelay(pdMS_TO_TICKS(100));
83  gpio_set_level(GPIO_RESET, 1);
84  }
85 
86  spi_bus_config_t spi_bus_config = {
87  .sclk_io_num = GPIO_SCLK,
88  .mosi_io_num = GPIO_MOSI,
89  .miso_io_num = -1,
90  .quadwp_io_num = -1,
91  .quadhd_io_num = -1};
92 
93  ret = spi_bus_initialize(LCD_HOST, &spi_bus_config, DMA_CHAN);
94  ESP_LOGI(tag, "spi_bus_initialize=%d", ret);
95  assert(ret == ESP_OK);
96 
97  spi_device_interface_config_t devcfg;
98  memset(&devcfg, 0, sizeof(spi_device_interface_config_t));
99  devcfg.clock_speed_hz = SPI_Frequency;
100  devcfg.spics_io_num = GPIO_CS;
101  devcfg.queue_size = 1;
102 
103  spi_device_handle_t handle;
104  ret = spi_bus_add_device(LCD_HOST, &devcfg, &handle);
105  ESP_LOGI(tag, "spi_bus_add_device=%d", ret);
106  assert(ret == ESP_OK);
107  dev->_dc = GPIO_DC;
108  dev->_SPIHandle = handle;
110  dev->_flip = false;
111 }
112 
119 bool spi_master_write_byte(spi_device_handle_t SPIHandle, const uint8_t *Data, size_t DataLength)
120 {
121  spi_transaction_t SPITransaction;
122 
123  if (DataLength > 0)
124  {
125  memset(&SPITransaction, 0, sizeof(spi_transaction_t));
126  SPITransaction.length = DataLength * 8;
127  SPITransaction.tx_buffer = Data;
128  spi_device_transmit(SPIHandle, &SPITransaction);
129  }
130 
131  return true;
132 }
133 
139 bool spi_master_write_command(SSD1306_t *dev, uint8_t Command)
140 {
141  static uint8_t CommandByte = 0;
142  CommandByte = Command;
143  gpio_set_level(dev->_dc, SPI_Command_Mode);
144  return spi_master_write_byte(dev->_SPIHandle, &CommandByte, 1);
145 }
146 
153 bool spi_master_write_data(SSD1306_t *dev, const uint8_t *Data, size_t DataLength)
154 {
155  gpio_set_level(dev->_dc, SPI_Data_Mode);
156  return spi_master_write_byte(dev->_SPIHandle, Data, DataLength);
157 }
158 
165 void spi_init(SSD1306_t *dev, int width, int height)
166 {
167  dev->_width = width;
168  dev->_height = height;
169  dev->_pages = 8;
170  if (dev->_height == 32)
171  dev->_pages = 4;
172 
175  if (dev->_height == 64)
177  if (dev->_height == 32)
182  if (dev->_flip)
183  {
185  }
186  else
187  {
189  }
190  //spi_master_write_command(dev, OLED_CMD_SET_SEGMENT_REMAP); // A1
195  if (dev->_height == 64)
197  if (dev->_height == 32)
205  //spi_master_write_command(dev, OLED_CMD_SET_HORI_ADDR_MODE); // 00
207  // Set Lower Column Start Address for Page Addressing Mode
209  // Set Higher Column Start Address for Page Addressing Mode
216 }
217 
226 void spi_display_image(SSD1306_t *dev, int page, int seg, uint8_t *images, int width)
227 {
228  if (page >= dev->_pages)
229  return;
230  if (seg >= dev->_width)
231  return;
232 
233  int _seg = seg + CONFIG_OFFSETX;
234  uint8_t columLow = _seg & 0x0F;
235  uint8_t columHigh = (_seg >> 4) & 0x0F;
236 
237  int _page = page;
238  if (dev->_flip)
239  {
240  _page = (dev->_pages - page) - 1;
241  }
242 
243  // Set Lower Column Start Address for Page Addressing Mode
244  spi_master_write_command(dev, (0x00 + columLow));
245  // Set Higher Column Start Address for Page Addressing Mode
246  spi_master_write_command(dev, (0x10 + columHigh));
247  // Set Page Start Address for Page Addressing Mode
248  spi_master_write_command(dev, 0xB0 | _page);
249 
250  spi_master_write_data(dev, images, width);
251 }
252 
258 void spi_contrast(SSD1306_t *dev, int contrast)
259 {
260  int _contrast = contrast;
261  if (contrast < 0x0)
262  _contrast = 0;
263  if (contrast > 0xFF)
264  _contrast = 0xFF;
265 
267  spi_master_write_command(dev, _contrast);
268 }
269 
276 {
277 
278  if (scroll == SCROLL_RIGHT)
279  {
281  spi_master_write_command(dev, 0x00); // Dummy byte
282  spi_master_write_command(dev, 0x00); // Define start page address
283  spi_master_write_command(dev, CONFIG_SSD1306_FRAME_FREQ); // Frame frequency
284  spi_master_write_command(dev, 0x07); // Define end page address
285  spi_master_write_command(dev, 0x00); //
286  spi_master_write_command(dev, 0xFF); //
288  }
289 
290  if (scroll == SCROLL_LEFT)
291  {
293  spi_master_write_command(dev, 0x00); // Dummy byte
294  spi_master_write_command(dev, 0x00); // Define start page address
295  spi_master_write_command(dev, CONFIG_SSD1306_FRAME_FREQ); // Frame frequency
296  spi_master_write_command(dev, 0x07); // Define end page address
297  spi_master_write_command(dev, 0x00); //
298  spi_master_write_command(dev, 0xFF); //
300  }
301 
302  if (scroll == SCROLL_DOWN)
303  {
305  spi_master_write_command(dev, 0x00); // Dummy byte
306  spi_master_write_command(dev, 0x00); // Define start page address
307  spi_master_write_command(dev, CONFIG_SSD1306_FRAME_FREQ); // Frame frequency
308  //spi_master_write_command(dev, 0x01); // Define end page address
309  spi_master_write_command(dev, 0x00); // Define end page address
310  spi_master_write_command(dev, 0x3F); // Vertical scrolling offset
311 
314  if (dev->_height == 64)
316  if (dev->_height == 32)
319  }
320 
321  if (scroll == SCROLL_UP)
322  {
324  spi_master_write_command(dev, 0x00); // Dummy byte
325  spi_master_write_command(dev, 0x00); // Define start page address
326  spi_master_write_command(dev, CONFIG_SSD1306_FRAME_FREQ); // Frame frequency
327  //spi_master_write_command(dev, 0x01); // Define end page address
328  spi_master_write_command(dev, 0x00); // Define end page address
329  spi_master_write_command(dev, 0x01); // Vertical scrolling offset
330 
333  if (dev->_height == 64)
335  if (dev->_height == 32)
338  }
339 
340  if (scroll == SCROLL_STOP)
341  {
343  }
344 }
345 
353 {
354  if (scroll == SCROLL_RIGHT)
355  {
357  spi_master_write_command(dev, 0x00); // Dummy byte
358  spi_master_write_command(dev, page); // Define start page address
359  spi_master_write_command(dev, CONFIG_SSD1306_FRAME_FREQ); // Frame frequency
360  spi_master_write_command(dev, page); // Define end page address
361  spi_master_write_command(dev, 0x00); //
362  spi_master_write_command(dev, 0xFF); //
364  }
365 
366  if (scroll == SCROLL_LEFT)
367  {
369  spi_master_write_command(dev, 0x00); // Dummy byte
370  spi_master_write_command(dev, page); // Define start page address
371  spi_master_write_command(dev, CONFIG_SSD1306_FRAME_FREQ); // Frame frequency
372  spi_master_write_command(dev, page); // Define end page address
373  spi_master_write_command(dev, 0x00); //
374  spi_master_write_command(dev, 0xFF); //
376  }
377 
378  if (scroll == SCROLL_STOP)
379  {
381  }
382 }
SSD1306_t dev
device for oled
Definition: main.c:81
defininitions for setting up, interacting with and sending commands to an ssd1306 driven screen via i...
ssd1306_scroll_type_t
Definition: ssd1306.h:105
@ SCROLL_STOP
Definition: ssd1306.h:110
@ SCROLL_LEFT
Definition: ssd1306.h:107
@ SCROLL_DOWN
Definition: ssd1306.h:108
@ SCROLL_RIGHT
Definition: ssd1306.h:106
@ SCROLL_UP
Definition: ssd1306.h:109
#define OLED_CMD_SET_DISPLAY_OFFSET
Definition: ssd1306.h:81
#define OLED_CMD_ACTIVE_SCROLL
Definition: ssd1306.h:98
#define OLED_CMD_SET_CHARGE_PUMP
Definition: ssd1306.h:91
#define OLED_CMD_DISPLAY_ON
Definition: ssd1306.h:65
#define OLED_CMD_DISPLAY_OFF
Definition: ssd1306.h:64
#define OLED_CMD_SET_MUX_RATIO
Definition: ssd1306.h:79
#define OLED_CMD_DISPLAY_NORMAL
Definition: ssd1306.h:62
#define OLED_CMD_SET_SEGMENT_REMAP_0
Definition: ssd1306.h:77
#define OLED_CMD_SET_SEGMENT_REMAP_1
Definition: ssd1306.h:78
#define OLED_CMD_SET_COM_PIN_MAP
Definition: ssd1306.h:82
#define SPIAddress
Definition: ssd1306.h:102
#define OLED_CMD_HORIZONTAL_LEFT
Definition: ssd1306.h:95
#define OLED_CMD_SET_CONTRAST
Definition: ssd1306.h:59
#define OLED_CONTROL_BYTE_DATA_STREAM
Definition: ssd1306.h:56
#define OLED_CMD_SET_COM_SCAN_MODE
Definition: ssd1306.h:80
#define OLED_CMD_HORIZONTAL_RIGHT
Definition: ssd1306.h:94
#define OLED_CMD_SET_DISPLAY_CLK_DIV
Definition: ssd1306.h:86
#define OLED_CMD_SET_PAGE_ADDR_MODE
Definition: ssd1306.h:71
#define OLED_CMD_DISPLAY_RAM
Definition: ssd1306.h:60
#define OLED_CMD_DEACTIVE_SCROLL
Definition: ssd1306.h:97
#define OLED_CMD_VERTICAL
Definition: ssd1306.h:99
#define OLED_CMD_SET_VCOMH_DESELCT
Definition: ssd1306.h:88
#define OLED_CMD_SET_MEMORY_ADDR_MODE
Definition: ssd1306.h:68
#define OLED_CMD_CONTINUOUS_SCROLL
Definition: ssd1306.h:96
void spi_hardware_scroll(SSD1306_t *dev, ssd1306_scroll_type_t scroll)
Definition: ssd1306_spi.c:275
void spi_display_image(SSD1306_t *dev, int page, int seg, uint8_t *images, int width)
Definition: ssd1306_spi.c:226
void spi_master_init(SSD1306_t *dev, int16_t GPIO_MOSI, int16_t GPIO_SCLK, int16_t GPIO_CS, int16_t GPIO_DC, int16_t GPIO_RESET)
Definition: ssd1306_spi.c:65
bool spi_master_write_data(SSD1306_t *dev, const uint8_t *Data, size_t DataLength)
Definition: ssd1306_spi.c:153
bool spi_master_write_command(SSD1306_t *dev, uint8_t Command)
Definition: ssd1306_spi.c:139
void spi_hardware_scroll_line(SSD1306_t *dev, int page, ssd1306_scroll_type_t scroll)
Definition: ssd1306_spi.c:352
void spi_init(SSD1306_t *dev, int width, int height)
Definition: ssd1306_spi.c:165
void spi_contrast(SSD1306_t *dev, int contrast)
Definition: ssd1306_spi.c:258
bool spi_master_write_byte(spi_device_handle_t SPIHandle, const uint8_t *Data, size_t DataLength)
Definition: ssd1306_spi.c:119
#define tag
tag for logging library
Definition: ssd1306_spi.c:42
int _address
Definition: ssd1306.h:122
int _pages
Definition: ssd1306.h:125
bool _flip
Definition: ssd1306.h:133
int _dc
Definition: ssd1306.h:126
spi_device_handle_t _SPIHandle
Definition: ssd1306.h:127
int _height
Definition: ssd1306.h:124
int _width
Definition: ssd1306.h:123