Peter Drescher's library for the Embedded Artists E-paper display, but modified to also support the LPC4088 QuickStart Board

Dependents:   app_epaper

Fork of EaEpaper by Peter Drescher

Committer:
embeddedartists
Date:
Wed Dec 04 12:51:40 2013 +0000
Revision:
3:6fb3e296a6fd
Parent:
0:fedcef5319f5
Added support for the LPC4088 QuickStart Board and more specifically the LPC4088 QSB Base Board

Who changed what in which revision?

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