Come from standard seeed epaper, but adding SPI signal in construtor
Fork of seeedstudio-epaper by
EPD.cpp@2:c5bb7d34974d, 2015-11-13 (annotated)
- Committer:
- thierryc49
- Date:
- Fri Nov 13 20:46:53 2015 +0000
- Revision:
- 2:c5bb7d34974d
- Parent:
- 1:2f62e2b80305
lib from seedstudio-epaper, Add SPI in parameter's constructor
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sigveseb | 1:2f62e2b80305 | 1 | // TODO: update copyright notice |
sigveseb | 1:2f62e2b80305 | 2 | |
sigveseb | 0:6ac5ba1343bf | 3 | // Copyright 2013 Pervasive Displays, Inc. |
sigveseb | 0:6ac5ba1343bf | 4 | // |
sigveseb | 0:6ac5ba1343bf | 5 | // Licensed under the Apache License, Version 2.0 (the "License"); |
sigveseb | 0:6ac5ba1343bf | 6 | // you may not use this file except in compliance with the License. |
sigveseb | 0:6ac5ba1343bf | 7 | // You may obtain a copy of the License at: |
sigveseb | 0:6ac5ba1343bf | 8 | // |
sigveseb | 0:6ac5ba1343bf | 9 | // http://www.apache.org/licenses/LICENSE-2.0 |
sigveseb | 0:6ac5ba1343bf | 10 | // |
sigveseb | 0:6ac5ba1343bf | 11 | // Unless required by applicable law or agreed to in writing, |
sigveseb | 0:6ac5ba1343bf | 12 | // software distributed under the License is distributed on an |
sigveseb | 0:6ac5ba1343bf | 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
sigveseb | 0:6ac5ba1343bf | 14 | // express or implied. See the License for the specific language |
sigveseb | 0:6ac5ba1343bf | 15 | // governing permissions and limitations under the License. |
sigveseb | 0:6ac5ba1343bf | 16 | |
sigveseb | 0:6ac5ba1343bf | 17 | |
sigveseb | 0:6ac5ba1343bf | 18 | #include <limits.h> |
sigveseb | 0:6ac5ba1343bf | 19 | #include <SPI.h> |
sigveseb | 0:6ac5ba1343bf | 20 | |
sigveseb | 0:6ac5ba1343bf | 21 | #include "EPD.h" |
sigveseb | 0:6ac5ba1343bf | 22 | #include <mbed.h> |
sigveseb | 0:6ac5ba1343bf | 23 | |
sigveseb | 0:6ac5ba1343bf | 24 | // inline arrays |
sigveseb | 0:6ac5ba1343bf | 25 | #define ARRAY(type, ...) ((type[]){__VA_ARGS__}) |
sigveseb | 0:6ac5ba1343bf | 26 | #define CU8(...) (ARRAY(const uint8_t, __VA_ARGS__)) |
sigveseb | 0:6ac5ba1343bf | 27 | |
sigveseb | 0:6ac5ba1343bf | 28 | Timer timer; |
sigveseb | 0:6ac5ba1343bf | 29 | |
thierryc49 | 2:c5bb7d34974d | 30 | //thierry |
thierryc49 | 2:c5bb7d34974d | 31 | //--origine SPI spi(p20, p22, p25); |
thierryc49 | 2:c5bb7d34974d | 32 | //SPI spi(P0_25,P0_28,P0_29); |
sigveseb | 0:6ac5ba1343bf | 33 | |
sigveseb | 0:6ac5ba1343bf | 34 | |
thierryc49 | 2:c5bb7d34974d | 35 | |
thierryc49 | 2:c5bb7d34974d | 36 | EPD_Class::EPD_Class(PinName Pin_EPD_CS, PinName Pin_PANEL_ON, PinName Pin_BORDER, PinName Pin_DISCHARGE, PinName Pin_PWM, PinName Pin_RESET, PinName Pin_BUSY,PinName Pin_MOSI,PinName Pin_MISO,PinName Pin_CLK) : |
sigveseb | 0:6ac5ba1343bf | 37 | EPD_Pin_EPD_CS(Pin_EPD_CS), |
sigveseb | 0:6ac5ba1343bf | 38 | EPD_Pin_PANEL_ON(Pin_PANEL_ON), |
sigveseb | 0:6ac5ba1343bf | 39 | EPD_Pin_BORDER(Pin_BORDER), |
sigveseb | 0:6ac5ba1343bf | 40 | EPD_Pin_DISCHARGE(Pin_DISCHARGE), |
sigveseb | 0:6ac5ba1343bf | 41 | EPD_Pin_PWM(Pin_PWM), |
sigveseb | 0:6ac5ba1343bf | 42 | EPD_Pin_RESET(Pin_RESET), |
thierryc49 | 2:c5bb7d34974d | 43 | EPD_Pin_BUSY(Pin_BUSY), |
thierryc49 | 2:c5bb7d34974d | 44 | spi (Pin_MOSI,Pin_MISO,Pin_CLK) |
thierryc49 | 2:c5bb7d34974d | 45 | { |
thierryc49 | 2:c5bb7d34974d | 46 | |
sigveseb | 0:6ac5ba1343bf | 47 | } |
sigveseb | 0:6ac5ba1343bf | 48 | |
sigveseb | 0:6ac5ba1343bf | 49 | void EPD_Class::begin(EPD_size sz) |
sigveseb | 0:6ac5ba1343bf | 50 | { |
sigveseb | 0:6ac5ba1343bf | 51 | this->size = sz; |
sigveseb | 0:6ac5ba1343bf | 52 | this->stage_time = 480; // milliseconds |
sigveseb | 0:6ac5ba1343bf | 53 | this->lines_per_display = 96; |
sigveseb | 0:6ac5ba1343bf | 54 | this->dots_per_line = 128; |
sigveseb | 0:6ac5ba1343bf | 55 | this->bytes_per_line = 128 / 8; |
sigveseb | 0:6ac5ba1343bf | 56 | this->bytes_per_scan = 96 / 4; |
sigveseb | 0:6ac5ba1343bf | 57 | this->filler = false; |
sigveseb | 0:6ac5ba1343bf | 58 | timer.start(); |
sigveseb | 0:6ac5ba1343bf | 59 | this->EPD_Pin_PWM.period(1.0/300000.0); |
sigveseb | 0:6ac5ba1343bf | 60 | |
sigveseb | 0:6ac5ba1343bf | 61 | |
sigveseb | 0:6ac5ba1343bf | 62 | // display size dependant items |
sigveseb | 0:6ac5ba1343bf | 63 | { |
sigveseb | 0:6ac5ba1343bf | 64 | static uint8_t cs[] = {0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00}; |
sigveseb | 0:6ac5ba1343bf | 65 | static uint8_t gs[] = {0x72, 0x03}; |
sigveseb | 0:6ac5ba1343bf | 66 | this->channel_select = cs; |
sigveseb | 0:6ac5ba1343bf | 67 | this->channel_select_length = sizeof(cs); |
sigveseb | 0:6ac5ba1343bf | 68 | this->gate_source = gs; |
sigveseb | 0:6ac5ba1343bf | 69 | this->gate_source_length = sizeof(gs); |
sigveseb | 0:6ac5ba1343bf | 70 | } |
sigveseb | 0:6ac5ba1343bf | 71 | |
sigveseb | 0:6ac5ba1343bf | 72 | // set up size structure |
sigveseb | 0:6ac5ba1343bf | 73 | switch (size) { |
sigveseb | 0:6ac5ba1343bf | 74 | default: |
sigveseb | 0:6ac5ba1343bf | 75 | case EPD_1_44: // default so no change |
sigveseb | 0:6ac5ba1343bf | 76 | break; |
sigveseb | 0:6ac5ba1343bf | 77 | |
sigveseb | 0:6ac5ba1343bf | 78 | case EPD_2_0: { |
sigveseb | 0:6ac5ba1343bf | 79 | this->lines_per_display = 96; |
sigveseb | 0:6ac5ba1343bf | 80 | this->dots_per_line = 200; |
sigveseb | 0:6ac5ba1343bf | 81 | this->bytes_per_line = 200 / 8; |
sigveseb | 0:6ac5ba1343bf | 82 | this->bytes_per_scan = 96 / 4; |
sigveseb | 0:6ac5ba1343bf | 83 | this->filler = true; |
sigveseb | 0:6ac5ba1343bf | 84 | static uint8_t cs[] = {0x72, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00}; |
sigveseb | 0:6ac5ba1343bf | 85 | static uint8_t gs[] = {0x72, 0x03}; |
sigveseb | 0:6ac5ba1343bf | 86 | this->channel_select = cs; |
sigveseb | 0:6ac5ba1343bf | 87 | this->channel_select_length = sizeof(cs); |
sigveseb | 0:6ac5ba1343bf | 88 | this->gate_source = gs; |
sigveseb | 0:6ac5ba1343bf | 89 | this->gate_source_length = sizeof(gs); |
sigveseb | 0:6ac5ba1343bf | 90 | break; |
sigveseb | 0:6ac5ba1343bf | 91 | } |
sigveseb | 0:6ac5ba1343bf | 92 | |
sigveseb | 0:6ac5ba1343bf | 93 | case EPD_2_7: { |
sigveseb | 0:6ac5ba1343bf | 94 | this->stage_time = 630; // milliseconds |
sigveseb | 0:6ac5ba1343bf | 95 | this->lines_per_display = 176; |
sigveseb | 0:6ac5ba1343bf | 96 | this->dots_per_line = 264; |
sigveseb | 0:6ac5ba1343bf | 97 | this->bytes_per_line = 264 / 8; |
sigveseb | 0:6ac5ba1343bf | 98 | this->bytes_per_scan = 176 / 4; |
sigveseb | 0:6ac5ba1343bf | 99 | this->filler = true; |
sigveseb | 0:6ac5ba1343bf | 100 | static uint8_t cs[] = {0x72, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x00}; |
sigveseb | 0:6ac5ba1343bf | 101 | static uint8_t gs[] = {0x72, 0x00}; |
sigveseb | 0:6ac5ba1343bf | 102 | this->channel_select = cs; |
sigveseb | 0:6ac5ba1343bf | 103 | this->channel_select_length = sizeof(cs); |
sigveseb | 0:6ac5ba1343bf | 104 | this->gate_source = gs; |
sigveseb | 0:6ac5ba1343bf | 105 | this->gate_source_length = sizeof(gs); |
sigveseb | 0:6ac5ba1343bf | 106 | break; |
sigveseb | 0:6ac5ba1343bf | 107 | } |
sigveseb | 0:6ac5ba1343bf | 108 | } |
sigveseb | 0:6ac5ba1343bf | 109 | |
sigveseb | 0:6ac5ba1343bf | 110 | this->factored_stage_time = this->stage_time; |
sigveseb | 0:6ac5ba1343bf | 111 | } |
sigveseb | 0:6ac5ba1343bf | 112 | |
sigveseb | 0:6ac5ba1343bf | 113 | |
sigveseb | 0:6ac5ba1343bf | 114 | void EPD_Class::start() { |
sigveseb | 0:6ac5ba1343bf | 115 | |
sigveseb | 0:6ac5ba1343bf | 116 | this->EPD_Pin_PWM = 0.5; |
sigveseb | 0:6ac5ba1343bf | 117 | this->EPD_Pin_RESET = 0; |
sigveseb | 0:6ac5ba1343bf | 118 | this->EPD_Pin_PANEL_ON = 0; |
sigveseb | 0:6ac5ba1343bf | 119 | this->EPD_Pin_DISCHARGE = 0; |
sigveseb | 0:6ac5ba1343bf | 120 | this->EPD_Pin_BORDER = 0; |
sigveseb | 0:6ac5ba1343bf | 121 | this->EPD_Pin_EPD_CS = 0; |
sigveseb | 0:6ac5ba1343bf | 122 | |
sigveseb | 0:6ac5ba1343bf | 123 | |
sigveseb | 0:6ac5ba1343bf | 124 | spi.format(8,0); |
sigveseb | 0:6ac5ba1343bf | 125 | spi.frequency(10000000); |
sigveseb | 0:6ac5ba1343bf | 126 | SPI_on(); |
sigveseb | 0:6ac5ba1343bf | 127 | |
sigveseb | 0:6ac5ba1343bf | 128 | wait_ms(5); |
sigveseb | 0:6ac5ba1343bf | 129 | this->EPD_Pin_PANEL_ON = 1; |
sigveseb | 0:6ac5ba1343bf | 130 | wait_ms(10); |
sigveseb | 0:6ac5ba1343bf | 131 | |
sigveseb | 0:6ac5ba1343bf | 132 | this->EPD_Pin_RESET = 1; |
sigveseb | 0:6ac5ba1343bf | 133 | this->EPD_Pin_BORDER = 1; |
sigveseb | 0:6ac5ba1343bf | 134 | this->EPD_Pin_EPD_CS = 1; |
sigveseb | 0:6ac5ba1343bf | 135 | wait_ms(5); |
sigveseb | 0:6ac5ba1343bf | 136 | |
sigveseb | 0:6ac5ba1343bf | 137 | this->EPD_Pin_RESET = 0; |
sigveseb | 0:6ac5ba1343bf | 138 | wait_ms(5); |
sigveseb | 0:6ac5ba1343bf | 139 | |
sigveseb | 0:6ac5ba1343bf | 140 | this->EPD_Pin_RESET = 1; |
sigveseb | 0:6ac5ba1343bf | 141 | wait_ms(5); |
sigveseb | 0:6ac5ba1343bf | 142 | |
sigveseb | 0:6ac5ba1343bf | 143 | // wait for COG to become ready |
sigveseb | 0:6ac5ba1343bf | 144 | while (this->EPD_Pin_BUSY) { |
sigveseb | 0:6ac5ba1343bf | 145 | } |
sigveseb | 0:6ac5ba1343bf | 146 | |
sigveseb | 0:6ac5ba1343bf | 147 | // channel select |
sigveseb | 0:6ac5ba1343bf | 148 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 149 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x01), 2); |
sigveseb | 0:6ac5ba1343bf | 150 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 151 | SPI_send(this->EPD_Pin_EPD_CS, this->channel_select, this->channel_select_length); |
sigveseb | 0:6ac5ba1343bf | 152 | |
sigveseb | 0:6ac5ba1343bf | 153 | // DC/DC frequency |
sigveseb | 0:6ac5ba1343bf | 154 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 155 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x06), 2); |
sigveseb | 0:6ac5ba1343bf | 156 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 157 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0xff), 2); |
sigveseb | 0:6ac5ba1343bf | 158 | |
sigveseb | 0:6ac5ba1343bf | 159 | // high power mode osc |
sigveseb | 0:6ac5ba1343bf | 160 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 161 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x07), 2); |
sigveseb | 0:6ac5ba1343bf | 162 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 163 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x9d), 2); |
sigveseb | 0:6ac5ba1343bf | 164 | |
sigveseb | 0:6ac5ba1343bf | 165 | |
sigveseb | 0:6ac5ba1343bf | 166 | // disable ADC |
sigveseb | 0:6ac5ba1343bf | 167 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 168 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x08), 2); |
sigveseb | 0:6ac5ba1343bf | 169 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 170 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x00), 2); |
sigveseb | 0:6ac5ba1343bf | 171 | |
sigveseb | 0:6ac5ba1343bf | 172 | // Vcom level |
sigveseb | 0:6ac5ba1343bf | 173 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 174 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x09), 2); |
sigveseb | 0:6ac5ba1343bf | 175 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 176 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0xd0, 0x00), 3); |
sigveseb | 0:6ac5ba1343bf | 177 | |
sigveseb | 0:6ac5ba1343bf | 178 | // gate and source voltage levels |
sigveseb | 0:6ac5ba1343bf | 179 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 180 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x04), 2); |
sigveseb | 0:6ac5ba1343bf | 181 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 182 | SPI_send(this->EPD_Pin_EPD_CS, this->gate_source, this->gate_source_length); |
sigveseb | 0:6ac5ba1343bf | 183 | |
sigveseb | 0:6ac5ba1343bf | 184 | |
sigveseb | 0:6ac5ba1343bf | 185 | this->EPD_Pin_PWM = 0.5; |
sigveseb | 0:6ac5ba1343bf | 186 | wait_ms(5); // pwm toggle >= 5ms |
sigveseb | 0:6ac5ba1343bf | 187 | |
sigveseb | 0:6ac5ba1343bf | 188 | // driver latch on |
sigveseb | 0:6ac5ba1343bf | 189 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 190 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x03), 2); |
sigveseb | 0:6ac5ba1343bf | 191 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 192 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x01), 2); |
sigveseb | 0:6ac5ba1343bf | 193 | |
sigveseb | 0:6ac5ba1343bf | 194 | // driver latch off |
sigveseb | 0:6ac5ba1343bf | 195 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 196 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x03), 2); |
sigveseb | 0:6ac5ba1343bf | 197 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 198 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x00), 2); |
sigveseb | 0:6ac5ba1343bf | 199 | |
sigveseb | 0:6ac5ba1343bf | 200 | wait_ms(5); |
sigveseb | 0:6ac5ba1343bf | 201 | |
sigveseb | 0:6ac5ba1343bf | 202 | // charge pump positive voltage on |
sigveseb | 0:6ac5ba1343bf | 203 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 204 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x05), 2); |
sigveseb | 0:6ac5ba1343bf | 205 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 206 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x01), 2); |
sigveseb | 0:6ac5ba1343bf | 207 | |
sigveseb | 0:6ac5ba1343bf | 208 | // final delay before PWM off |
sigveseb | 0:6ac5ba1343bf | 209 | wait_ms(30); |
sigveseb | 0:6ac5ba1343bf | 210 | this->EPD_Pin_PWM = 0; |
sigveseb | 0:6ac5ba1343bf | 211 | |
sigveseb | 0:6ac5ba1343bf | 212 | // charge pump negative voltage on |
sigveseb | 0:6ac5ba1343bf | 213 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 214 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x05), 2); |
sigveseb | 0:6ac5ba1343bf | 215 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 216 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x03), 2); |
sigveseb | 0:6ac5ba1343bf | 217 | |
sigveseb | 0:6ac5ba1343bf | 218 | wait_ms(30); |
sigveseb | 0:6ac5ba1343bf | 219 | |
sigveseb | 0:6ac5ba1343bf | 220 | // Vcom driver on |
sigveseb | 0:6ac5ba1343bf | 221 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 222 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x05), 2); |
sigveseb | 0:6ac5ba1343bf | 223 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 224 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x0f), 2); |
sigveseb | 0:6ac5ba1343bf | 225 | |
sigveseb | 0:6ac5ba1343bf | 226 | wait_ms(30); |
sigveseb | 0:6ac5ba1343bf | 227 | |
sigveseb | 0:6ac5ba1343bf | 228 | // output enable to disable |
sigveseb | 0:6ac5ba1343bf | 229 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 230 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x02), 2); |
sigveseb | 0:6ac5ba1343bf | 231 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 232 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x24), 2); |
sigveseb | 0:6ac5ba1343bf | 233 | } |
sigveseb | 0:6ac5ba1343bf | 234 | |
sigveseb | 0:6ac5ba1343bf | 235 | |
sigveseb | 0:6ac5ba1343bf | 236 | void EPD_Class::end() |
sigveseb | 0:6ac5ba1343bf | 237 | { |
sigveseb | 0:6ac5ba1343bf | 238 | // dummy frame |
sigveseb | 0:6ac5ba1343bf | 239 | //this->frame_fixed(0x55, EPD_normal); |
sigveseb | 0:6ac5ba1343bf | 240 | // dummy line and border |
sigveseb | 0:6ac5ba1343bf | 241 | if (EPD_1_44 == this->size) { |
sigveseb | 0:6ac5ba1343bf | 242 | // only for 1.44" EPD |
sigveseb | 0:6ac5ba1343bf | 243 | this->line(0x7fffu, 0, 0xaa, false, EPD_normal); |
sigveseb | 0:6ac5ba1343bf | 244 | |
sigveseb | 0:6ac5ba1343bf | 245 | wait_ms(250); |
sigveseb | 0:6ac5ba1343bf | 246 | |
sigveseb | 0:6ac5ba1343bf | 247 | } |
sigveseb | 0:6ac5ba1343bf | 248 | else { |
sigveseb | 0:6ac5ba1343bf | 249 | // all other display sizes |
sigveseb | 0:6ac5ba1343bf | 250 | this->line(0x7fffu, 0, 0x55, false, EPD_normal); |
sigveseb | 0:6ac5ba1343bf | 251 | |
sigveseb | 0:6ac5ba1343bf | 252 | wait_ms(25); |
sigveseb | 0:6ac5ba1343bf | 253 | |
sigveseb | 0:6ac5ba1343bf | 254 | this->EPD_Pin_BORDER = 0; |
sigveseb | 0:6ac5ba1343bf | 255 | wait_ms(250); |
sigveseb | 0:6ac5ba1343bf | 256 | this->EPD_Pin_BORDER = 1; |
sigveseb | 0:6ac5ba1343bf | 257 | } |
sigveseb | 0:6ac5ba1343bf | 258 | SPI_on(); |
sigveseb | 0:6ac5ba1343bf | 259 | // latch reset turn on |
sigveseb | 0:6ac5ba1343bf | 260 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 261 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x03), 2); |
sigveseb | 0:6ac5ba1343bf | 262 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 263 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x01), 2); |
sigveseb | 0:6ac5ba1343bf | 264 | |
sigveseb | 0:6ac5ba1343bf | 265 | // output enable off |
sigveseb | 0:6ac5ba1343bf | 266 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 267 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x02), 2); |
sigveseb | 0:6ac5ba1343bf | 268 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 269 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x05), 2); |
sigveseb | 0:6ac5ba1343bf | 270 | |
sigveseb | 0:6ac5ba1343bf | 271 | // Vcom power off |
sigveseb | 0:6ac5ba1343bf | 272 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 273 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x05), 2); |
sigveseb | 0:6ac5ba1343bf | 274 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 275 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x0e), 2); |
sigveseb | 0:6ac5ba1343bf | 276 | |
sigveseb | 0:6ac5ba1343bf | 277 | // power off negative charge pump |
sigveseb | 0:6ac5ba1343bf | 278 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 279 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x05), 2); |
sigveseb | 0:6ac5ba1343bf | 280 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 281 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x02), 2); |
sigveseb | 0:6ac5ba1343bf | 282 | |
sigveseb | 0:6ac5ba1343bf | 283 | // discharge |
sigveseb | 0:6ac5ba1343bf | 284 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 285 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x04), 2); |
sigveseb | 0:6ac5ba1343bf | 286 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 287 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x0c), 2); |
sigveseb | 0:6ac5ba1343bf | 288 | |
sigveseb | 0:6ac5ba1343bf | 289 | wait_ms(120); |
sigveseb | 0:6ac5ba1343bf | 290 | |
sigveseb | 0:6ac5ba1343bf | 291 | // all charge pumps off |
sigveseb | 0:6ac5ba1343bf | 292 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 293 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x05), 2); |
sigveseb | 0:6ac5ba1343bf | 294 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 295 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x00), 2); |
sigveseb | 0:6ac5ba1343bf | 296 | |
sigveseb | 0:6ac5ba1343bf | 297 | // turn of osc |
sigveseb | 0:6ac5ba1343bf | 298 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 299 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x07), 2); |
sigveseb | 0:6ac5ba1343bf | 300 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 301 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x0d), 2); |
sigveseb | 0:6ac5ba1343bf | 302 | |
sigveseb | 0:6ac5ba1343bf | 303 | // discharge internal - 1 |
sigveseb | 0:6ac5ba1343bf | 304 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 305 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x04), 2); |
sigveseb | 0:6ac5ba1343bf | 306 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 307 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x50), 2); |
sigveseb | 0:6ac5ba1343bf | 308 | |
sigveseb | 0:6ac5ba1343bf | 309 | wait_ms(40); |
sigveseb | 0:6ac5ba1343bf | 310 | |
sigveseb | 0:6ac5ba1343bf | 311 | // discharge internal - 2 |
sigveseb | 0:6ac5ba1343bf | 312 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 313 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x04), 2); |
sigveseb | 0:6ac5ba1343bf | 314 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 315 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0xA0), 2); |
sigveseb | 0:6ac5ba1343bf | 316 | |
sigveseb | 0:6ac5ba1343bf | 317 | wait_ms(40); |
sigveseb | 0:6ac5ba1343bf | 318 | |
sigveseb | 0:6ac5ba1343bf | 319 | // discharge internal - 3 |
sigveseb | 0:6ac5ba1343bf | 320 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 321 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x04), 2); |
sigveseb | 0:6ac5ba1343bf | 322 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 323 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x00), 2); |
sigveseb | 0:6ac5ba1343bf | 324 | // turn of power and all signals |
sigveseb | 0:6ac5ba1343bf | 325 | // |
sigveseb | 0:6ac5ba1343bf | 326 | |
sigveseb | 0:6ac5ba1343bf | 327 | wait_ms(10); |
sigveseb | 0:6ac5ba1343bf | 328 | this->EPD_Pin_RESET = 0; |
sigveseb | 0:6ac5ba1343bf | 329 | this->EPD_Pin_PANEL_ON = 0; |
sigveseb | 0:6ac5ba1343bf | 330 | this->EPD_Pin_BORDER = 0; |
sigveseb | 0:6ac5ba1343bf | 331 | |
sigveseb | 0:6ac5ba1343bf | 332 | // discharge pulse |
sigveseb | 0:6ac5ba1343bf | 333 | this->EPD_Pin_DISCHARGE = 1; |
sigveseb | 0:6ac5ba1343bf | 334 | wait_ms(250); |
sigveseb | 0:6ac5ba1343bf | 335 | this->EPD_Pin_DISCHARGE = 0; |
sigveseb | 0:6ac5ba1343bf | 336 | |
sigveseb | 0:6ac5ba1343bf | 337 | EPD_Pin_EPD_CS = 1; |
sigveseb | 0:6ac5ba1343bf | 338 | } |
sigveseb | 0:6ac5ba1343bf | 339 | |
sigveseb | 0:6ac5ba1343bf | 340 | |
sigveseb | 0:6ac5ba1343bf | 341 | // convert a temperature in Celcius to |
sigveseb | 0:6ac5ba1343bf | 342 | // the scale factor for frame_*_repeat methods |
sigveseb | 0:6ac5ba1343bf | 343 | int EPD_Class::temperature_to_factor_10x(int temperature) |
sigveseb | 0:6ac5ba1343bf | 344 | { |
sigveseb | 0:6ac5ba1343bf | 345 | if (temperature <= -10) { |
sigveseb | 0:6ac5ba1343bf | 346 | return 170; |
sigveseb | 0:6ac5ba1343bf | 347 | } else if (temperature <= -5) { |
sigveseb | 0:6ac5ba1343bf | 348 | return 120; |
sigveseb | 0:6ac5ba1343bf | 349 | } else if (temperature <= 5) { |
sigveseb | 0:6ac5ba1343bf | 350 | return 80; |
sigveseb | 0:6ac5ba1343bf | 351 | } else if (temperature <= 10) { |
sigveseb | 0:6ac5ba1343bf | 352 | return 40; |
sigveseb | 0:6ac5ba1343bf | 353 | } else if (temperature <= 15) { |
sigveseb | 0:6ac5ba1343bf | 354 | return 30; |
sigveseb | 0:6ac5ba1343bf | 355 | } else if (temperature <= 20) { |
sigveseb | 0:6ac5ba1343bf | 356 | return 20; |
sigveseb | 0:6ac5ba1343bf | 357 | } else if (temperature <= 40) { |
sigveseb | 0:6ac5ba1343bf | 358 | return 10; |
sigveseb | 0:6ac5ba1343bf | 359 | } |
sigveseb | 0:6ac5ba1343bf | 360 | return 7; |
sigveseb | 0:6ac5ba1343bf | 361 | } |
sigveseb | 0:6ac5ba1343bf | 362 | |
sigveseb | 0:6ac5ba1343bf | 363 | |
sigveseb | 0:6ac5ba1343bf | 364 | // One frame of data is the number of lines * rows. For example: |
sigveseb | 0:6ac5ba1343bf | 365 | // The 1.44” frame of data is 96 lines * 128 dots. |
sigveseb | 0:6ac5ba1343bf | 366 | // The 2” frame of data is 96 lines * 200 dots. |
sigveseb | 0:6ac5ba1343bf | 367 | // The 2.7” frame of data is 176 lines * 264 dots. |
sigveseb | 0:6ac5ba1343bf | 368 | |
sigveseb | 0:6ac5ba1343bf | 369 | // the image is arranged by line which matches the display size |
sigveseb | 0:6ac5ba1343bf | 370 | // so smallest would have 96 * 32 bytes |
sigveseb | 0:6ac5ba1343bf | 371 | |
sigveseb | 0:6ac5ba1343bf | 372 | void EPD_Class::frame_fixed(uint8_t fixed_value, EPD_stage stage, int from_line, int to_line) |
sigveseb | 0:6ac5ba1343bf | 373 | { |
sigveseb | 0:6ac5ba1343bf | 374 | for (uint8_t line = from_line; line < to_line; line++) |
sigveseb | 0:6ac5ba1343bf | 375 | { |
sigveseb | 0:6ac5ba1343bf | 376 | this->line(line, 0, fixed_value, false, stage); |
sigveseb | 0:6ac5ba1343bf | 377 | } |
sigveseb | 0:6ac5ba1343bf | 378 | } |
sigveseb | 0:6ac5ba1343bf | 379 | |
sigveseb | 0:6ac5ba1343bf | 380 | void EPD_Class::frame_data(const uint8_t *image, EPD_stage stage, int from_line, int to_line) |
sigveseb | 0:6ac5ba1343bf | 381 | { |
sigveseb | 0:6ac5ba1343bf | 382 | for (uint8_t line = from_line; line < to_line; line++) |
sigveseb | 0:6ac5ba1343bf | 383 | { |
sigveseb | 1:2f62e2b80305 | 384 | this->line(line, &image[(line - from_line) * this->bytes_per_line], 0, true, stage); |
sigveseb | 0:6ac5ba1343bf | 385 | } |
sigveseb | 0:6ac5ba1343bf | 386 | } |
sigveseb | 0:6ac5ba1343bf | 387 | |
sigveseb | 0:6ac5ba1343bf | 388 | |
sigveseb | 0:6ac5ba1343bf | 389 | void EPD_Class::frame_fixed_repeat(uint8_t fixed_value, EPD_stage stage, int from_line, int to_line) |
sigveseb | 0:6ac5ba1343bf | 390 | { |
sigveseb | 0:6ac5ba1343bf | 391 | long stage_time = this->factored_stage_time; |
sigveseb | 0:6ac5ba1343bf | 392 | do { |
sigveseb | 0:6ac5ba1343bf | 393 | unsigned long t_start = timer.read_ms(); |
sigveseb | 0:6ac5ba1343bf | 394 | this->frame_fixed(fixed_value, stage, from_line, to_line); |
sigveseb | 0:6ac5ba1343bf | 395 | unsigned long t_end = timer.read_ms(); |
sigveseb | 0:6ac5ba1343bf | 396 | if (t_end > t_start) { |
sigveseb | 0:6ac5ba1343bf | 397 | stage_time -= t_end - t_start; |
sigveseb | 0:6ac5ba1343bf | 398 | } else { |
sigveseb | 0:6ac5ba1343bf | 399 | stage_time -= t_start - t_end + 1 + ULONG_MAX; |
sigveseb | 0:6ac5ba1343bf | 400 | } |
sigveseb | 0:6ac5ba1343bf | 401 | } while (stage_time > 0); |
sigveseb | 0:6ac5ba1343bf | 402 | } |
sigveseb | 0:6ac5ba1343bf | 403 | |
sigveseb | 0:6ac5ba1343bf | 404 | |
sigveseb | 0:6ac5ba1343bf | 405 | void EPD_Class::frame_data_repeat(const uint8_t *image, EPD_stage stage, int from_line, int to_line) |
sigveseb | 0:6ac5ba1343bf | 406 | { |
sigveseb | 0:6ac5ba1343bf | 407 | |
sigveseb | 0:6ac5ba1343bf | 408 | long stage_time = this->factored_stage_time; |
sigveseb | 0:6ac5ba1343bf | 409 | |
sigveseb | 0:6ac5ba1343bf | 410 | do { |
sigveseb | 0:6ac5ba1343bf | 411 | unsigned long t_start = timer.read_ms(); |
sigveseb | 0:6ac5ba1343bf | 412 | this->frame_data(image, stage, from_line, to_line); |
sigveseb | 0:6ac5ba1343bf | 413 | unsigned long t_end = timer.read_ms(); |
sigveseb | 0:6ac5ba1343bf | 414 | if (t_end > t_start) { |
sigveseb | 0:6ac5ba1343bf | 415 | stage_time -= t_end - t_start; |
sigveseb | 0:6ac5ba1343bf | 416 | } else { |
sigveseb | 0:6ac5ba1343bf | 417 | stage_time -= t_start - t_end + 1 + ULONG_MAX; |
sigveseb | 0:6ac5ba1343bf | 418 | } |
sigveseb | 0:6ac5ba1343bf | 419 | } while (stage_time > 0); |
sigveseb | 0:6ac5ba1343bf | 420 | |
sigveseb | 0:6ac5ba1343bf | 421 | } |
sigveseb | 0:6ac5ba1343bf | 422 | |
sigveseb | 0:6ac5ba1343bf | 423 | void EPD_Class::line(uint16_t line, const uint8_t *data, uint8_t fixed_value, bool read_progmem, EPD_stage stage) |
sigveseb | 0:6ac5ba1343bf | 424 | { |
sigveseb | 0:6ac5ba1343bf | 425 | // charge pump voltage levels |
sigveseb | 0:6ac5ba1343bf | 426 | SPI_on(); |
sigveseb | 0:6ac5ba1343bf | 427 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 428 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x04), 2); |
sigveseb | 0:6ac5ba1343bf | 429 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 430 | SPI_send(this->EPD_Pin_EPD_CS, this->gate_source, this->gate_source_length); |
sigveseb | 0:6ac5ba1343bf | 431 | |
sigveseb | 0:6ac5ba1343bf | 432 | // send data |
sigveseb | 0:6ac5ba1343bf | 433 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 434 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x0a), 2); |
sigveseb | 0:6ac5ba1343bf | 435 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 436 | |
sigveseb | 0:6ac5ba1343bf | 437 | // CS low |
sigveseb | 0:6ac5ba1343bf | 438 | this->EPD_Pin_EPD_CS = 0; |
sigveseb | 0:6ac5ba1343bf | 439 | SPI_put_wait(0x72, this->EPD_Pin_BUSY); |
sigveseb | 0:6ac5ba1343bf | 440 | |
sigveseb | 0:6ac5ba1343bf | 441 | // even pixels |
sigveseb | 0:6ac5ba1343bf | 442 | for (uint16_t b = this->bytes_per_line; b > 0; --b) |
sigveseb | 0:6ac5ba1343bf | 443 | { |
sigveseb | 0:6ac5ba1343bf | 444 | if (0 != data) |
sigveseb | 0:6ac5ba1343bf | 445 | { |
sigveseb | 0:6ac5ba1343bf | 446 | |
sigveseb | 0:6ac5ba1343bf | 447 | uint8_t pixels = data[b - 1] & 0xaa; |
sigveseb | 0:6ac5ba1343bf | 448 | |
sigveseb | 0:6ac5ba1343bf | 449 | |
sigveseb | 0:6ac5ba1343bf | 450 | switch(stage) |
sigveseb | 0:6ac5ba1343bf | 451 | { |
sigveseb | 0:6ac5ba1343bf | 452 | case EPD_compensate: // B -> W, W -> B (Current Image) |
sigveseb | 0:6ac5ba1343bf | 453 | pixels = 0xaa | ((pixels ^ 0xaa) >> 1); |
sigveseb | 0:6ac5ba1343bf | 454 | break; |
sigveseb | 0:6ac5ba1343bf | 455 | |
sigveseb | 0:6ac5ba1343bf | 456 | case EPD_white: // B -> N, W -> W (Current Image) |
sigveseb | 0:6ac5ba1343bf | 457 | pixels = 0x55 + ((pixels ^ 0xaa) >> 1); |
sigveseb | 0:6ac5ba1343bf | 458 | break; |
sigveseb | 0:6ac5ba1343bf | 459 | |
sigveseb | 0:6ac5ba1343bf | 460 | case EPD_inverse: // B -> N, W -> B (New Image) |
sigveseb | 0:6ac5ba1343bf | 461 | pixels = 0x55 | (pixels ^ 0xaa); |
sigveseb | 0:6ac5ba1343bf | 462 | break; |
sigveseb | 0:6ac5ba1343bf | 463 | |
sigveseb | 0:6ac5ba1343bf | 464 | case EPD_normal: // B -> B, W -> W (New Image) |
sigveseb | 0:6ac5ba1343bf | 465 | pixels = 0xaa | (pixels >> 1); |
sigveseb | 0:6ac5ba1343bf | 466 | break; |
sigveseb | 0:6ac5ba1343bf | 467 | } |
sigveseb | 0:6ac5ba1343bf | 468 | |
sigveseb | 0:6ac5ba1343bf | 469 | SPI_put_wait(pixels, this->EPD_Pin_BUSY); |
sigveseb | 0:6ac5ba1343bf | 470 | } |
sigveseb | 0:6ac5ba1343bf | 471 | else |
sigveseb | 0:6ac5ba1343bf | 472 | { |
sigveseb | 0:6ac5ba1343bf | 473 | SPI_put_wait(fixed_value, this->EPD_Pin_BUSY); |
sigveseb | 0:6ac5ba1343bf | 474 | } |
sigveseb | 0:6ac5ba1343bf | 475 | } |
sigveseb | 0:6ac5ba1343bf | 476 | |
sigveseb | 0:6ac5ba1343bf | 477 | // scan line |
sigveseb | 0:6ac5ba1343bf | 478 | for (uint16_t b = 0; b < this->bytes_per_scan; ++b) |
sigveseb | 0:6ac5ba1343bf | 479 | { |
sigveseb | 0:6ac5ba1343bf | 480 | if (line / 4 == b) |
sigveseb | 0:6ac5ba1343bf | 481 | { |
sigveseb | 0:6ac5ba1343bf | 482 | SPI_put_wait(0xc0 >> (2 * (line & 0x03)), this->EPD_Pin_BUSY); |
sigveseb | 0:6ac5ba1343bf | 483 | } |
sigveseb | 0:6ac5ba1343bf | 484 | else |
sigveseb | 0:6ac5ba1343bf | 485 | { |
sigveseb | 0:6ac5ba1343bf | 486 | SPI_put_wait(0x00, this->EPD_Pin_BUSY); |
sigveseb | 0:6ac5ba1343bf | 487 | } |
sigveseb | 0:6ac5ba1343bf | 488 | } |
sigveseb | 0:6ac5ba1343bf | 489 | |
sigveseb | 0:6ac5ba1343bf | 490 | // odd pixels |
sigveseb | 0:6ac5ba1343bf | 491 | for (uint16_t b = 0; b < this->bytes_per_line; ++b) |
sigveseb | 0:6ac5ba1343bf | 492 | { |
sigveseb | 0:6ac5ba1343bf | 493 | if (0 != data) |
sigveseb | 0:6ac5ba1343bf | 494 | { |
sigveseb | 0:6ac5ba1343bf | 495 | uint8_t pixels = data[b] & 0x55; |
sigveseb | 0:6ac5ba1343bf | 496 | |
sigveseb | 0:6ac5ba1343bf | 497 | |
sigveseb | 0:6ac5ba1343bf | 498 | switch(stage) |
sigveseb | 0:6ac5ba1343bf | 499 | { |
sigveseb | 0:6ac5ba1343bf | 500 | case EPD_compensate: // B -> W, W -> B (Current Image) |
sigveseb | 0:6ac5ba1343bf | 501 | pixels = 0xaa | (pixels ^ 0x55); |
sigveseb | 0:6ac5ba1343bf | 502 | break; |
sigveseb | 0:6ac5ba1343bf | 503 | case EPD_white: // B -> N, W -> W (Current Image) |
sigveseb | 0:6ac5ba1343bf | 504 | pixels = 0x55 + (pixels ^ 0x55); |
sigveseb | 0:6ac5ba1343bf | 505 | break; |
sigveseb | 0:6ac5ba1343bf | 506 | case EPD_inverse: // B -> N, W -> B (New Image) |
sigveseb | 0:6ac5ba1343bf | 507 | pixels = 0x55 | ((pixels ^ 0x55) << 1); |
sigveseb | 0:6ac5ba1343bf | 508 | break; |
sigveseb | 0:6ac5ba1343bf | 509 | case EPD_normal: // B -> B, W -> W (New Image) |
sigveseb | 0:6ac5ba1343bf | 510 | pixels = 0xaa | pixels; |
sigveseb | 0:6ac5ba1343bf | 511 | break; |
sigveseb | 0:6ac5ba1343bf | 512 | } |
sigveseb | 0:6ac5ba1343bf | 513 | uint8_t p1 = (pixels >> 6) & 0x03; |
sigveseb | 0:6ac5ba1343bf | 514 | uint8_t p2 = (pixels >> 4) & 0x03; |
sigveseb | 0:6ac5ba1343bf | 515 | uint8_t p3 = (pixels >> 2) & 0x03; |
sigveseb | 0:6ac5ba1343bf | 516 | uint8_t p4 = (pixels >> 0) & 0x03; |
sigveseb | 0:6ac5ba1343bf | 517 | pixels = (p1 << 0) | (p2 << 2) | (p3 << 4) | (p4 << 6); |
sigveseb | 0:6ac5ba1343bf | 518 | SPI_put_wait(pixels, this->EPD_Pin_BUSY); |
sigveseb | 0:6ac5ba1343bf | 519 | } |
sigveseb | 0:6ac5ba1343bf | 520 | else |
sigveseb | 0:6ac5ba1343bf | 521 | { |
sigveseb | 0:6ac5ba1343bf | 522 | SPI_put_wait(fixed_value, this->EPD_Pin_BUSY); |
sigveseb | 0:6ac5ba1343bf | 523 | } |
sigveseb | 0:6ac5ba1343bf | 524 | } |
sigveseb | 0:6ac5ba1343bf | 525 | |
sigveseb | 0:6ac5ba1343bf | 526 | if (this->filler) |
sigveseb | 0:6ac5ba1343bf | 527 | { |
sigveseb | 0:6ac5ba1343bf | 528 | SPI_put_wait(0x00, this->EPD_Pin_BUSY); |
sigveseb | 0:6ac5ba1343bf | 529 | } |
sigveseb | 0:6ac5ba1343bf | 530 | |
sigveseb | 0:6ac5ba1343bf | 531 | // CS high |
sigveseb | 0:6ac5ba1343bf | 532 | this->EPD_Pin_EPD_CS = 1; |
sigveseb | 0:6ac5ba1343bf | 533 | |
sigveseb | 0:6ac5ba1343bf | 534 | // output data to panel |
sigveseb | 0:6ac5ba1343bf | 535 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 536 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x70, 0x02), 2); |
sigveseb | 0:6ac5ba1343bf | 537 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 538 | SPI_send(this->EPD_Pin_EPD_CS, CU8(0x72, 0x2f), 2); |
sigveseb | 0:6ac5ba1343bf | 539 | } |
sigveseb | 0:6ac5ba1343bf | 540 | |
thierryc49 | 2:c5bb7d34974d | 541 | void EPD_Class::SPI_on() { |
sigveseb | 0:6ac5ba1343bf | 542 | wait_us(10); |
sigveseb | 0:6ac5ba1343bf | 543 | } |
sigveseb | 0:6ac5ba1343bf | 544 | |
sigveseb | 0:6ac5ba1343bf | 545 | |
thierryc49 | 2:c5bb7d34974d | 546 | void EPD_Class::SPI_put(uint8_t c) { |
sigveseb | 0:6ac5ba1343bf | 547 | spi.write(c); |
sigveseb | 0:6ac5ba1343bf | 548 | } |
sigveseb | 0:6ac5ba1343bf | 549 | |
sigveseb | 0:6ac5ba1343bf | 550 | |
thierryc49 | 2:c5bb7d34974d | 551 | void EPD_Class::SPI_put_wait(uint8_t c, DigitalIn busy_pin) { |
sigveseb | 0:6ac5ba1343bf | 552 | |
sigveseb | 0:6ac5ba1343bf | 553 | SPI_put(c); |
sigveseb | 0:6ac5ba1343bf | 554 | |
sigveseb | 0:6ac5ba1343bf | 555 | // wait for COG ready |
sigveseb | 0:6ac5ba1343bf | 556 | while (1 == busy_pin) { |
sigveseb | 0:6ac5ba1343bf | 557 | } |
sigveseb | 0:6ac5ba1343bf | 558 | } |
sigveseb | 0:6ac5ba1343bf | 559 | |
sigveseb | 0:6ac5ba1343bf | 560 | |
thierryc49 | 2:c5bb7d34974d | 561 | void EPD_Class::SPI_send(DigitalOut cs_pin, const uint8_t *buffer, uint16_t length) { |
sigveseb | 0:6ac5ba1343bf | 562 | // CS low |
sigveseb | 0:6ac5ba1343bf | 563 | cs_pin = 0; |
sigveseb | 0:6ac5ba1343bf | 564 | |
sigveseb | 0:6ac5ba1343bf | 565 | // send all data |
sigveseb | 0:6ac5ba1343bf | 566 | for (uint16_t i = 0; i < length; ++i) { |
sigveseb | 0:6ac5ba1343bf | 567 | SPI_put(*buffer++); |
sigveseb | 0:6ac5ba1343bf | 568 | } |
sigveseb | 0:6ac5ba1343bf | 569 | |
sigveseb | 0:6ac5ba1343bf | 570 | // CS high |
sigveseb | 0:6ac5ba1343bf | 571 | cs_pin = 1; |
sigveseb | 0:6ac5ba1343bf | 572 | } |