55SPIClass spi2 (2 );
66SdFat sd (&spi2);
77
8-
8+ /* *
9+ *
10+ * @brief writePixelInternal funtion sets pixel data for (x, y) pixel position
11+ *
12+ * @param int16_t x0
13+ * default position for x, will be changed depending on rotation
14+ * @param int16_t y0
15+ * default position for y, will be changed depending on rotation
16+ * @param uint16_t color
17+ * pixel color, in 3bit mode have values in range 0-7
18+ *
19+ * @note If x0 or y0 are out of inkplate screen borders, function will
20+ * exit.
21+ */
922void EPDDriver::writePixelInternal (int16_t x, int16_t y, uint16_t color)
1023{
1124 int16_t x0 = x;
@@ -65,119 +78,23 @@ int EPDDriver::initDriver(Inkplate *_inkplatePtr)
6578 // If the driver was already initialized, skip current initialization
6679 if (_beginDone == 1 )
6780 return 0 ;
68-
81+
82+ // Save the given inkplate pointer for internal use
6983 _inkplate = _inkplatePtr;
7084
71- internalIO.begin (IO_INT_ADDR);
72- externalIO.begin (IO_EXT_ADDR);
73-
74- internalIO.digitalWrite (9 , LOW);
75-
85+ // Initialize the image processing functionalities
7686 beginImage (_inkplatePtr);
7787
78- _inkplate = _inkplatePtr;
79-
80-
81- memset (internalIO._ioExpanderRegs , 0 , 22 );
82- memset (externalIO._ioExpanderRegs , 0 , 22 );
83-
84- internalIO.pinMode (VCOM, OUTPUT);
85- internalIO.pinMode (PWRUP, OUTPUT);
86- internalIO.pinMode (WAKEUP, OUTPUT);
87- internalIO.pinMode (GPIO0_ENABLE, OUTPUT);
88- internalIO.digitalWrite (GPIO0_ENABLE, 1 );
89-
90- internalIO.digitalWrite (WAKEUP, 1 );
91- WAKEUP_SET;
92- delay (1 );
93- Wire.beginTransmission (0x48 );
94- Wire.write (0x09 );
95- Wire.write (0B00011011 ); // Power up seq.
96- Wire.write (0B00000000 ); // Power up delay (3mS per rail)
97- Wire.write (0B00011011 ); // Power down seq.
98- Wire.write (0B00000000 ); // Power down delay (6mS per rail)
99- Wire.endTransmission ();
100- delay (1 );
101- internalIO.digitalWrite (WAKEUP, 0 );
102- WAKEUP_CLEAR;
103-
104- // Set all pins of seconds I/O expander to outputs, low.
105- // For some reason, it draw more current in deep sleep when pins are set as
106- // inputs...
88+ // Initialize the all GPIOs
89+ gpioInit ();
10790
108- for (uint32_t i = 0 ; i < 256 ; ++i)
109- pinLUT[i] = ((i & B00000011) << 4 ) | (((i & B00001100) >> 2 ) << 18 ) | (((i & B00010000) >> 4 ) << 23 ) |
110- (((i & B11100000) >> 5 ) << 25 );
11191
112- for (int i = 0 ; i < 15 ; i++)
113- {
114- externalIO.pinMode (i, OUTPUT);
115- externalIO.digitalWrite (i, LOW);
116- }
117-
118- // For same reason, unused pins of first I/O expander have to be also set as
119- // outputs, low.
120- internalIO.pinMode (14 , OUTPUT);
121- internalIO.pinMode (15 , OUTPUT);
122- internalIO.digitalWrite (14 , LOW);
123- internalIO.digitalWrite (15 , LOW);
124-
125- // Set SPI pins to input to reduce power consumption in deep sleep
126- pinMode (12 , INPUT);
127- pinMode (13 , INPUT);
128- pinMode (14 , INPUT);
129- pinMode (15 , INPUT);
130-
131- // And also disable uSD card supply
132- internalIO.pinMode (SD_PMOS_PIN, INPUT);
133-
134- // CONTROL PINS
135- pinMode (0 , OUTPUT);
136- pinMode (2 , OUTPUT);
137- pinMode (32 , OUTPUT);
138- pinMode (33 , OUTPUT);
139- internalIO.pinMode (OE, OUTPUT);
140- internalIO.pinMode (GMOD, OUTPUT);
141- internalIO.pinMode (SPV, OUTPUT);
142-
143- // DATA PINS
144- pinMode (4 , OUTPUT); // D0
145- pinMode (5 , OUTPUT);
146- pinMode (18 , OUTPUT);
147- pinMode (19 , OUTPUT);
148- pinMode (23 , OUTPUT);
149- pinMode (25 , OUTPUT);
150- pinMode (26 , OUTPUT);
151- pinMode (27 , OUTPUT); // D7
152-
153- internalIO.pinMode (10 , OUTPUT);
154- internalIO.pinMode (11 , OUTPUT);
155- internalIO.pinMode (12 , OUTPUT);
156- internalIO.digitalWrite (10 , LOW);
157- internalIO.digitalWrite (11 , LOW);
158- internalIO.digitalWrite (12 , LOW);
159- // Battery voltage Switch MOSFET
160- internalIO.pinMode (9 , OUTPUT);
161- internalIO.digitalWrite (9 , LOW);
162-
163- // Initialize all the framebuffers
164- DMemoryNew = (uint8_t *)ps_malloc (E_INK_WIDTH * E_INK_HEIGHT / 8 );
165- _partial = (uint8_t *)ps_malloc (E_INK_WIDTH * E_INK_HEIGHT / 8 );
166- _pBuffer = (uint8_t *)ps_malloc (E_INK_WIDTH * E_INK_HEIGHT / 4 );
167- DMemory4Bit = (uint8_t *)ps_malloc (E_INK_WIDTH * E_INK_HEIGHT / 2 );
168- GLUT = (uint32_t *)malloc (256 * 9 * sizeof (uint32_t ));
169- GLUT2 = (uint32_t *)malloc (256 * 9 * sizeof (uint32_t ));
170- if (DMemoryNew == NULL || _partial == NULL || _pBuffer == NULL || DMemory4Bit == NULL || GLUT == NULL ||
171- GLUT2 == NULL )
92+ if (!initializeFramebuffers ())
17293 {
17394 return 0 ;
17495 }
175- // Set all the framebuffers to White at start
176- memset (DMemoryNew, 0 , E_INK_WIDTH * E_INK_HEIGHT / 8 );
177- memset (_partial, 0 , E_INK_WIDTH * E_INK_HEIGHT / 8 );
178- memset (_pBuffer, 0 , E_INK_WIDTH * E_INK_HEIGHT / 4 );
179- memset (DMemory4Bit, 255 , E_INK_WIDTH * E_INK_HEIGHT / 2 );
18096
97+ // Calculate color LUTs to optimize drawing to the screen
18198 calculateLUTs ();
18299
183100 _beginDone = 1 ;
@@ -246,11 +163,24 @@ void EPDDriver::vscan_end()
246163 delayMicroseconds (0 );
247164}
248165
166+ /* *
167+ * @brief sets the current display mode of the e-ink display
168+ *
169+ * @param uint8_t
170+ * if set to 1, it will be set to grayscale mode
171+ * if set to 0, set to BW mode
172+ */
249173void EPDDriver::selectDisplayMode (uint8_t displayMode)
250174{
251175 _displayMode = displayMode;
252176}
253177
178+ /* *
179+ * @brief clearDisplay function clears memory buffer for display
180+ *
181+ * @note This does not clear the actual display, only the memory buffer, you need to call
182+ * display() function after this to clear the display
183+ */
254184void EPDDriver::clearDisplay ()
255185{
256186 // Clear 1 bit per pixel display buffer
@@ -262,6 +192,14 @@ void EPDDriver::clearDisplay()
262192 memset (DMemory4Bit, 255 , E_INK_WIDTH * E_INK_HEIGHT / 2 );
263193}
264194
195+ /* *
196+ * @brief display function update display with new data from buffer
197+ *
198+ * @param bool leaveOn
199+ * if set to 1, it will disable turning supply for eink after
200+ * display update in order to save some time needed for power supply
201+ * to save some time at next display update or increase refreshing speed
202+ */
265203void EPDDriver::display (bool _leaveOn)
266204{
267205 if (_displayMode == 0 )
@@ -637,6 +575,21 @@ void EPDDriver::einkOff()
637575 setPanelState (0 );
638576}
639577
578+ void EPDDriver::pmicBegin ()
579+ {
580+ WAKEUP_SET;
581+ delay (1 );
582+ Wire.beginTransmission (0x48 );
583+ Wire.write (0x09 );
584+ Wire.write (0B00011011 ); // Power up seq.
585+ Wire.write (0B00000000 ); // Power up delay (3mS per rail)
586+ Wire.write (0B00011011 ); // Power down seq.
587+ Wire.write (0B00000000 ); // Power down delay (6mS per rail)
588+ Wire.endTransmission ();
589+ delay (1 );
590+ WAKEUP_CLEAR;
591+ }
592+
640593
641594/* *
642595 * @brief pinsAsOutputs sets all tps pins as outputs
@@ -781,6 +734,116 @@ uint8_t EPDDriver::getDisplayMode()
781734 return _displayMode;
782735}
783736
737+ /* *
738+ * @brief Initializes the internal and external IO expanders,
739+ * Configures all of the data and control pins for the
740+ * EPD Driver.
741+ */
742+ void EPDDriver::gpioInit ()
743+ {
744+ internalIO.begin (IO_INT_ADDR);
745+ externalIO.begin (IO_EXT_ADDR);
746+
747+ internalIO.digitalWrite (9 , LOW);
748+
749+ // Set all IO expander registers to 0
750+ memset (internalIO._ioExpanderRegs , 0 , 22 );
751+ memset (externalIO._ioExpanderRegs , 0 , 22 );
752+
753+ internalIO.pinMode (VCOM, OUTPUT);
754+ internalIO.pinMode (PWRUP, OUTPUT);
755+ internalIO.pinMode (WAKEUP, OUTPUT);
756+ internalIO.pinMode (GPIO0_ENABLE, OUTPUT);
757+ internalIO.digitalWrite (GPIO0_ENABLE, 1 );
758+
759+ // For same reason, unused pins of first I/O expander have to be also set as
760+ // outputs, low.
761+ internalIO.pinMode (14 , OUTPUT);
762+ internalIO.pinMode (15 , OUTPUT);
763+ internalIO.digitalWrite (14 , LOW);
764+ internalIO.digitalWrite (15 , LOW);
765+
766+ // Set SPI pins to input to reduce power consumption in deep sleep
767+ pinMode (12 , INPUT);
768+ pinMode (13 , INPUT);
769+ pinMode (14 , INPUT);
770+ pinMode (15 , INPUT);
771+
772+ // And also disable uSD card supply
773+ internalIO.pinMode (SD_PMOS_PIN, INPUT);
774+
775+ // CONTROL PINS
776+ pinMode (0 , OUTPUT);
777+ pinMode (2 , OUTPUT);
778+ pinMode (32 , OUTPUT);
779+ pinMode (33 , OUTPUT);
780+ internalIO.pinMode (OE, OUTPUT);
781+ internalIO.pinMode (GMOD, OUTPUT);
782+ internalIO.pinMode (SPV, OUTPUT);
783+
784+ // DATA PINS
785+ pinMode (4 , OUTPUT); // D0
786+ pinMode (5 , OUTPUT);
787+ pinMode (18 , OUTPUT);
788+ pinMode (19 , OUTPUT);
789+ pinMode (23 , OUTPUT);
790+ pinMode (25 , OUTPUT);
791+ pinMode (26 , OUTPUT);
792+ pinMode (27 , OUTPUT); // D7
793+
794+ internalIO.pinMode (10 , OUTPUT);
795+ internalIO.pinMode (11 , OUTPUT);
796+ internalIO.pinMode (12 , OUTPUT);
797+ internalIO.digitalWrite (10 , LOW);
798+ internalIO.digitalWrite (11 , LOW);
799+ internalIO.digitalWrite (12 , LOW);
800+ // Battery voltage Switch MOSFET
801+ internalIO.pinMode (9 , OUTPUT);
802+ internalIO.digitalWrite (9 , LOW);
803+
804+ // Set all pins of seconds I/O expander to outputs, low.
805+ // For some reason, it draw more current in deep sleep when pins are set as
806+ // inputs...
807+
808+ for (uint32_t i = 0 ; i < 256 ; ++i)
809+ pinLUT[i] = ((i & B00000011) << 4 ) | (((i & B00001100) >> 2 ) << 18 ) | (((i & B00010000) >> 4 ) << 23 ) |
810+ (((i & B11100000) >> 5 ) << 25 );
811+
812+ for (int i = 0 ; i < 15 ; i++)
813+ {
814+ externalIO.pinMode (i, OUTPUT);
815+ externalIO.digitalWrite (i, LOW);
816+ }
817+ }
818+
819+ /* *
820+ * @brief initializeFramebuffers allocates memory to be used
821+ * by specific display modes of the display
822+ *
823+ * @return returns 0 if allocation failed, 1 if it succeeded
824+ */
825+ uint8_t EPDDriver::initializeFramebuffers ()
826+ {
827+ // Initialize all the framebuffers
828+ DMemoryNew = (uint8_t *)ps_malloc (E_INK_WIDTH * E_INK_HEIGHT / 8 );
829+ _partial = (uint8_t *)ps_malloc (E_INK_WIDTH * E_INK_HEIGHT / 8 );
830+ _pBuffer = (uint8_t *)ps_malloc (E_INK_WIDTH * E_INK_HEIGHT / 4 );
831+ DMemory4Bit = (uint8_t *)ps_malloc (E_INK_WIDTH * E_INK_HEIGHT / 2 );
832+ GLUT = (uint32_t *)malloc (256 * 9 * sizeof (uint32_t ));
833+ GLUT2 = (uint32_t *)malloc (256 * 9 * sizeof (uint32_t ));
834+ if (DMemoryNew == NULL || _partial == NULL || _pBuffer == NULL || DMemory4Bit == NULL || GLUT == NULL ||
835+ GLUT2 == NULL )
836+ {
837+ return 0 ;
838+ }
839+ // Set all the framebuffers to White at start
840+ memset (DMemoryNew, 0 , E_INK_WIDTH * E_INK_HEIGHT / 8 );
841+ memset (_partial, 0 , E_INK_WIDTH * E_INK_HEIGHT / 8 );
842+ memset (_pBuffer, 0 , E_INK_WIDTH * E_INK_HEIGHT / 4 );
843+ memset (DMemory4Bit, 255 , E_INK_WIDTH * E_INK_HEIGHT / 2 );
844+
845+ }
846+
784847/* *
785848 * @brief sdCardInit initializes sd card trough SPI
786849 *
0 commit comments