roo_display
API Documentation for roo_display
Loading...
Searching...
No Matches
ssd1327.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4
9#include "roo_threads.h"
10#include "roo_threads/thread.h"
11
12namespace roo_display {
13namespace ssd1327 {
14
15enum Command { CASET = 0x15, RASET = 0x75 };
16
17static const int16_t kWidth = 128;
18static const int16_t kHeight = 128;
19
21
22template <typename Transport>
24 public:
26
27 Ssd1327Target() : transport_(), xy_swap_(false) {}
28
29 void init() {
30 transport_.init();
31 sleep_ms(200);
32 begin();
33 const uint8_t init[] = {
34 0xAE, 0x15, 0x00, 0x7F, 0x75, 0x00, 0x7F, 0x81, 0x53, 0xA0, 0x42, 0xA1,
35 0x00, 0xA2, 0x00, 0xA4, 0xA8, 0x7F, 0xB1, 0xF1, 0xB3, 0xC1, 0xAB, 0x01,
36 0xB6, 0x01, 0xBE, 0x07, 0xBC, 0x08, 0xD5, 0x62, 0xFD, 0x12};
37 writeCommand(init, sizeof(init));
38 end();
39 sleep_ms(200);
40 begin();
41 writeCommand(0xAF);
42 end();
43 }
44
45 int16_t width() const { return kWidth; }
46 int16_t height() const { return kHeight; }
47
48 void begin() {
49 transport_.beginWriteOnlyTransaction();
50 transport_.begin();
51 }
52
53 void end() {
54 transport_.end();
55 transport_.endTransaction();
56 }
57
59 int16_t x1, int16_t y1) {
60 if (x0 < 0) x0 = 0;
61 if (y0 < 0) y0 = 0;
62 if (x1 >= kWidth) x1 = kWidth - 1;
63 if (y1 >= kHeight) y1 = kHeight - 1;
64 if (x0 > x1 || y0 > y1) return;
65 if (xy_swap_) {
66 y0 &= ~1;
67 y1 |= 1;
68 setYaddr(x0, x1);
69 setXaddr(y0, y1);
70 const uint8_t* ptr = reinterpret_cast<const uint8_t*>(
71 buffer.buffer() + (x0 + y0 * kWidth) / 2);
72 uint32_t offset;
73 for (int16_t x = (x0 & ~1); x <= (x1 | 1);) {
74 if (x++ >= x0) {
75 offset = 0;
76 for (int16_t y = y0; y <= y1; y += 2) {
77 uint8_t datum = (ptr[offset] & 0xF0) + (ptr[offset + 64] >> 4);
78 transport_.write(datum);
79 offset += 128;
80 }
81 }
82 if (x++ <= x1) {
83 offset = 0;
84 for (int16_t y = y0; y <= y1; y += 2) {
85 uint8_t datum = (ptr[offset] << 4) + (ptr[offset + 64] & 0x0F);
86 transport_.write(datum);
87 offset += 128;
88 }
89 }
90 ptr++;
91 }
92 } else {
93 x0 &= ~1;
94 x1 |= 1;
95 setXaddr(x0, x1);
96 setYaddr(y0, y1);
97 const uint8_t* ptr = reinterpret_cast<const uint8_t*>(
98 buffer.buffer() + (x0 + y0 * kWidth) / 2);
99 for (int16_t y = y0; y <= y1; ++y) {
100 uint32_t offset = 0;
101 for (int16_t x = x0; x <= x1; x += 2) {
102 uint8_t datum = ptr[offset];
103 // TODO(dawidk): block-write is possible here, and perhaps it would be
104 // faster. One gotcha is that SPI.writeBytes() doesn't guarantee the
105 // source data won't be mutated, so technically we'd need to use an
106 // extra buffer, perhaps with zero-buffer specializations for
107 // platforms that don't mutate.
108 transport_.write(datum);
109 offset++;
110 }
111 ptr += 64;
112 }
113 }
114 }
115
116 void setOrientation(Orientation orientation) {
117 xy_swap_ = orientation.isXYswapped();
118 const uint8_t remap[] = {
119 0xA0, static_cast<uint8_t>(
120 0x40 | (orientation.isLeftToRight() ? 0x02 : 0x01) |
121 (orientation.isTopToBottom() ? 0x00 : 0x10))};
122 writeCommand(remap, 2);
123 }
124
125 private:
126 void setXaddr(uint16_t x0, uint16_t x1) __attribute__((always_inline)) {
127 const uint8_t caset[] = {CASET, static_cast<uint8_t>(x0 / 2),
128 static_cast<uint8_t>(x1 / 2)};
129 writeCommand(caset, 3);
130 }
131
132 void setYaddr(uint16_t y0, uint16_t y1) __attribute__((always_inline)) {
133 const uint8_t raset[] = {RASET, static_cast<uint8_t>(y0),
134 static_cast<uint8_t>(y1)};
135 writeCommand(raset, 3);
136 }
137
138 void writeCommand(uint8_t c) __attribute__((always_inline)) {
139 transport_.cmdBegin();
140 transport_.write(c);
141 transport_.cmdEnd();
142 }
143
144 void writeCommand(const uint8_t* c, uint32_t size)
145 __attribute__((always_inline)) {
146 transport_.cmdBegin();
147 transport_.writeBytes((const roo::byte*)c, size);
148 transport_.cmdEnd();
149 }
150
151 void sleep_ms(uint32_t ms) {
152 roo::this_thread::sleep_for(roo_time::Millis(ms));
153 }
154
155 Transport transport_;
156 bool xy_swap_;
157};
158
159} // namespace ssd1327
160
161template <typename Transport>
163
164template <int pinCS, int pinDC, int pinRST, typename Spi = DefaultSpi,
168
169} // namespace roo_display
Represents the orientation of a display device.
Definition orientation.h:25
bool isLeftToRight() const
Return whether horizontal direction is left-to-right.
Definition orientation.h:98
bool isTopToBottom() const
Return whether vertical direction is top-to-bottom.
bool isXYswapped() const
Return whether x maps to the vertical direction.
Definition orientation.h:90
void setOrientation(Orientation orientation)
Definition ssd1327.h:116
void flushRect(ConstDramRaster< Grayscale4 > &buffer, int16_t x0, int16_t y0, int16_t x1, int16_t y1)
Definition ssd1327.h:58
static const int16_t kWidth
Definition ssd1327.h:17
SpiSettings< 16000000, kSpiMsbFirst, kSpiMode0 > DefaultSpiSettings
Definition ssd1327.h:20
static const int16_t kHeight
Definition ssd1327.h:18
Defines 140 opaque HTML named colors.