libDaisy
Hardware Library for Daisy
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
oled_ssd130x.h
Go to the documentation of this file.
1#pragma once
2#ifndef SA_OLED_SSD130X_H
3#define SA_OLED_SSD130X_H
5#include "per/i2c.h"
6#include "per/spi.h"
7#include "per/gpio.h"
8#include "sys/system.h"
9#include "stm32h7xx_hal.h"
10
11namespace daisy
12{
17{
18 public:
38 void Init(const Config& config)
39 {
40 i2c_address_ = config.i2c_address;
41 i2c_.Init(config.i2c_config);
42 };
43 void SendCommand(uint8_t cmd)
44 {
45 uint8_t buf[2] = {0X00, cmd};
46 i2c_.TransmitBlocking(i2c_address_, buf, 2, 1000);
47 };
48
49 void SendData(uint8_t* buff, size_t size)
50 {
51 for(size_t i = 0; i < size; i++)
52 {
53 uint8_t buf[2] = {0X40, buff[i]};
54 i2c_.TransmitBlocking(i2c_address_, buf, 2, 1000);
55 }
56 };
57
58 private:
60 uint8_t i2c_address_;
61};
62
67{
68 public:
107 void Init(const Config& config)
108 {
109 // Initialize both GPIO
110 pin_dc_.Init(config.pin_config.dc, GPIO::Mode::OUTPUT);
111 pin_reset_.Init(config.pin_config.reset, GPIO::Mode::OUTPUT);
112
113 // Initialize SPI
114 spi_.Init(config.spi_config);
115
116 // Reset and Configure OLED.
117 pin_reset_.Write(0);
118 System::Delay(10);
119 pin_reset_.Write(1);
120 System::Delay(10);
121 };
122
123 void SendCommand(uint8_t cmd)
124 {
125 pin_dc_.Write(0);
126 spi_.BlockingTransmit(&cmd, 1);
127 };
128
129 void SendCommands(uint8_t* buff, size_t size)
130 {
131 pin_dc_.Write(0);
132 spi_.BlockingTransmit(buff, size);
133 };
134
135 void SendData(uint8_t* buff, size_t size)
136 {
137 pin_dc_.Write(1);
138 spi_.BlockingTransmit(buff, size);
139 };
140
141 void SendDataDma(uint8_t* buff,
142 size_t size,
144 void* context)
145 {
146 SCB_CleanInvalidateDCache_by_Addr(buff, size);
147 pin_dc_.Write(1);
148 spi_.DmaTransmit(buff, size, NULL, end_callback, context);
149 };
150
151 private:
152 SpiHandle spi_;
153 GPIO pin_reset_;
154 GPIO pin_dc_;
155};
156
161{
162 public:
163 struct Config
164 {
166 {
167 // Initialize using defaults
168 Defaults();
169 }
170 struct
171 {
172 uint32_t sclk_delay;
178 void Defaults()
179 {
180 pin_config.sclk_delay = 0; // fast as possible?!
181 // SPI peripheral config
182 pin_config.sclk = Pin(PORTD, 3);
183 pin_config.mosi = Pin(PORTC, 3);
184 // SSD130x control pin config
185 pin_config.dc = Pin(PORTC, 11); //D2
186 pin_config.reset = Pin(PORTC, 10); //D3
187 }
188 };
189 void Init(const Config& config)
190 {
191 // Initialize both GPIO
192 pin_sclk_.Init(config.pin_config.sclk, GPIO::Mode::OUTPUT);
193 pin_sclk_.Write(1); //ClockPolarity::LOW
194 clk_delay = config.pin_config.sclk_delay;
195 pin_mosi_.Init(config.pin_config.mosi, GPIO::Mode::OUTPUT);
196 pin_mosi_.Write(0);
197
198 pin_dc_.Init(config.pin_config.dc, GPIO::Mode::OUTPUT);
199 pin_reset_.Init(config.pin_config.reset, GPIO::Mode::OUTPUT);
200
201 // Reset and Configure OLED.
202 pin_reset_.Write(0);
203 System::Delay(10);
204 pin_reset_.Write(1);
205 System::Delay(10);
206 };
207 void SendCommand(uint8_t cmd)
208 {
209 pin_dc_.Write(0);
210 SoftSpiTransmit(cmd);
211 };
212
213 void SendData(uint8_t* buff, size_t size)
214 {
215 pin_dc_.Write(1);
216 for(size_t i = 0; i < size; i++)
217 SoftSpiTransmit(buff[i]);
218 };
219
220 private:
221 void SoftSpiTransmit(uint8_t val)
222 {
223 // bit flip
224 val = ((val & 0x01) << 7) | ((val & 0x02) << 5) | ((val & 0x04) << 3)
225 | ((val & 0x08) << 1) | ((val & 0x10) >> 1) | ((val & 0x20) >> 3)
226 | ((val & 0x40) >> 5) | ((val & 0x80) >> 7);
227
228 for(uint8_t bit = 0u; bit < 8u; bit++)
229 {
230 pin_mosi_.Write((val & (1 << bit)) ? 1 : 0);
231
232 System::DelayTicks(clk_delay);
233
234 pin_sclk_.Toggle();
235
236 System::DelayTicks(clk_delay);
237
238 pin_sclk_.Toggle();
239 }
240 }
241
242 uint32_t clk_delay;
243 GPIO pin_sclk_;
244 GPIO pin_mosi_;
245 GPIO pin_reset_;
246 GPIO pin_dc_;
247};
248
249
253template <size_t width, size_t height, typename Transport>
255{
256 public:
257 struct Config
258 {
259 typename Transport::Config transport_config;
260 };
261
262 void Init(Config config)
263 {
264 transport_.Init(config.transport_config);
265
266 // Init routine...
267
268 // Display Off
269 transport_.SendCommand(0xaE);
270 // Dimension dependent commands...
271 switch(height)
272 {
273 case 16:
274 // Display Clock Divide Ratio
275 transport_.SendCommand(0xD5);
276 transport_.SendCommand(0x60);
277 // Multiplex Ratio
278 transport_.SendCommand(0xA8);
279 transport_.SendCommand(0x0F);
280 // COM Pins
281 transport_.SendCommand(0xDA);
282 transport_.SendCommand(0x02);
283 break;
284 case 32:
285 // Display Clock Divide Ratio
286 transport_.SendCommand(0xD5);
287 transport_.SendCommand(0x80);
288 // Multiplex Ratio
289 transport_.SendCommand(0xA8);
290 transport_.SendCommand(0x1F);
291 // COM Pins
292 transport_.SendCommand(0xDA);
293 if(width == 64)
294 {
295 transport_.SendCommand(0x12);
296 }
297 else
298 {
299 transport_.SendCommand(0x02);
300 }
301
302 break;
303 case 48:
304 // Display Clock Divide Ratio
305 transport_.SendCommand(0xD5);
306 transport_.SendCommand(0x80);
307 // Multiplex Ratio
308 transport_.SendCommand(0xA8);
309 transport_.SendCommand(0x2F);
310 // COM Pins
311 transport_.SendCommand(0xDA);
312 transport_.SendCommand(0x12);
313 break;
314 default: // 128
315 // Display Clock Divide Ratio
316 transport_.SendCommand(0xD5);
317 transport_.SendCommand(0x80);
318 // Multiplex Ratio
319 transport_.SendCommand(0xA8);
320 transport_.SendCommand(0x3F);
321 // COM Pins
322 transport_.SendCommand(0xDA);
323 transport_.SendCommand(0x12);
324 break;
325 }
326
327 // Display Offset
328 transport_.SendCommand(0xD3);
329 transport_.SendCommand(0x00);
330 // Start Line Address
331 transport_.SendCommand(0x40);
332 // Normal Display
333 transport_.SendCommand(0xA6);
334 // All On Resume
335 transport_.SendCommand(0xA4);
336 // Charge Pump
337 transport_.SendCommand(0x8D);
338 transport_.SendCommand(0x14);
339 // Set Segment Remap
340 transport_.SendCommand(0xA1);
341 // COM Output Scan Direction
342 transport_.SendCommand(0xC8);
343 // Contrast Control
344 transport_.SendCommand(0x81);
345 transport_.SendCommand(0x8F);
346 // Pre Charge
347 transport_.SendCommand(0xD9);
348 transport_.SendCommand(0x25);
349 // VCOM Detect
350 transport_.SendCommand(0xDB);
351 transport_.SendCommand(0x34);
352
353
354 // Display On
355 transport_.SendCommand(0xAF); //--turn on oled panel
356 };
357
358 size_t Width() const { return width; };
359 size_t Height() const { return height; };
360
361 void DrawPixel(uint_fast8_t x, uint_fast8_t y, bool on)
362 {
363 if(x >= width || y >= height)
364 return;
365 if(on)
366 buffer_[x + (y / 8) * width] |= (1 << (y % 8));
367 else
368 buffer_[x + (y / 8) * width] &= ~(1 << (y % 8));
369 }
370
371 void Fill(bool on)
372 {
373 for(size_t i = 0; i < sizeof(buffer_); i++)
374 {
375 buffer_[i] = on ? 0xff : 0x00;
376 }
377 };
378
382 void Update()
383 {
384 uint8_t i;
385 uint8_t high_column_addr;
386 switch(height)
387 {
388 case 32: high_column_addr = 0x12; break;
389
390 default: high_column_addr = 0x10; break;
391 }
392 for(i = 0; i < (height / 8); i++)
393 {
394 transport_.SendCommand(0xB0 + i);
395 transport_.SendCommand(0x00);
396 transport_.SendCommand(high_column_addr);
397 transport_.SendData(&buffer_[width * i], width);
398 }
399 };
400
404 bool UpdateFinished() { return true; }
405
406 protected:
407 Transport transport_;
408 uint8_t buffer_[width * height / 8];
409};
410
416
422
428
440
446
452
457
462
467
473
478template <size_t width, size_t height, typename Transport>
480{
481 public:
482 struct Config
483 {
484 typename Transport::Config transport_config;
485 };
486
487 void Init(Config config)
488 {
489 transport_.Init(config.transport_config);
490
491 useDma_ = config.transport_config.useDma;
492
493 // Init routine...
494 uint8_t uDispayOffset;
495 uint8_t uMultiplex;
496 switch(height)
497 {
498 case 64:
499 uDispayOffset = 0x60;
500 uMultiplex = 0x7F;
501 break;
502
503 case 80:
504 uDispayOffset = 0x68;
505 uMultiplex = 0x4F;
506 break;
507
508 case 128:
509 default:
510 uDispayOffset = 0x00;
511 uMultiplex = 0x7F;
512 break;
513 }
514
515 // Display Off
516 transport_.SendCommand(0xaE);
517
518 // Memory Mode
519 transport_.SendCommand(0x20);
520
521 // Normal Display
522 transport_.SendCommand(0xA6);
523
524 // Multiplex Ratio
525 transport_.SendCommand(0xA8);
526 transport_.SendCommand(uMultiplex);
527
528 // All On Resume
529 transport_.SendCommand(0xA4);
530
531 // Display Offset
532 transport_.SendCommand(0xD3);
533 transport_.SendCommand(uDispayOffset);
534
535 // Display Clock Divide Ratio
536 transport_.SendCommand(0xD5);
537 transport_.SendCommand(0x80);
538
539 // Pre Charge
540 transport_.SendCommand(0xD9);
541 transport_.SendCommand(0x22);
542
543 // Com Pins
544 transport_.SendCommand(0xDA);
545 transport_.SendCommand(0x12);
546
547 // VCOM Detect
548 transport_.SendCommand(0xDB);
549 transport_.SendCommand(0x35);
550
551 // Contrast Control
552 transport_.SendCommand(0x81);
553 transport_.SendCommand(0x80);
555 // Display On
556 transport_.SendCommand(0xAF);
557 };
558
559 size_t Width() const { return width; };
560 size_t Height() const { return height; };
561
562 void DrawPixel(uint_fast8_t x, uint_fast8_t y, bool on)
563 {
564 if(x >= width || y >= height)
565 return;
566 if(on)
567 buffer_[x + (y / 8) * width] |= (1 << (y % 8));
568 else
569 buffer_[x + (y / 8) * width] &= ~(1 << (y % 8));
570 }
571
572 void Fill(bool on)
573 {
574 for(size_t i = 0; i < sizeof(buffer_); i++)
576 buffer_[i] = on ? 0xff : 0x00;
577 }
578 };
579
583 void Update()
584 {
585 if(useDma_)
586 {
587 transferPagesCount_ = (height / 8);
588 if(transferPagesCount_)
589 {
590 updateing_ = true;
591 TransferPageDma(0);
592 }
593 }
594 else
595 {
596 uint8_t i;
597 uint8_t high_column_addr;
598 switch(height)
599 {
600 case 32: high_column_addr = 0x12; break;
601
602 default: high_column_addr = 0x10; break;
603 }
604 for(i = 0; i < (height / 8); i++)
605 {
606 transport_.SendCommand(0xB0 + i);
607 transport_.SendCommand(0x00);
608 transport_.SendCommand(high_column_addr);
609 transport_.SendData(&buffer_[width * i], width);
611 updateing_ = false;
612 }
613 };
614
618 bool UpdateFinished() { return !updateing_; }
619
620 private:
621 Transport transport_;
622 uint8_t buffer_[width * height / 8];
623 bool updateing_;
624 uint8_t transferPagesCount_;
625 uint8_t transferingPage_;
626 bool useDma_;
627
628 void TransferPageDma(uint8_t page)
629 {
630 transferingPage_ = page;
631
632 uint8_t high_column_addr;
633 switch(height)
634 {
635 case 32: high_column_addr = 0x12; break;
636
637 default: high_column_addr = 0x10; break;
638 }
639 uint8_t commands[] = {static_cast<uint8_t>(0xB0 + transferingPage_),
640 0x00,
641 high_column_addr};
642 transport_.SendCommands(commands, 3);
643 // transport_.SendCommand(0xB0 + transferingPage_);
644 // transport_.SendCommand(0x00);
645 // transport_.SendCommand(high_column_addr);
646 transport_.SendDataDma(&buffer_[width * transferingPage_],
647 width,
648 SpiPageCompleteCallback,
649 this);
650 // transport_.SendDataDma(&buffer_[width * 16], width, SpiPageCompleteCallback, this);
651 }
652
653 void PageTransfered(void)
654 {
655 if(transferingPage_ < transferPagesCount_ - 1)
656 {
657 TransferPageDma(transferingPage_ + 1);
658 }
659 else
660 updateing_ = false;
661 }
662
663 static void SpiPageCompleteCallback(void* context,
666 static_cast<SSD1307Driver*>(context)->PageTransfered();
667 }
668};
669
681
687
693
699
705
706
707}; // namespace daisy
708
709
710#endif
General Purpose I/O control.
Definition gpio.h:22
void Write(bool state)
Changes the state of the GPIO hardware when configured as an OUTPUT.
void Init()
Initialize the GPIO using the internal Config struct.
void Toggle()
flips the current state of the GPIO. If it was HIGH, it will go LOW, and vice versa.
Definition i2c.h:26
Result Init(const Config &config)
Result TransmitBlocking(uint16_t address, uint8_t *data, uint16_t size, uint32_t timeout)
Definition oled_ssd130x.h:472
void Init(Config config)
Definition oled_ssd130x.h:479
size_t Width() const
Definition oled_ssd130x.h:551
bool UpdateFinished()
Definition oled_ssd130x.h:610
void DrawPixel(uint_fast8_t x, uint_fast8_t y, bool on)
Definition oled_ssd130x.h:554
void Update()
Definition oled_ssd130x.h:575
void Fill(bool on)
Definition oled_ssd130x.h:564
size_t Height() const
Definition oled_ssd130x.h:552
Definition oled_ssd130x.h:161
void SendData(uint8_t *buff, size_t size)
Definition oled_ssd130x.h:213
void SendCommand(uint8_t cmd)
Definition oled_ssd130x.h:207
void Init(const Config &config)
Definition oled_ssd130x.h:189
Definition oled_ssd130x.h:67
void SendCommand(uint8_t cmd)
Definition oled_ssd130x.h:123
void SendDataDma(uint8_t *buff, size_t size, SpiHandle::EndCallbackFunctionPtr end_callback, void *context)
Definition oled_ssd130x.h:141
void SendData(uint8_t *buff, size_t size)
Definition oled_ssd130x.h:135
void SendCommands(uint8_t *buff, size_t size)
Definition oled_ssd130x.h:129
void Init(const Config &config)
Definition oled_ssd130x.h:107
Definition oled_ssd130x.h:255
void Update()
Definition oled_ssd130x.h:382
size_t Height() const
Definition oled_ssd130x.h:359
void Fill(bool on)
Definition oled_ssd130x.h:371
size_t Width() const
Definition oled_ssd130x.h:358
void Init(Config config)
Definition oled_ssd130x.h:262
bool UpdateFinished()
Definition oled_ssd130x.h:404
Transport transport_
Definition oled_ssd130x.h:407
void DrawPixel(uint_fast8_t x, uint_fast8_t y, bool on)
Definition oled_ssd130x.h:361
uint8_t buffer_[width *height/8]
Definition oled_ssd130x.h:408
Definition oled_ssd130x.h:17
void Init(const Config &config)
Definition oled_ssd130x.h:38
void SendData(uint8_t *buff, size_t size)
Definition oled_ssd130x.h:49
void SendCommand(uint8_t cmd)
Definition oled_ssd130x.h:43
Definition spi.h:24
Result DmaTransmit(uint8_t *buff, size_t size, SpiHandle::StartCallbackFunctionPtr start_callback, SpiHandle::EndCallbackFunctionPtr end_callback, void *callback_context)
Result BlockingTransmit(uint8_t *buff, size_t size, uint32_t timeout=100)
Result Init(const Config &config)
void(*) EndCallbackFunctionPtr(void *context, Result result)
Definition spi.h:137
Result
Definition spi.h:116
static void Delay(uint32_t delay_ms)
static void DelayTicks(uint32_t delay_ticks)
Hardware defines and helpers for daisy field platform.
Definition index.h:2
@ PORTX
Definition daisy_core.h:188
@ PORTB
Definition daisy_core.h:178
@ PORTC
Definition daisy_core.h:179
@ PORTD
Definition daisy_core.h:180
@ PORTG
Definition daisy_core.h:183
daisy::SSD1307Driver< 128, 64, SSD130x4WireSpiTransport > SSD13074WireSpi128x64Driver
Definition oled_ssd130x.h:665
Definition i2c.h:30
struct daisy::I2CHandle::Config::@15 pin_config
Mode mode
Definition i2c.h:65
Pin scl
Definition i2c.h:60
Speed speed
Definition i2c.h:64
Peripheral periph
Definition i2c.h:57
Pin sda
Definition i2c.h:61
representation of hardware port/pin combination
Definition daisy_core.h:193
Definition oled_ssd130x.h:475
Transport::Config transport_config
Definition oled_ssd130x.h:476
Definition oled_ssd130x.h:164
void Defaults()
Definition oled_ssd130x.h:178
Config()
Definition oled_ssd130x.h:165
uint32_t sclk_delay
Definition oled_ssd130x.h:172
Pin reset
Definition oled_ssd130x.h:176
Pin mosi
Definition oled_ssd130x.h:174
struct daisy::SSD130x4WireSoftSpiTransport::Config::@10 pin_config
Pin dc
Definition oled_ssd130x.h:175
Pin sclk
Definition oled_ssd130x.h:173
Definition oled_ssd130x.h:70
Pin reset
Definition oled_ssd130x.h:80
Pin dc
Definition oled_ssd130x.h:79
SpiHandle::Config spi_config
Definition oled_ssd130x.h:76
void Defaults()
Definition oled_ssd130x.h:83
struct daisy::SSD130x4WireSpiTransport::Config::@9 pin_config
bool useDma
Definition oled_ssd130x.h:82
Config()
Definition oled_ssd130x.h:71
Definition oled_ssd130x.h:258
Transport::Config transport_config
Definition oled_ssd130x.h:259
Definition oled_ssd130x.h:20
uint8_t i2c_address
Definition oled_ssd130x.h:27
void Defaults()
Definition oled_ssd130x.h:28
I2CHandle::Config i2c_config
Definition oled_ssd130x.h:26
Config()
Definition oled_ssd130x.h:21
Definition spi.h:27
ClockPolarity clock_polarity
Definition spi.h:104
Peripheral periph
Definition spi.h:100
Pin nss
Definition spi.h:88
struct daisy::SpiHandle::Config::@18 pin_config
Mode mode
Definition spi.h:101
Pin mosi
Definition spi.h:87
Pin sclk
Definition spi.h:85
ClockPhase clock_phase
Definition spi.h:105
BaudPrescaler baud_prescaler
Definition spi.h:107
Pin miso
Definition spi.h:86
Direction direction
Definition spi.h:102
unsigned long datasize
Definition spi.h:103