1919
2020#include " Inkplate.h"
2121
22- #if defined(ARDUINO_INKPLATECOLOR) || defined(ARDUINO_INKPLATE2) || defined(ARDUINO_INKPLATE4) || \
23- defined (ARDUINO_INKPLATE7)
24- Inkplate::Inkplate() : Adafruit_GFX(E_INK_WIDTH, E_INK_HEIGHT), Graphics(E_INK_WIDTH, E_INK_HEIGHT)
25- #else
26-
27- Inkplate::Inkplate (uint8_t _mode) : Adafruit_GFX(E_INK_WIDTH, E_INK_HEIGHT), Graphics(E_INK_WIDTH, E_INK_HEIGHT)
28- #endif
29- {
30- #if !defined(ARDUINO_INKPLATECOLOR) && !defined(ARDUINO_INKPLATE2) && !defined(ARDUINO_INKPLATE4) && \
31- !defined (ARDUINO_INKPLATE7)
32- setDisplayMode (_mode);
33- #endif
34- }
35-
36- /* *
37- * @brief clearDisplay function clears memory buffer for display
38- *
39- * @note This does not clear the actual display, only the memory buffer, you need to call
40- * display() function after this to clear the display
41- */
42- void Inkplate::clearDisplay ()
43- {
44- #if defined(ARDUINO_INKPLATECOLOR)
45- memset (DMemory4Bit, WHITE << 4 | WHITE, E_INK_WIDTH * E_INK_HEIGHT / 2 );
46- #elif defined(ARDUINO_INKPLATE2)
47- memset (DMemory4Bit, 0xFF , E_INK_WIDTH * E_INK_HEIGHT / 4 );
48- #elif defined(ARDUINO_INKPLATE4)
49- memset (DMemory4Bit, 0xFF , (E_INK_WIDTH * E_INK_HEIGHT / 8 ));
50- memset (DMemory4Bit + (E_INK_WIDTH * E_INK_HEIGHT / 8 ), 0x00 , (E_INK_WIDTH * E_INK_HEIGHT / 8 ));
51- #elif defined(ARDUINO_INKPLATE7)
52- memset (DMemory4Bit, 0x33 , (E_INK_WIDTH * E_INK_HEIGHT / 2 ));
53- #else
54- // Clear 1 bit per pixel display buffer
55- if (getDisplayMode () == 0 )
56- memset (_partial, 0 , E_INK_WIDTH * E_INK_HEIGHT / 8 );
57-
58- // Clear 3 bit per pixel display buffer
59- if (getDisplayMode () == 1 )
60- memset (DMemory4Bit, 255 , E_INK_WIDTH * E_INK_HEIGHT / 2 );
61- #endif
62- }
63-
64- #if !defined(ARDUINO_INKPLATECOLOR) && !defined(ARDUINO_INKPLATE2) && !defined(ARDUINO_INKPLATE4) && \
65- !defined (ARDUINO_INKPLATE7)
66-
67- /* *
68- * @brief display function update display with new data from buffer
69- *
70- * @param bool leaveOn
71- * if set to 1, it will disable turning supply for eink after
72- * display update in order to save some time needed for power supply
73- * to save some time at next display update or increase refreshing speed
74- */
75- void Inkplate::display (bool leaveOn)
22+ // --------------------------USER FUNCTIONS--------------------------------------------
23+ Inkplate::Inkplate (uint8_t mode) : Adafruit_GFX(E_INK_WIDTH, E_INK_HEIGHT), Graphics(E_INK_WIDTH, E_INK_HEIGHT)
7624{
77- if (getDisplayMode () == 0 )
78- display1b (leaveOn);
79- else if (getDisplayMode () == 1 )
80- display3b (leaveOn);
25+ _mode=mode;
8126}
8227
83- /* *
84- * @brief preloadScreen function copy data from partial to data buffer
85- */
86- void Inkplate::preloadScreen ()
28+ void Inkplate::begin ()
8729{
88- memcpy (DMemoryNew, _partial, E_INK_WIDTH * E_INK_HEIGHT / 8 );
89- }
9030
91- /* *
92- * @brief einkOn turns on supply for epaper display (TPS65186) [+15 VDC,
93- * -15VDC, +22VDC, -20VDC, +3.3VDC, VCOM]
94- *
95- * @note its important to use this order when turning epaper on.
96- * using wrong order can irreparably damage epaper
97- *
98- * @return 1 if succesfully turned on, 0 if failed
99- */
100- int Inkplate::einkOn ()
101- {
102- if (getPanelState () == 1 )
103- return 1 ;
104- WAKEUP_SET;
105- delay (5 );
31+ // Check if the initializaton of the library already done.
32+ // In the case of already initialized library, return form the begin() funtion to
33+ // avoiid any memory leaks, multiple initializaton of the peripherals etc.
34+ if (_beginDone == 1 )
35+ return ;
10636
107- #ifdef ARDUINO_INKPLATE6PLUSV2
108- if (pwrMode != INKPLATE_USB_PWR_ONLY)
109- {
110- // Enable all rails
111- Wire.beginTransmission (0x48 );
112- Wire.write (0x01 );
113- Wire.write (B00100000);
114- Wire.endTransmission ();
115- }
116- #else
117- // Enable all rails
118- Wire.beginTransmission (0x48 );
119- Wire.write (0x01 );
120- Wire.write (B00100000);
121- Wire.endTransmission ();
122- #endif
37+ Wire.begin ();
12338
124- // Modify power up sequence.
125- Wire.beginTransmission (0x48 );
126- Wire.write (0x09 );
127- Wire.write (B11100100);
128- Wire.endTransmission ();
39+ // Init low level driver for EPD.
40+ initDriver (this );
12941
130- // Modify power down sequence (VEE and VNEG are swapped)
131- Wire.beginTransmission (0x48 );
132- Wire.write (0x0b );
133- Wire.write (B00011011);
134- Wire.endTransmission ();
42+ // Forward the display mode to the EPD driver
43+ selectDisplayMode (_mode);
13544
136- pinsAsOutputs ();
137- LE_CLEAR;
138- #if !defined(ARDUINO_ESP32_DEV) && !defined(ARDUINO_INKPLATE6V2) && !defined(ARDUINO_INKPLATE6FLICK)
139- CL_CLEAR;
140- #endif
141- SPH_SET;
142- GMOD_SET;
143- SPV_SET;
144- CKV_CLEAR;
145- OE_CLEAR;
146- PWRUP_SET;
147- setPanelState (1 );
45+ // Clean frame buffers.
46+ clearDisplay ();
14847
149- unsigned long timer = millis ();
150- do
151- {
152- delay (1 );
153- } while ((readPowerGood () != PWR_GOOD_OK) && (millis () - timer) < 250 );
154- if ((millis () - timer) >= 250 )
155- {
156- einkOff ();
157- return 0 ;
158- }
48+ // Block multiple inits.
49+ _beginDone = 1 ;
15950
160- VCOM_SET;
161- OE_SET;
162-
163- return 1 ;
16451}
165-
166- /* *
167- * @brief einkOff turns off epaper power supply and put all digital IO
168- * pins in high Z state
169- */
170- void Inkplate::einkOff ()
52+ void Inkplate::writePixel (int16_t x, int16_t y, uint16_t color)
17153{
172- if (getPanelState () == 0 )
54+ int16_t x0 = x;
55+ int16_t y0 = y;
56+ if (x0 > width () - 1 || y0 > height () - 1 || x0 < 0 || y0 < 0 )
17357 return ;
174- VCOM_CLEAR;
175- OE_CLEAR;
176- GMOD_CLEAR;
177- #if !defined(ARDUINO_ESP32_DEV) && !defined(ARDUINO_INKPLATE6V2) && !defined(ARDUINO_INKPLATE6FLICK)
178- GPIO.out &= ~(DATA | LE | CL);
179- #else
180- LE_CLEAR;
181- #endif
182- CKV_CLEAR;
183- SPH_CLEAR;
184- SPV_CLEAR;
185- PWRUP_CLEAR;
18658
187- unsigned long timer = millis ();
188- do
59+ switch (rotation)
18960 {
190- delay (1 );
191- } while ((readPowerGood () != 0 ) && (millis () - timer) < 250 );
192-
193- // Do not disable WAKEUP if older Inkplate6Plus is used.
194- #ifndef ARDUINO_INKPLATE6PLUS
195- #ifdef ARDUINO_INKPLATE6PLUSV2
196- if (pwrMode != INKPLATE_USB_PWR_ONLY)
197- WAKEUP_CLEAR;
198- #else
199- WAKEUP_CLEAR; // Disable 3V3 Switch for ePaper.
200- Wire.beginTransmission (0x48 );
201- Wire.write (0x01 );
202- Wire.write (B00000000);
203- Wire.endTransmission ();
204- #endif
205- #endif
206-
207- pinsZstate ();
208-
209- setPanelState (0 );
210- }
211-
212- /* *
213- * @brief readPowerGood reads ok status for each rail
214- *
215- * @return power good status register
216- */
217- uint8_t Inkplate::readPowerGood ()
218- {
219- Wire.beginTransmission (0x48 );
220- Wire.write (0x0F );
221- Wire.endTransmission ();
222-
223- Wire.requestFrom (0x48 , 1 );
224- return Wire.read ();
225- }
226-
227- // LOW LEVEL FUNCTIONS
228-
229- /* *
230- * @brief vscan_start starts writing new frame and skips first two lines
231- * that are invisible on screen
232- */
233- void Inkplate::vscan_start ()
234- {
235- CKV_SET;
236- delayMicroseconds (7 );
237- SPV_CLEAR;
238- delayMicroseconds (10 );
239- CKV_CLEAR;
240- delayMicroseconds (0 );
241- CKV_SET;
242- delayMicroseconds (8 );
243- SPV_SET;
244- delayMicroseconds (10 );
245- CKV_CLEAR;
246- delayMicroseconds (0 );
247- CKV_SET;
248- delayMicroseconds (18 );
249- CKV_CLEAR;
250- delayMicroseconds (0 );
251- CKV_SET;
252- delayMicroseconds (18 );
253- CKV_CLEAR;
254- delayMicroseconds (0 );
255- CKV_SET;
256- }
257-
258- /* *
259- * @brief hscan_start starts writing data into current row
260- *
261- * @param uint32_t _d
262- * data to be written into current row
263- */
264- void Inkplate::hscan_start (uint32_t _d)
265- {
266- #if !defined(ARDUINO_ESP32_DEV) && !defined(ARDUINO_INKPLATE6V2)
267- SPH_CLEAR;
268- GPIO.out_w1ts = (_d) | CL;
269- GPIO.out_w1tc = DATA | CL;
270- SPH_SET;
271- CKV_SET;
272- #endif
273- }
274-
275- /* *
276- * @brief vscan_end ends current row and prints data to screen
277- */
278- void Inkplate::vscan_end ()
279- {
280- CKV_CLEAR;
281- LE_SET;
282- LE_CLEAR;
283- delayMicroseconds (0 );
284- }
285-
286- /* *
287- * @brief pinsZstate sets all tps pins at high z state
288- *
289- * @note this is used only when turning off epaper
290- */
291- void Inkplate::pinsZstate ()
292- {
293- pinMode (2 , INPUT);
294- pinMode (32 , INPUT);
295- pinMode (33 , INPUT);
296- pinModeInternal (IO_INT_ADDR, ioRegsInt, OE, INPUT);
297- pinModeInternal (IO_INT_ADDR, ioRegsInt, GMOD, INPUT);
298- pinModeInternal (IO_INT_ADDR, ioRegsInt, SPV, INPUT);
299-
300- // Set up the EPD Data and CL pins for I2S (only on Inkplate6).
301- pinMode (0 , INPUT);
302- pinMode (4 , INPUT);
303- pinMode (5 , INPUT);
304- pinMode (18 , INPUT);
305- pinMode (19 , INPUT);
306- pinMode (23 , INPUT);
307- pinMode (25 , INPUT);
308- pinMode (26 , INPUT);
309- pinMode (27 , INPUT);
61+ case 1 :
62+ _swap_int16_t (x0, y0);
63+ x0 = height () - x0 - 1 ;
64+ break ;
65+ case 2 :
66+ x0 = width () - x0 - 1 ;
67+ y0 = height () - y0 - 1 ;
68+ break ;
69+ case 3 :
70+ _swap_int16_t (x0, y0);
71+ y0 = width () - y0 - 1 ;
72+ break ;
73+ }
31074
311- #if defined(ARDUINO_ESP32_DEV) || defined(ARDUINO_INKPLATE6V2) || defined(ARDUINO_INKPLATE5V2) || \
312- defined (ARDUINO_INKPLATE6FLICK)
313- // Disable clock for the EPD.
314- myI2S->conf1 .tx_stop_en = 0 ;
315- #endif
75+ if (getDisplayMode () == 0 )
76+ {
77+ int x = x0 >> 3 ;
78+ int x_sub = x0 & 7 ;
79+ uint8_t temp = *(_partial + ((E_INK_WIDTH >> 3 ) * y0) + x);
80+ *(_partial + (E_INK_WIDTH / 8 * y0) + x) = (~pixelMaskLUT[x_sub] & temp) | (color ? pixelMaskLUT[x_sub] : 0 );
81+ }
82+ else
83+ {
84+ color &= 7 ;
85+ int x = x0 >> 1 ;
86+ int x_sub = x0 & 1 ;
87+ uint8_t temp;
88+ temp = *(DMemory4Bit + (E_INK_WIDTH >> 1 ) * y0 + x);
89+ *(DMemory4Bit + (E_INK_WIDTH >> 1 ) * y0 + x) = (pixelMaskGLUT[x_sub] & temp) | (x_sub ? color : color << 4 );
90+ }
31691}
31792
318- /* *
319- * @brief pinsAsOutputs sets all tps pins as outputs
320- */
321- void Inkplate::pinsAsOutputs ()
93+ void Inkplate::drawPixel (int16_t x, int16_t y, uint16_t color)
32294{
323- pinMode (2 , OUTPUT);
324- pinMode (32 , OUTPUT);
325- pinMode (33 , OUTPUT);
326- pinModeInternal (IO_INT_ADDR, ioRegsInt, OE, OUTPUT);
327- pinModeInternal (IO_INT_ADDR, ioRegsInt, GMOD, OUTPUT);
328- pinModeInternal (IO_INT_ADDR, ioRegsInt, SPV, OUTPUT);
329-
330- #if defined(ARDUINO_ESP32_DEV) || defined(ARDUINO_INKPLATE6V2) || defined(ARDUINO_INKPLATE5V2) || \
331- defined (ARDUINO_INKPLATE6FLICK)
332- // Set up the EPD Data and CL pins for I2S.
333- setI2S1pin (0 , I2S1O_BCK_OUT_IDX, 0 );
334- setI2S1pin (4 , I2S1O_DATA_OUT0_IDX, 0 );
335- setI2S1pin (5 , I2S1O_DATA_OUT1_IDX, 0 );
336- setI2S1pin (18 , I2S1O_DATA_OUT2_IDX, 0 );
337- setI2S1pin (19 , I2S1O_DATA_OUT3_IDX, 0 );
338- setI2S1pin (23 , I2S1O_DATA_OUT4_IDX, 0 );
339- setI2S1pin (25 , I2S1O_DATA_OUT5_IDX, 0 );
340- setI2S1pin (26 , I2S1O_DATA_OUT6_IDX, 0 );
341- setI2S1pin (27 , I2S1O_DATA_OUT7_IDX, 0 );
342-
343- // Start sending clock to the EPD.
344- myI2S->conf1 .tx_stop_en = 1 ;
345- #else
346- pinMode (0 , OUTPUT);
347- pinMode (4 , OUTPUT);
348- pinMode (5 , OUTPUT);
349- pinMode (18 , OUTPUT);
350- pinMode (19 , OUTPUT);
351- pinMode (23 , OUTPUT);
352- pinMode (25 , OUTPUT);
353- pinMode (26 , OUTPUT);
354- pinMode (27 , OUTPUT);
355- #endif
95+ writePixel (x,y,color);
35696}
357-
358- #endif
97+ void Inkplate::setRotation (uint8_t r){}
0 commit comments