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