Library to control the EM027BS013 ePaper display from Pervasive Display.

Dependencies:   LM75B

Dependents:   app_epaper_EM027BS013_LPC1549 lpc4088_ebb_epaper EaEpaper_EM027BS013 app_epaper_EM027BS013 ... more

Committer:
embeddedartists
Date:
Tue Jul 22 11:59:06 2014 +0000
Revision:
0:9297e33f50cf
First version of library for the EM027BS013 ePaper display.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
embeddedartists 0:9297e33f50cf 1 /**
embeddedartists 0:9297e33f50cf 2 * \file
embeddedartists 0:9297e33f50cf 3 *
embeddedartists 0:9297e33f50cf 4 * \brief The waveform driving processes and updating stages of G2 COG with V230 EPD
embeddedartists 0:9297e33f50cf 5 *
embeddedartists 0:9297e33f50cf 6 * Copyright (c) 2012-2014 Pervasive Displays Inc. All rights reserved.
embeddedartists 0:9297e33f50cf 7 *
embeddedartists 0:9297e33f50cf 8 * \asf_license_start
embeddedartists 0:9297e33f50cf 9 *
embeddedartists 0:9297e33f50cf 10 * \page License
embeddedartists 0:9297e33f50cf 11 *
embeddedartists 0:9297e33f50cf 12 * Redistribution and use in source and binary forms, with or without
embeddedartists 0:9297e33f50cf 13 * modification, are permitted provided that the following conditions are met:
embeddedartists 0:9297e33f50cf 14 *
embeddedartists 0:9297e33f50cf 15 * 1. Redistributions of source code must retain the above copyright notice,
embeddedartists 0:9297e33f50cf 16 * this list of conditions and the following disclaimer.
embeddedartists 0:9297e33f50cf 17 *
embeddedartists 0:9297e33f50cf 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
embeddedartists 0:9297e33f50cf 19 * this list of conditions and the following disclaimer in the documentation
embeddedartists 0:9297e33f50cf 20 * and/or other materials provided with the distribution.
embeddedartists 0:9297e33f50cf 21 *
embeddedartists 0:9297e33f50cf 22 * 3. The name of Atmel may not be used to endorse or promote products derived
embeddedartists 0:9297e33f50cf 23 * from this software without specific prior written permission.
embeddedartists 0:9297e33f50cf 24 *
embeddedartists 0:9297e33f50cf 25 * 4. This software may only be redistributed and used in connection with an
embeddedartists 0:9297e33f50cf 26 * Atmel microcontroller product.
embeddedartists 0:9297e33f50cf 27 *
embeddedartists 0:9297e33f50cf 28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
embeddedartists 0:9297e33f50cf 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
embeddedartists 0:9297e33f50cf 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
embeddedartists 0:9297e33f50cf 31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
embeddedartists 0:9297e33f50cf 32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
embeddedartists 0:9297e33f50cf 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
embeddedartists 0:9297e33f50cf 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
embeddedartists 0:9297e33f50cf 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
embeddedartists 0:9297e33f50cf 36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
embeddedartists 0:9297e33f50cf 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
embeddedartists 0:9297e33f50cf 38 * POSSIBILITY OF SUCH DAMAGE.
embeddedartists 0:9297e33f50cf 39 *
embeddedartists 0:9297e33f50cf 40 * \asf_license_stop
embeddedartists 0:9297e33f50cf 41 **/
embeddedartists 0:9297e33f50cf 42
embeddedartists 0:9297e33f50cf 43 #include "EPD_COG_process.h"
embeddedartists 0:9297e33f50cf 44 #ifdef COG_V230_G2
embeddedartists 0:9297e33f50cf 45
embeddedartists 0:9297e33f50cf 46 #define ADDRESS_NULL 0xffffffff
embeddedartists 0:9297e33f50cf 47 //EPD Panel parameters
embeddedartists 0:9297e33f50cf 48 const struct COG_parameters_t COG_parameters[COUNT_OF_EPD_TYPE] = {
embeddedartists 0:9297e33f50cf 49 {
embeddedartists 0:9297e33f50cf 50 // FOR 1.44"
embeddedartists 0:9297e33f50cf 51 {0x00,0x00,0x00,0x00,0x00,0x0F,0xFF,0x00},
embeddedartists 0:9297e33f50cf 52 0x03,
embeddedartists 0:9297e33f50cf 53 (128/8),
embeddedartists 0:9297e33f50cf 54 96,
embeddedartists 0:9297e33f50cf 55 ((((128+96)*2)/8)+1),
embeddedartists 0:9297e33f50cf 56 0,
embeddedartists 0:9297e33f50cf 57 480
embeddedartists 0:9297e33f50cf 58 },
embeddedartists 0:9297e33f50cf 59 {
embeddedartists 0:9297e33f50cf 60 // For 2.0"
embeddedartists 0:9297e33f50cf 61 {0x00,0x00,0x00,0x00,0x01,0xFF,0xE0,0x00},
embeddedartists 0:9297e33f50cf 62 0x03,
embeddedartists 0:9297e33f50cf 63 (200/8),
embeddedartists 0:9297e33f50cf 64 96,
embeddedartists 0:9297e33f50cf 65 ((((200+96)*2)/8)+1),
embeddedartists 0:9297e33f50cf 66 0,
embeddedartists 0:9297e33f50cf 67 480
embeddedartists 0:9297e33f50cf 68 },
embeddedartists 0:9297e33f50cf 69 {
embeddedartists 0:9297e33f50cf 70 // For 2.7"
embeddedartists 0:9297e33f50cf 71 {0x00,0x00,0x00,0x7F,0xFF,0xFE,0x00,0x00},
embeddedartists 0:9297e33f50cf 72 0x00,
embeddedartists 0:9297e33f50cf 73 (264/8),
embeddedartists 0:9297e33f50cf 74 176,
embeddedartists 0:9297e33f50cf 75 ((((264+176)*2)/8)+1),
embeddedartists 0:9297e33f50cf 76 0,
embeddedartists 0:9297e33f50cf 77 630
embeddedartists 0:9297e33f50cf 78 }
embeddedartists 0:9297e33f50cf 79 };
embeddedartists 0:9297e33f50cf 80
embeddedartists 0:9297e33f50cf 81 /* \brief EPD Waveform parameters
embeddedartists 0:9297e33f50cf 82 * \note the parameters of waveform table below is different from the G2 COG document due to
embeddedartists 0:9297e33f50cf 83 * use block size is easier to achieve than accurate block time for different MCU.
embeddedartists 0:9297e33f50cf 84 * The approach is also working.
embeddedartists 0:9297e33f50cf 85 * */
embeddedartists 0:9297e33f50cf 86 const struct EPD_WaveformTable_Struct E_Waveform[COUNT_OF_EPD_TYPE][3] = {
embeddedartists 0:9297e33f50cf 87 {// FOR 1.44"
embeddedartists 0:9297e33f50cf 88 {//50 �� T �� 40
embeddedartists 0:9297e33f50cf 89 4, //stage1_frame1
embeddedartists 0:9297e33f50cf 90 16, //stage1_block1
embeddedartists 0:9297e33f50cf 91 2, //stage1_step1
embeddedartists 0:9297e33f50cf 92 155, //stage2_t1
embeddedartists 0:9297e33f50cf 93 155, //stage2_t2
embeddedartists 0:9297e33f50cf 94 4, //stage2_cycle
embeddedartists 0:9297e33f50cf 95 4, //stage3_frame3
embeddedartists 0:9297e33f50cf 96 16, //stage3_block3
embeddedartists 0:9297e33f50cf 97 2 //stage3_step3
embeddedartists 0:9297e33f50cf 98 }
embeddedartists 0:9297e33f50cf 99 ,{//40 �� T �� 10
embeddedartists 0:9297e33f50cf 100 4, //stage1_frame1
embeddedartists 0:9297e33f50cf 101 16, //stage1_block1
embeddedartists 0:9297e33f50cf 102 2, //stage1_step1
embeddedartists 0:9297e33f50cf 103 155, //stage2_t1
embeddedartists 0:9297e33f50cf 104 155, //stage2_t2
embeddedartists 0:9297e33f50cf 105 4, //stage2_cycle
embeddedartists 0:9297e33f50cf 106 4, //stage3_frame3
embeddedartists 0:9297e33f50cf 107 16, //stage3_block3
embeddedartists 0:9297e33f50cf 108 2 //stage3_step3
embeddedartists 0:9297e33f50cf 109 },
embeddedartists 0:9297e33f50cf 110 {//10 �� T �� 0
embeddedartists 0:9297e33f50cf 111 2, //stage1_frame1
embeddedartists 0:9297e33f50cf 112 42, //stage1_block1
embeddedartists 0:9297e33f50cf 113 6, //stage1_step1
embeddedartists 0:9297e33f50cf 114 392, //stage2_t1
embeddedartists 0:9297e33f50cf 115 392, //stage2_t2
embeddedartists 0:9297e33f50cf 116 4, //stage2_cycle
embeddedartists 0:9297e33f50cf 117 2, //stage3_frame3
embeddedartists 0:9297e33f50cf 118 42, //stage3_block3
embeddedartists 0:9297e33f50cf 119 6 //stage3_step3
embeddedartists 0:9297e33f50cf 120 }
embeddedartists 0:9297e33f50cf 121
embeddedartists 0:9297e33f50cf 122 },
embeddedartists 0:9297e33f50cf 123 {// For 2.0"
embeddedartists 0:9297e33f50cf 124 {//50 �� T �� 40
embeddedartists 0:9297e33f50cf 125 4, //stage1_frame1
embeddedartists 0:9297e33f50cf 126 36, //stage1_block1
embeddedartists 0:9297e33f50cf 127 2, //stage1_step1
embeddedartists 0:9297e33f50cf 128 196, //stage2_t1
embeddedartists 0:9297e33f50cf 129 196, //stage2_t2
embeddedartists 0:9297e33f50cf 130 4, //stage2_cycle
embeddedartists 0:9297e33f50cf 131 4, //stage3_frame3
embeddedartists 0:9297e33f50cf 132 36, //stage3_block3
embeddedartists 0:9297e33f50cf 133 2 //stage3_step3
embeddedartists 0:9297e33f50cf 134 },
embeddedartists 0:9297e33f50cf 135 {//40 �� T �� 10
embeddedartists 0:9297e33f50cf 136 2, //stage1_frame1
embeddedartists 0:9297e33f50cf 137 36, //stage1_block1
embeddedartists 0:9297e33f50cf 138 2, //stage1_step1
embeddedartists 0:9297e33f50cf 139 196, //stage2_t1
embeddedartists 0:9297e33f50cf 140 196, //stage2_t2
embeddedartists 0:9297e33f50cf 141 4, //stage2_cycle
embeddedartists 0:9297e33f50cf 142 2, //stage3_frame3
embeddedartists 0:9297e33f50cf 143 36, //stage3_block3
embeddedartists 0:9297e33f50cf 144 2 //stage3_step3
embeddedartists 0:9297e33f50cf 145 },
embeddedartists 0:9297e33f50cf 146 {//10 �� T �� 0
embeddedartists 0:9297e33f50cf 147 2, //stage1_frame1
embeddedartists 0:9297e33f50cf 148 36, //stage1_block1
embeddedartists 0:9297e33f50cf 149 2, //stage1_step1
embeddedartists 0:9297e33f50cf 150 392, //stage2_t1
embeddedartists 0:9297e33f50cf 151 392, //stage2_t2
embeddedartists 0:9297e33f50cf 152 4, //stage2_cycle
embeddedartists 0:9297e33f50cf 153 2, //stage3_frame3
embeddedartists 0:9297e33f50cf 154 36, //stage3_block3
embeddedartists 0:9297e33f50cf 155 2 //stage3_step3
embeddedartists 0:9297e33f50cf 156 }
embeddedartists 0:9297e33f50cf 157 },
embeddedartists 0:9297e33f50cf 158 {// For 2.7"
embeddedartists 0:9297e33f50cf 159 {//50 �� T �� 40
embeddedartists 0:9297e33f50cf 160 4, //stage1_frame1
embeddedartists 0:9297e33f50cf 161 28, //stage1_block1
embeddedartists 0:9297e33f50cf 162 4, //stage1_step1
embeddedartists 0:9297e33f50cf 163 196, //stage2_t1
embeddedartists 0:9297e33f50cf 164 196, //stage2_t2
embeddedartists 0:9297e33f50cf 165 4, //stage2_cycle
embeddedartists 0:9297e33f50cf 166 4, //stage3_frame3
embeddedartists 0:9297e33f50cf 167 28, //stage3_block3
embeddedartists 0:9297e33f50cf 168 4 //stage3_step3
embeddedartists 0:9297e33f50cf 169 },
embeddedartists 0:9297e33f50cf 170 {//40 �� T �� 10
embeddedartists 0:9297e33f50cf 171 2, //stage1_frame1
embeddedartists 0:9297e33f50cf 172 28, //stage1_block1
embeddedartists 0:9297e33f50cf 173 2, //stage1_step1
embeddedartists 0:9297e33f50cf 174 196, //stage2_t1
embeddedartists 0:9297e33f50cf 175 196, //stage2_t2
embeddedartists 0:9297e33f50cf 176 4, //stage2_cycle
embeddedartists 0:9297e33f50cf 177 2, //stage3_frame3
embeddedartists 0:9297e33f50cf 178 28, //stage3_block3
embeddedartists 0:9297e33f50cf 179 2 //stage3_step3
embeddedartists 0:9297e33f50cf 180 },
embeddedartists 0:9297e33f50cf 181 {//10 �� T �� 0
embeddedartists 0:9297e33f50cf 182 2, //stage1_frame1
embeddedartists 0:9297e33f50cf 183 28, //stage1_block1
embeddedartists 0:9297e33f50cf 184 4, //stage1_step1
embeddedartists 0:9297e33f50cf 185 392, //stage2_t1
embeddedartists 0:9297e33f50cf 186 392, //stage2_t2
embeddedartists 0:9297e33f50cf 187 4, //stage2_cycle
embeddedartists 0:9297e33f50cf 188 2, //stage3_frame3
embeddedartists 0:9297e33f50cf 189 28, //stage3_block3
embeddedartists 0:9297e33f50cf 190 4 //stage3_step3
embeddedartists 0:9297e33f50cf 191 }
embeddedartists 0:9297e33f50cf 192 },
embeddedartists 0:9297e33f50cf 193
embeddedartists 0:9297e33f50cf 194 };
embeddedartists 0:9297e33f50cf 195
embeddedartists 0:9297e33f50cf 196 const uint8_t SCAN_TABLE[4] = {0xC0,0x30,0x0C,0x03};
embeddedartists 0:9297e33f50cf 197
embeddedartists 0:9297e33f50cf 198 static struct EPD_WaveformTable_Struct *action__Waveform_param;
embeddedartists 0:9297e33f50cf 199 static COG_line_data_packet_type COG_Line;
embeddedartists 0:9297e33f50cf 200 static EPD_read_flash_handler _On_EPD_read_flash;
embeddedartists 0:9297e33f50cf 201 static uint8_t *data_line_even;
embeddedartists 0:9297e33f50cf 202 static uint8_t *data_line_odd;
embeddedartists 0:9297e33f50cf 203 static uint8_t *data_line_scan;
embeddedartists 0:9297e33f50cf 204 static uint8_t *data_line_border_byte;
embeddedartists 0:9297e33f50cf 205
embeddedartists 0:9297e33f50cf 206 /**
embeddedartists 0:9297e33f50cf 207 * \brief According to EPD size and temperature to get stage_time
embeddedartists 0:9297e33f50cf 208 * \note Refer to COG document Section 5.3 for more details
embeddedartists 0:9297e33f50cf 209 *
embeddedartists 0:9297e33f50cf 210 * \param EPD_type_index The defined EPD size
embeddedartists 0:9297e33f50cf 211 */
embeddedartists 0:9297e33f50cf 212 static void set_temperature_factor(uint8_t EPD_type_index) {
embeddedartists 0:9297e33f50cf 213 int8_t temperature;
embeddedartists 0:9297e33f50cf 214 temperature = get_temperature();
embeddedartists 0:9297e33f50cf 215 if (50 >= temperature && temperature > 40){
embeddedartists 0:9297e33f50cf 216 action__Waveform_param=(struct EPD_WaveformTable_Struct *)&E_Waveform[EPD_type_index][0];
embeddedartists 0:9297e33f50cf 217 }else if (40 >= temperature && temperature > 10){
embeddedartists 0:9297e33f50cf 218 action__Waveform_param=(struct EPD_WaveformTable_Struct *)&E_Waveform[EPD_type_index][1];
embeddedartists 0:9297e33f50cf 219 }else if (10 >= temperature && temperature > 0){
embeddedartists 0:9297e33f50cf 220 action__Waveform_param=(struct EPD_WaveformTable_Struct *)&E_Waveform[EPD_type_index][2];
embeddedartists 0:9297e33f50cf 221 }else action__Waveform_param=(struct EPD_WaveformTable_Struct *)&E_Waveform[EPD_type_index][1]; //Default
embeddedartists 0:9297e33f50cf 222 }
embeddedartists 0:9297e33f50cf 223
embeddedartists 0:9297e33f50cf 224 /**
embeddedartists 0:9297e33f50cf 225 * \brief Initialize the EPD hardware setting
embeddedartists 0:9297e33f50cf 226 */
embeddedartists 0:9297e33f50cf 227 void EPD_init(void) {
embeddedartists 0:9297e33f50cf 228 EPD_display_hardware_init();
embeddedartists 0:9297e33f50cf 229 EPD_cs_low();
embeddedartists 0:9297e33f50cf 230 EPD_rst_low();
embeddedartists 0:9297e33f50cf 231 EPD_discharge_low();
embeddedartists 0:9297e33f50cf 232 EPD_border_low();
embeddedartists 0:9297e33f50cf 233 }
embeddedartists 0:9297e33f50cf 234
embeddedartists 0:9297e33f50cf 235 /**
embeddedartists 0:9297e33f50cf 236 * \brief Select the EPD size to get line data array for driving COG
embeddedartists 0:9297e33f50cf 237 *
embeddedartists 0:9297e33f50cf 238 * \param EPD_type_index The defined EPD size
embeddedartists 0:9297e33f50cf 239 */
embeddedartists 0:9297e33f50cf 240 void COG_driver_EPDtype_select(uint8_t EPD_type_index) {
embeddedartists 0:9297e33f50cf 241 switch(EPD_type_index) {
embeddedartists 0:9297e33f50cf 242 case EPD_144:
embeddedartists 0:9297e33f50cf 243 data_line_even = &COG_Line.line_data_by_size.line_data_for_144.even[0];
embeddedartists 0:9297e33f50cf 244 data_line_odd = &COG_Line.line_data_by_size.line_data_for_144.odd[0];
embeddedartists 0:9297e33f50cf 245 data_line_scan = &COG_Line.line_data_by_size.line_data_for_144.scan[0];
embeddedartists 0:9297e33f50cf 246 data_line_border_byte = &COG_Line.line_data_by_size.line_data_for_144.border_byte;
embeddedartists 0:9297e33f50cf 247 break;
embeddedartists 0:9297e33f50cf 248 case EPD_200:
embeddedartists 0:9297e33f50cf 249 data_line_even = &COG_Line.line_data_by_size.line_data_for_200.even[0];
embeddedartists 0:9297e33f50cf 250 data_line_odd = &COG_Line.line_data_by_size.line_data_for_200.odd[0];
embeddedartists 0:9297e33f50cf 251 data_line_scan = &COG_Line.line_data_by_size.line_data_for_200.scan[0];
embeddedartists 0:9297e33f50cf 252 data_line_border_byte = &COG_Line.line_data_by_size.line_data_for_200.border_byte;
embeddedartists 0:9297e33f50cf 253 break;
embeddedartists 0:9297e33f50cf 254 case EPD_270:
embeddedartists 0:9297e33f50cf 255 data_line_even = &COG_Line.line_data_by_size.line_data_for_270.even[0];
embeddedartists 0:9297e33f50cf 256 data_line_odd = &COG_Line.line_data_by_size.line_data_for_270.odd[0];
embeddedartists 0:9297e33f50cf 257 data_line_scan = &COG_Line.line_data_by_size.line_data_for_270.scan[0];
embeddedartists 0:9297e33f50cf 258 data_line_border_byte = &COG_Line.line_data_by_size.line_data_for_270.border_byte;
embeddedartists 0:9297e33f50cf 259 break;
embeddedartists 0:9297e33f50cf 260 }
embeddedartists 0:9297e33f50cf 261 }
embeddedartists 0:9297e33f50cf 262
embeddedartists 0:9297e33f50cf 263 /**
embeddedartists 0:9297e33f50cf 264 * \brief Power on COG Driver
embeddedartists 0:9297e33f50cf 265 * \note For detailed flow and description, please refer to the COG G2 document Section 3.
embeddedartists 0:9297e33f50cf 266 */
embeddedartists 0:9297e33f50cf 267 void EPD_power_on (void) {
embeddedartists 0:9297e33f50cf 268 /* Initial state */
embeddedartists 0:9297e33f50cf 269 EPD_Vcc_turn_on(); //Vcc and Vdd >= 2.7V
embeddedartists 0:9297e33f50cf 270 EPD_cs_high();
embeddedartists 0:9297e33f50cf 271 EPD_border_high();
embeddedartists 0:9297e33f50cf 272 EPD_rst_high();
embeddedartists 0:9297e33f50cf 273 delay_ms(5);
embeddedartists 0:9297e33f50cf 274 EPD_rst_low();
embeddedartists 0:9297e33f50cf 275 delay_ms(5);
embeddedartists 0:9297e33f50cf 276 EPD_rst_high();
embeddedartists 0:9297e33f50cf 277 delay_ms(5);
embeddedartists 0:9297e33f50cf 278 }
embeddedartists 0:9297e33f50cf 279
embeddedartists 0:9297e33f50cf 280
embeddedartists 0:9297e33f50cf 281 /**
embeddedartists 0:9297e33f50cf 282 * \brief Initialize COG Driver
embeddedartists 0:9297e33f50cf 283 * \note For detailed flow and description, please refer to the COG G2 document Section 4.
embeddedartists 0:9297e33f50cf 284 *
embeddedartists 0:9297e33f50cf 285 * \param EPD_type_index The defined EPD size
embeddedartists 0:9297e33f50cf 286 */
embeddedartists 0:9297e33f50cf 287 uint8_t EPD_initialize_driver (uint8_t EPD_type_index) {
embeddedartists 0:9297e33f50cf 288
embeddedartists 0:9297e33f50cf 289 uint16_t i;
embeddedartists 0:9297e33f50cf 290 // Empty the Line buffer
embeddedartists 0:9297e33f50cf 291 for (i = 0; i <= LINE_BUFFER_DATA_SIZE; i ++) {
embeddedartists 0:9297e33f50cf 292 COG_Line.uint8[i] = 0x00;
embeddedartists 0:9297e33f50cf 293 }
embeddedartists 0:9297e33f50cf 294 // Determine the EPD size for driving COG
embeddedartists 0:9297e33f50cf 295 COG_driver_EPDtype_select(EPD_type_index);
embeddedartists 0:9297e33f50cf 296
embeddedartists 0:9297e33f50cf 297 // Sense temperature to determine Temperature Factor
embeddedartists 0:9297e33f50cf 298 set_temperature_factor(EPD_type_index);
embeddedartists 0:9297e33f50cf 299 i = 0;
embeddedartists 0:9297e33f50cf 300
embeddedartists 0:9297e33f50cf 301 while (EPD_IsBusy()) {
embeddedartists 0:9297e33f50cf 302 if((i++) >= 0x0FFF) return ERROR_BUSY;
embeddedartists 0:9297e33f50cf 303 }
embeddedartists 0:9297e33f50cf 304
embeddedartists 0:9297e33f50cf 305 //Check COG ID
embeddedartists 0:9297e33f50cf 306 if((SPI_R(0x72,0x00) & 0x0f) !=0x02) return ERROR_COG_ID;
embeddedartists 0:9297e33f50cf 307
embeddedartists 0:9297e33f50cf 308 //Disable OE
embeddedartists 0:9297e33f50cf 309 epd_spi_send_byte(0x02,0x40);
embeddedartists 0:9297e33f50cf 310
embeddedartists 0:9297e33f50cf 311 //Check Breakage
embeddedartists 0:9297e33f50cf 312 if((SPI_R(0x0F,0x00) & 0x80) != 0x80) return ERROR_BREAKAGE;
embeddedartists 0:9297e33f50cf 313
embeddedartists 0:9297e33f50cf 314 //Power Saving Mode
embeddedartists 0:9297e33f50cf 315 epd_spi_send_byte(0x0B, 0x02);
embeddedartists 0:9297e33f50cf 316
embeddedartists 0:9297e33f50cf 317 //Channel Select
embeddedartists 0:9297e33f50cf 318 epd_spi_send (0x01, (uint8_t *)&COG_parameters[EPD_type_index].channel_select, 8);
embeddedartists 0:9297e33f50cf 319
embeddedartists 0:9297e33f50cf 320 //High Power Mode Osc Setting
embeddedartists 0:9297e33f50cf 321 epd_spi_send_byte(0x07,0xD1);
embeddedartists 0:9297e33f50cf 322
embeddedartists 0:9297e33f50cf 323 //Power Setting
embeddedartists 0:9297e33f50cf 324 epd_spi_send_byte(0x08,0x02);
embeddedartists 0:9297e33f50cf 325
embeddedartists 0:9297e33f50cf 326 //Set Vcom level
embeddedartists 0:9297e33f50cf 327 epd_spi_send_byte(0x09,0xC2);
embeddedartists 0:9297e33f50cf 328
embeddedartists 0:9297e33f50cf 329 //Power Setting
embeddedartists 0:9297e33f50cf 330 epd_spi_send_byte(0x04,0x03);
embeddedartists 0:9297e33f50cf 331
embeddedartists 0:9297e33f50cf 332 //Driver latch on
embeddedartists 0:9297e33f50cf 333 epd_spi_send_byte(0x03,0x01);
embeddedartists 0:9297e33f50cf 334
embeddedartists 0:9297e33f50cf 335 //Driver latch off
embeddedartists 0:9297e33f50cf 336 epd_spi_send_byte(0x03,0x00);
embeddedartists 0:9297e33f50cf 337
embeddedartists 0:9297e33f50cf 338 delay_ms(5);
embeddedartists 0:9297e33f50cf 339
embeddedartists 0:9297e33f50cf 340 //Chargepump Start
embeddedartists 0:9297e33f50cf 341 i=0;
embeddedartists 0:9297e33f50cf 342 do {
embeddedartists 0:9297e33f50cf 343 //Start chargepump positive V
embeddedartists 0:9297e33f50cf 344 //VGH & VDH on
embeddedartists 0:9297e33f50cf 345 epd_spi_send_byte(0x05,0x01);
embeddedartists 0:9297e33f50cf 346
embeddedartists 0:9297e33f50cf 347 delay_ms(240);
embeddedartists 0:9297e33f50cf 348
embeddedartists 0:9297e33f50cf 349 //Start chargepump neg voltage
embeddedartists 0:9297e33f50cf 350 //VGL & VDL on
embeddedartists 0:9297e33f50cf 351 epd_spi_send_byte(0x05,0x03);
embeddedartists 0:9297e33f50cf 352
embeddedartists 0:9297e33f50cf 353 delay_ms(40);
embeddedartists 0:9297e33f50cf 354
embeddedartists 0:9297e33f50cf 355 //Set chargepump
embeddedartists 0:9297e33f50cf 356 //Vcom_Driver to ON
embeddedartists 0:9297e33f50cf 357 //Vcom_Driver on
embeddedartists 0:9297e33f50cf 358 epd_spi_send_byte(0x05,0x0F);
embeddedartists 0:9297e33f50cf 359
embeddedartists 0:9297e33f50cf 360 delay_ms(40);
embeddedartists 0:9297e33f50cf 361
embeddedartists 0:9297e33f50cf 362 //Check DC/DC
embeddedartists 0:9297e33f50cf 363 if((SPI_R(0x0F,0x00) & 0x40) != 0x00) break;
embeddedartists 0:9297e33f50cf 364
embeddedartists 0:9297e33f50cf 365 }while((i++) != 4);
embeddedartists 0:9297e33f50cf 366
embeddedartists 0:9297e33f50cf 367 if(i>=4)
embeddedartists 0:9297e33f50cf 368 {
embeddedartists 0:9297e33f50cf 369 //Output enable to disable
embeddedartists 0:9297e33f50cf 370 epd_spi_send_byte(0x02,0x40);
embeddedartists 0:9297e33f50cf 371 return ERROR_CHARGEPUMP;
embeddedartists 0:9297e33f50cf 372 }
embeddedartists 0:9297e33f50cf 373 else return RES_OK;
embeddedartists 0:9297e33f50cf 374 }
embeddedartists 0:9297e33f50cf 375
embeddedartists 0:9297e33f50cf 376 /**
embeddedartists 0:9297e33f50cf 377 * \brief Initialize the parameters of Block type stage
embeddedartists 0:9297e33f50cf 378 *
embeddedartists 0:9297e33f50cf 379 * \param EPD_type_index The defined EPD size
embeddedartists 0:9297e33f50cf 380 * \param EPD_V230_G2_Struct The Block type waveform structure
embeddedartists 0:9297e33f50cf 381 * \param block_size The width of Block size
embeddedartists 0:9297e33f50cf 382 * \param step_size The width of Step size
embeddedartists 0:9297e33f50cf 383 * \param frame_cycle The width of Step size
embeddedartists 0:9297e33f50cf 384 */
embeddedartists 0:9297e33f50cf 385 void stage_init(uint8_t EPD_type_index,struct EPD_V230_G2_Struct *S_epd_v230,
embeddedartists 0:9297e33f50cf 386 uint8_t block_size,uint8_t step_size,
embeddedartists 0:9297e33f50cf 387 uint8_t frame_cycle)
embeddedartists 0:9297e33f50cf 388 {
embeddedartists 0:9297e33f50cf 389 S_epd_v230->frame_y0 = 0;
embeddedartists 0:9297e33f50cf 390 S_epd_v230->frame_y1 = 176;
embeddedartists 0:9297e33f50cf 391 S_epd_v230->block_y0 = 0;
embeddedartists 0:9297e33f50cf 392 S_epd_v230->block_y1 = 0;
embeddedartists 0:9297e33f50cf 393 S_epd_v230->step_y0 = 0;
embeddedartists 0:9297e33f50cf 394 S_epd_v230->step_y1 = 0;
embeddedartists 0:9297e33f50cf 395 S_epd_v230->block_size = action__Waveform_param->stage1_block1;
embeddedartists 0:9297e33f50cf 396 S_epd_v230->step_size =action__Waveform_param->stage1_step1;
embeddedartists 0:9297e33f50cf 397 S_epd_v230->frame_cycle = action__Waveform_param->stage1_frame1;
embeddedartists 0:9297e33f50cf 398 S_epd_v230->number_of_steps = (COG_parameters[EPD_type_index].vertical_size / S_epd_v230->step_size) + (action__Waveform_param->stage1_block1 / action__Waveform_param->stage1_step1) -1;
embeddedartists 0:9297e33f50cf 399
embeddedartists 0:9297e33f50cf 400 }
embeddedartists 0:9297e33f50cf 401
embeddedartists 0:9297e33f50cf 402 /**
embeddedartists 0:9297e33f50cf 403 * \brief For Frame type waveform to update all black/white pattern
embeddedartists 0:9297e33f50cf 404 *
embeddedartists 0:9297e33f50cf 405 * \param EPD_type_index The defined EPD size
embeddedartists 0:9297e33f50cf 406 * \param bwdata Black or White color to whole screen
embeddedartists 0:9297e33f50cf 407 * \param work_time The working time
embeddedartists 0:9297e33f50cf 408 */
embeddedartists 0:9297e33f50cf 409 static inline void same_data_frame (uint8_t EPD_type_index, uint8_t bwdata, uint32_t work_time) {
embeddedartists 0:9297e33f50cf 410 uint16_t i;
embeddedartists 0:9297e33f50cf 411 for (i = 0; i < COG_parameters[EPD_type_index].horizontal_size; i++) {
embeddedartists 0:9297e33f50cf 412 data_line_even[i]=bwdata;
embeddedartists 0:9297e33f50cf 413 data_line_odd[i]=bwdata;
embeddedartists 0:9297e33f50cf 414 }
embeddedartists 0:9297e33f50cf 415 start_EPD_timer();
embeddedartists 0:9297e33f50cf 416 do
embeddedartists 0:9297e33f50cf 417 {
embeddedartists 0:9297e33f50cf 418 for (i = 0; i < COG_parameters[EPD_type_index].vertical_size; i++) {
embeddedartists 0:9297e33f50cf 419
embeddedartists 0:9297e33f50cf 420 /* Scan byte shift per data line */
embeddedartists 0:9297e33f50cf 421 data_line_scan[(i>>2)]=SCAN_TABLE[(i%4)];
embeddedartists 0:9297e33f50cf 422
embeddedartists 0:9297e33f50cf 423 /* Sending data */
embeddedartists 0:9297e33f50cf 424 epd_spi_send (0x0A, (uint8_t *)&COG_Line.uint8, COG_parameters[EPD_type_index].data_line_size);
embeddedartists 0:9297e33f50cf 425
embeddedartists 0:9297e33f50cf 426 /* Turn on Output Enable */
embeddedartists 0:9297e33f50cf 427 epd_spi_send_byte (0x02, 0x07);
embeddedartists 0:9297e33f50cf 428
embeddedartists 0:9297e33f50cf 429 data_line_scan[(i>>2)]=0;
embeddedartists 0:9297e33f50cf 430
embeddedartists 0:9297e33f50cf 431 }
embeddedartists 0:9297e33f50cf 432 } while (get_current_time_tick()<(work_time));
embeddedartists 0:9297e33f50cf 433 /* Stop system timer */
embeddedartists 0:9297e33f50cf 434 stop_EPD_timer();
embeddedartists 0:9297e33f50cf 435 }
embeddedartists 0:9297e33f50cf 436
embeddedartists 0:9297e33f50cf 437 /**
embeddedartists 0:9297e33f50cf 438 * \brief Write nothing Line to COG
embeddedartists 0:9297e33f50cf 439 * \note A line whose all Scan Bytes are 0x00
embeddedartists 0:9297e33f50cf 440 *
embeddedartists 0:9297e33f50cf 441 * \param EPD_type_index The defined EPD size
embeddedartists 0:9297e33f50cf 442 */
embeddedartists 0:9297e33f50cf 443 void nothing_line(uint8_t EPD_type_index) {
embeddedartists 0:9297e33f50cf 444 uint16_t i;
embeddedartists 0:9297e33f50cf 445 for (i = 0; i < COG_parameters[EPD_type_index].horizontal_size; i++) {
embeddedartists 0:9297e33f50cf 446 data_line_even[i] = NOTHING;
embeddedartists 0:9297e33f50cf 447 data_line_odd[i] = NOTHING;
embeddedartists 0:9297e33f50cf 448 }
embeddedartists 0:9297e33f50cf 449 }
embeddedartists 0:9297e33f50cf 450
embeddedartists 0:9297e33f50cf 451
embeddedartists 0:9297e33f50cf 452 /**
embeddedartists 0:9297e33f50cf 453 * \brief Get line data of Stage 1 and 3
embeddedartists 0:9297e33f50cf 454 *
embeddedartists 0:9297e33f50cf 455 * \note
embeddedartists 0:9297e33f50cf 456 * - One dot/pixel is comprised of 2 bits which are White(10), Black(11) or Nothing(01).
embeddedartists 0:9297e33f50cf 457 * The image data bytes must be divided into Odd and Even bytes.
embeddedartists 0:9297e33f50cf 458 * - The COG driver uses a buffer to write one line of data (FIFO) - interlaced
embeddedartists 0:9297e33f50cf 459 * It's different order from COG_G1
embeddedartists 0:9297e33f50cf 460 * Odd byte {D(199,y),D(197,y), D(195,y), D(193,y)}, ... ,{D(7,y),D(5,y),D(3,y), D(1,y)}
embeddedartists 0:9297e33f50cf 461 * Scan byte {S(96), S(95)...}
embeddedartists 0:9297e33f50cf 462 * Odd byte {D(2,y),D(4,y), D(6,y), D(8,y)}, ... ,{D(194,y),D(196,y),D(198,y), D(200,y)}
embeddedartists 0:9297e33f50cf 463 * - For more details on the driving stages, please refer to the COG G2 document Section 5.
embeddedartists 0:9297e33f50cf 464 *
embeddedartists 0:9297e33f50cf 465 * \param EPD_type_index The defined EPD size
embeddedartists 0:9297e33f50cf 466 * \param image_ptr The pointer of memory that stores image that will send to COG
embeddedartists 0:9297e33f50cf 467 * \param stage_no The assigned stage number that will proceed
embeddedartists 0:9297e33f50cf 468 */
embeddedartists 0:9297e33f50cf 469
embeddedartists 0:9297e33f50cf 470 void read_line_data_handle(uint8_t EPD_type_index,uint8_t *image_prt,uint8_t stage_no)
embeddedartists 0:9297e33f50cf 471 {
embeddedartists 0:9297e33f50cf 472 int16_t x,k;
embeddedartists 0:9297e33f50cf 473 uint8_t temp_byte; // Temporary storage for image data check
embeddedartists 0:9297e33f50cf 474 k=COG_parameters[EPD_type_index].horizontal_size-1;
embeddedartists 0:9297e33f50cf 475 for (x =0 ; x < COG_parameters[EPD_type_index].horizontal_size ; x++) {
embeddedartists 0:9297e33f50cf 476 temp_byte = *image_prt++;
embeddedartists 0:9297e33f50cf 477 switch(stage_no) {
embeddedartists 0:9297e33f50cf 478 case Stage1: // Inverse image
embeddedartists 0:9297e33f50cf 479 /* Example at stage 1 to get Even and Odd data. It's different order from G1.
embeddedartists 0:9297e33f50cf 480 * +---------+----+----+----+----+----+----+----+----+
embeddedartists 0:9297e33f50cf 481 * | |bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|
embeddedartists 0:9297e33f50cf 482 * |temp_byte+----+----+----+----+----+----+----+----+
embeddedartists 0:9297e33f50cf 483 * | | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 |
embeddedartists 0:9297e33f50cf 484 * +---------+----+----+----+----+----+----+----+----+ */
embeddedartists 0:9297e33f50cf 485 data_line_odd[x] = ((temp_byte & 0x40) ? BLACK3 : WHITE3); // WHITE3 = 0x80 = 1000 0000
embeddedartists 0:9297e33f50cf 486 data_line_odd[x] |= ((temp_byte & 0x10) ? BLACK2 : WHITE2); // BLACK2 = 0x30 = 0011 0000
embeddedartists 0:9297e33f50cf 487 data_line_odd[x] |= ((temp_byte & 0x04) ? BLACK1 : WHITE1); // BLACK1 = 0x0C = 0000 1100
embeddedartists 0:9297e33f50cf 488 data_line_odd[x] |= ((temp_byte & 0x01) ? BLACK0 : WHITE0); // WHITE0 = 0x02 = 0000 0010
embeddedartists 0:9297e33f50cf 489 /* data_line_odd[x] = 1000 0000 | 0011 0000 | 0000 1100 | 0000 0010 = 1011 1110 ==> 1011 1110
embeddedartists 0:9297e33f50cf 490 * See Even data row at the table below*/
embeddedartists 0:9297e33f50cf 491
embeddedartists 0:9297e33f50cf 492 data_line_even[k] = ((temp_byte & 0x80) ? BLACK0 : WHITE0); // BLACK0 = 0x03 = 0000 0011
embeddedartists 0:9297e33f50cf 493 data_line_even[k] |= ((temp_byte & 0x20) ? BLACK1 : WHITE1); // BLACK1 = 0x0C = 0000 1100
embeddedartists 0:9297e33f50cf 494 data_line_even[k] |= ((temp_byte & 0x08) ? BLACK2 : WHITE2); // WHITE2 = 0x20 = 0010 0000
embeddedartists 0:9297e33f50cf 495 data_line_even[k--] |= ((temp_byte & 0x02) ? BLACK3 : WHITE3); // WHITE3 = 0x80 = 1000 0000
embeddedartists 0:9297e33f50cf 496 /* data_line_even[k] = 0000 0011 | 0000 1100 | 0010 0000 | 1000 0000 = 1010 1111 ==> 1111 1010
embeddedartists 0:9297e33f50cf 497 * See Odd data row at the table below
embeddedartists 0:9297e33f50cf 498 * +---------+----+----+----+----+----+----+----+----+
embeddedartists 0:9297e33f50cf 499 * | |bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|
embeddedartists 0:9297e33f50cf 500 * |temp_byte+----+----+----+----+----+----+----+----+
embeddedartists 0:9297e33f50cf 501 * | | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 |
embeddedartists 0:9297e33f50cf 502 * +---------+----+----+----+----+----+----+----+----+
embeddedartists 0:9297e33f50cf 503 * | Color | W | B | W | W | B | W | B | B | W=White, B=Black, N=Nothing
embeddedartists 0:9297e33f50cf 504 * +---------+----+----+----+----+----+----+----+----+
embeddedartists 0:9297e33f50cf 505 * | Stage 1 | B | W | B | B | W | B | W | W | Inverse
embeddedartists 0:9297e33f50cf 506 * +---------+----+----+----+----+----+----+----+----+
embeddedartists 0:9297e33f50cf 507 * | Input | 11 | 10 | 11 | 11 | 10 | 11 | 10 | 10 | W=10, B=11, N=01
embeddedartists 0:9297e33f50cf 508 * +---------+----+----+----+----+----+----+----+----+
embeddedartists 0:9297e33f50cf 509 * |Even data| 11 | | 11 | | 10 | | 10 | | = 1111 1010
embeddedartists 0:9297e33f50cf 510 * +---------+----+----+----+----+----+----+----+----+
embeddedartists 0:9297e33f50cf 511 * |Odd data | | 10 | | 11 | | 11 | | 10 | = 1011 1110
embeddedartists 0:9297e33f50cf 512 * +---------+----+----+----+----+----+----+----+----+ */
embeddedartists 0:9297e33f50cf 513 break;
embeddedartists 0:9297e33f50cf 514 case Stage3: // New image
embeddedartists 0:9297e33f50cf 515 data_line_odd[x] = ((temp_byte & 0x40) ? WHITE3 : BLACK3 );
embeddedartists 0:9297e33f50cf 516 data_line_odd[x] |= ((temp_byte & 0x10) ? WHITE2 : BLACK2 );
embeddedartists 0:9297e33f50cf 517 data_line_odd[x] |= ((temp_byte & 0x04) ? WHITE1 : BLACK1 );
embeddedartists 0:9297e33f50cf 518 data_line_odd[x] |= ((temp_byte & 0x01) ? WHITE0 : BLACK0 );
embeddedartists 0:9297e33f50cf 519
embeddedartists 0:9297e33f50cf 520 data_line_even[k] = ((temp_byte & 0x80) ? WHITE0 : BLACK0 );
embeddedartists 0:9297e33f50cf 521 data_line_even[k] |= ((temp_byte & 0x20) ? WHITE1 : BLACK1 );
embeddedartists 0:9297e33f50cf 522 data_line_even[k] |= ((temp_byte & 0x08) ? WHITE2 : BLACK2 );
embeddedartists 0:9297e33f50cf 523 data_line_even[k--] |= ((temp_byte & 0x02) ? WHITE3 : BLACK3 );
embeddedartists 0:9297e33f50cf 524 break;
embeddedartists 0:9297e33f50cf 525 }
embeddedartists 0:9297e33f50cf 526 }
embeddedartists 0:9297e33f50cf 527 }
embeddedartists 0:9297e33f50cf 528
embeddedartists 0:9297e33f50cf 529
embeddedartists 0:9297e33f50cf 530 /**
embeddedartists 0:9297e33f50cf 531 * \brief The base function to handle the driving stages for Frame and Block type
embeddedartists 0:9297e33f50cf 532 *
embeddedartists 0:9297e33f50cf 533 * \note
embeddedartists 0:9297e33f50cf 534 * - There are 3 stages to complete an image update on COG_V230_G2 type EPD.
embeddedartists 0:9297e33f50cf 535 * - For more details on the driving stages, please refer to the COG G2 document Section 5.4
embeddedartists 0:9297e33f50cf 536 *
embeddedartists 0:9297e33f50cf 537 * \param EPD_type_index The defined EPD size
embeddedartists 0:9297e33f50cf 538 * \param image_ptr The pointer of image array that stores image that will send to COG
embeddedartists 0:9297e33f50cf 539 * \param image_data_address The address of memory that stores image
embeddedartists 0:9297e33f50cf 540 * \param stage_no The assigned stage number that will proceed
embeddedartists 0:9297e33f50cf 541 * \param lineoffset Line data offset
embeddedartists 0:9297e33f50cf 542 */
embeddedartists 0:9297e33f50cf 543 void stage_handle_Base(uint8_t EPD_type_index,uint8_t *image_prt,long image_data_address,
embeddedartists 0:9297e33f50cf 544 uint8_t stage_no,uint8_t lineoffset)
embeddedartists 0:9297e33f50cf 545 {
embeddedartists 0:9297e33f50cf 546 struct EPD_V230_G2_Struct S_epd_v230;
embeddedartists 0:9297e33f50cf 547 int16_t cycle,m,i; //m=number of steps
embeddedartists 0:9297e33f50cf 548 //uint8_t isLastframe = 0; //If it is the last frame to send Nothing at the fist scan line
embeddedartists 0:9297e33f50cf 549 uint8_t isLastBlock=0; //If the beginning line of block is in active range of EPD
embeddedartists 0:9297e33f50cf 550 int16_t scanline_no=0;
embeddedartists 0:9297e33f50cf 551 uint8_t *action_block_prt;
embeddedartists 0:9297e33f50cf 552 long action_block_address;
embeddedartists 0:9297e33f50cf 553 uint8_t byte_array[LINE_BUFFER_DATA_SIZE];
embeddedartists 0:9297e33f50cf 554 /** Stage 2: BLACK/WHITE image, Frame type */
embeddedartists 0:9297e33f50cf 555 if(stage_no==Stage2)
embeddedartists 0:9297e33f50cf 556 {
embeddedartists 0:9297e33f50cf 557 for(i=0;i<action__Waveform_param->stage2_cycle;i++)
embeddedartists 0:9297e33f50cf 558 {
embeddedartists 0:9297e33f50cf 559 same_data_frame (EPD_type_index,ALL_BLACK,action__Waveform_param->stage2_t1);
embeddedartists 0:9297e33f50cf 560 same_data_frame (EPD_type_index,ALL_WHITE,action__Waveform_param->stage2_t2);
embeddedartists 0:9297e33f50cf 561 }
embeddedartists 0:9297e33f50cf 562 return;
embeddedartists 0:9297e33f50cf 563 }
embeddedartists 0:9297e33f50cf 564 /** Stage 1 & 3, Block type */
embeddedartists 0:9297e33f50cf 565 // The frame/block/step of Stage1 and Stage3 are default the same.
embeddedartists 0:9297e33f50cf 566 stage_init(EPD_type_index,
embeddedartists 0:9297e33f50cf 567 &S_epd_v230,
embeddedartists 0:9297e33f50cf 568 action__Waveform_param->stage1_block1,
embeddedartists 0:9297e33f50cf 569 action__Waveform_param->stage1_step1,
embeddedartists 0:9297e33f50cf 570 action__Waveform_param->stage1_frame1);
embeddedartists 0:9297e33f50cf 571
embeddedartists 0:9297e33f50cf 572 /* Repeat number of frames */
embeddedartists 0:9297e33f50cf 573 for (cycle = 0; cycle < (S_epd_v230.frame_cycle ); cycle++)
embeddedartists 0:9297e33f50cf 574 {
embeddedartists 0:9297e33f50cf 575
embeddedartists 0:9297e33f50cf 576 // if (cycle == (S_epd_v230.frame_cycle - 1)) isLastframe = 1;
embeddedartists 0:9297e33f50cf 577
embeddedartists 0:9297e33f50cf 578 isLastBlock = 0;
embeddedartists 0:9297e33f50cf 579 S_epd_v230.step_y0 = 0;
embeddedartists 0:9297e33f50cf 580 S_epd_v230.step_y1 = S_epd_v230.step_size ;
embeddedartists 0:9297e33f50cf 581 S_epd_v230.block_y0 = 0;
embeddedartists 0:9297e33f50cf 582 S_epd_v230.block_y1 = 0;
embeddedartists 0:9297e33f50cf 583 /* Move number of steps */
embeddedartists 0:9297e33f50cf 584 for (m = 0; m < S_epd_v230.number_of_steps; m++)
embeddedartists 0:9297e33f50cf 585 {
embeddedartists 0:9297e33f50cf 586 S_epd_v230.block_y1 += S_epd_v230.step_size;
embeddedartists 0:9297e33f50cf 587 S_epd_v230.block_y0 = S_epd_v230.block_y1 - S_epd_v230.block_size;
embeddedartists 0:9297e33f50cf 588 /* reset block_y0=frame_y0 if block is not in active range of EPD */
embeddedartists 0:9297e33f50cf 589 if (S_epd_v230.block_y0 < S_epd_v230.frame_y0) S_epd_v230.block_y0 = S_epd_v230.frame_y0;
embeddedartists 0:9297e33f50cf 590
embeddedartists 0:9297e33f50cf 591 /* if the beginning line of block is in active range of EPD */
embeddedartists 0:9297e33f50cf 592 if (S_epd_v230.block_y1 == S_epd_v230.block_size) isLastBlock = 1;
embeddedartists 0:9297e33f50cf 593
embeddedartists 0:9297e33f50cf 594 if(image_prt!=NULL)
embeddedartists 0:9297e33f50cf 595 {
embeddedartists 0:9297e33f50cf 596 action_block_prt=(image_prt+(int)(S_epd_v230.block_y0*lineoffset));
embeddedartists 0:9297e33f50cf 597 }
embeddedartists 0:9297e33f50cf 598 else if(_On_EPD_read_flash!=NULL) //Read line data in range of block, read first
embeddedartists 0:9297e33f50cf 599 {
embeddedartists 0:9297e33f50cf 600 action_block_address=image_data_address+(long)(S_epd_v230.block_y0*lineoffset);
embeddedartists 0:9297e33f50cf 601 _On_EPD_read_flash(action_block_address,(uint8_t *)&byte_array,
embeddedartists 0:9297e33f50cf 602 COG_parameters[EPD_type_index].horizontal_size);
embeddedartists 0:9297e33f50cf 603 action_block_prt=(uint8_t *)&byte_array;
embeddedartists 0:9297e33f50cf 604 }
embeddedartists 0:9297e33f50cf 605 /* Update line data */
embeddedartists 0:9297e33f50cf 606 for (i = S_epd_v230.block_y0; i < S_epd_v230.block_y1; i++)
embeddedartists 0:9297e33f50cf 607 {
embeddedartists 0:9297e33f50cf 608
embeddedartists 0:9297e33f50cf 609 if (i >= COG_parameters[EPD_type_index].vertical_size) break;
embeddedartists 0:9297e33f50cf 610 //if (isLastframe &&
embeddedartists 0:9297e33f50cf 611 if (
embeddedartists 0:9297e33f50cf 612 isLastBlock &&(i < (S_epd_v230.step_size + S_epd_v230.block_y0)))
embeddedartists 0:9297e33f50cf 613 {
embeddedartists 0:9297e33f50cf 614 nothing_line(EPD_type_index);
embeddedartists 0:9297e33f50cf 615 }
embeddedartists 0:9297e33f50cf 616 else
embeddedartists 0:9297e33f50cf 617 {
embeddedartists 0:9297e33f50cf 618 read_line_data_handle(EPD_type_index,action_block_prt,stage_no);
embeddedartists 0:9297e33f50cf 619 }
embeddedartists 0:9297e33f50cf 620
embeddedartists 0:9297e33f50cf 621 if(_On_EPD_read_flash!=NULL) //Read line data in range of block
embeddedartists 0:9297e33f50cf 622 {
embeddedartists 0:9297e33f50cf 623 action_block_address +=lineoffset;
embeddedartists 0:9297e33f50cf 624 _On_EPD_read_flash(action_block_address,(uint8_t *)&byte_array,
embeddedartists 0:9297e33f50cf 625 COG_parameters[EPD_type_index].horizontal_size);
embeddedartists 0:9297e33f50cf 626 action_block_prt=(uint8_t *)&byte_array;
embeddedartists 0:9297e33f50cf 627 }
embeddedartists 0:9297e33f50cf 628 else action_block_prt+=lineoffset;
embeddedartists 0:9297e33f50cf 629
embeddedartists 0:9297e33f50cf 630 scanline_no= (COG_parameters[EPD_type_index].vertical_size-1)-i;
embeddedartists 0:9297e33f50cf 631
embeddedartists 0:9297e33f50cf 632 /* Scan byte shift per data line */
embeddedartists 0:9297e33f50cf 633 data_line_scan[(scanline_no>>2)] = SCAN_TABLE[(scanline_no%4)];
embeddedartists 0:9297e33f50cf 634
embeddedartists 0:9297e33f50cf 635 /* the border uses the internal signal control byte. */
embeddedartists 0:9297e33f50cf 636 *data_line_border_byte=0x00;
embeddedartists 0:9297e33f50cf 637
embeddedartists 0:9297e33f50cf 638 /* Sending data */
embeddedartists 0:9297e33f50cf 639 epd_spi_send (0x0A, (uint8_t *)&COG_Line.uint8,
embeddedartists 0:9297e33f50cf 640 COG_parameters[EPD_type_index].data_line_size);
embeddedartists 0:9297e33f50cf 641
embeddedartists 0:9297e33f50cf 642
embeddedartists 0:9297e33f50cf 643 /* Turn on Output Enable */
embeddedartists 0:9297e33f50cf 644 epd_spi_send_byte (0x02, 0x07);
embeddedartists 0:9297e33f50cf 645
embeddedartists 0:9297e33f50cf 646 data_line_scan[(scanline_no>>2)]=0;
embeddedartists 0:9297e33f50cf 647
embeddedartists 0:9297e33f50cf 648 }
embeddedartists 0:9297e33f50cf 649 }
embeddedartists 0:9297e33f50cf 650
embeddedartists 0:9297e33f50cf 651 }
embeddedartists 0:9297e33f50cf 652 }
embeddedartists 0:9297e33f50cf 653
embeddedartists 0:9297e33f50cf 654 /**
embeddedartists 0:9297e33f50cf 655 * \brief The driving stages from image array (image_data.h) to COG
embeddedartists 0:9297e33f50cf 656 *
embeddedartists 0:9297e33f50cf 657 * \param EPD_type_index The defined EPD size
embeddedartists 0:9297e33f50cf 658 * \param image_ptr The pointer of image array that stores image that will send to COG
embeddedartists 0:9297e33f50cf 659 * \param stage_no The assigned stage number that will proceed
embeddedartists 0:9297e33f50cf 660 * \param lineoffset Line data offset
embeddedartists 0:9297e33f50cf 661 */
embeddedartists 0:9297e33f50cf 662 void stage_handle(uint8_t EPD_type_index,uint8_t *image_prt,uint8_t stage_no,uint8_t lineoffset)
embeddedartists 0:9297e33f50cf 663 {
embeddedartists 0:9297e33f50cf 664 stage_handle_Base(EPD_type_index,image_prt,ADDRESS_NULL,stage_no,lineoffset);
embeddedartists 0:9297e33f50cf 665 }
embeddedartists 0:9297e33f50cf 666
embeddedartists 0:9297e33f50cf 667 /**
embeddedartists 0:9297e33f50cf 668 * \brief The driving stages from memory to COG
embeddedartists 0:9297e33f50cf 669 *
embeddedartists 0:9297e33f50cf 670 * \note
embeddedartists 0:9297e33f50cf 671 * - This function is additional added here for developer if the image data
embeddedartists 0:9297e33f50cf 672 * is stored in Flash memory.
embeddedartists 0:9297e33f50cf 673 *
embeddedartists 0:9297e33f50cf 674 * \param EPD_type_index The defined EPD size
embeddedartists 0:9297e33f50cf 675 * \param image_data_address The address of flash memory that stores image
embeddedartists 0:9297e33f50cf 676 * \param stage_no The assigned stage number that will proceed
embeddedartists 0:9297e33f50cf 677 * \param lineoffset Line data offset
embeddedartists 0:9297e33f50cf 678 */
embeddedartists 0:9297e33f50cf 679 static void stage_handle_ex(uint8_t EPD_type_index,long image_data_address,uint8_t stage_no,uint8_t lineoffset) {
embeddedartists 0:9297e33f50cf 680 stage_handle_Base(EPD_type_index,NULL,image_data_address,stage_no,lineoffset);
embeddedartists 0:9297e33f50cf 681 }
embeddedartists 0:9297e33f50cf 682
embeddedartists 0:9297e33f50cf 683 /**
embeddedartists 0:9297e33f50cf 684 * \brief Write image data from memory array (image_data.h) to the EPD
embeddedartists 0:9297e33f50cf 685 *
embeddedartists 0:9297e33f50cf 686 * \param EPD_type_index The defined EPD size
embeddedartists 0:9297e33f50cf 687 * \param previous_image_ptr The pointer of memory that stores previous image
embeddedartists 0:9297e33f50cf 688 * \param new_image_ptr The pointer of memory that stores new image
embeddedartists 0:9297e33f50cf 689 */
embeddedartists 0:9297e33f50cf 690 void EPD_display_from_array_prt (uint8_t EPD_type_index, uint8_t *previous_image_ptr,
embeddedartists 0:9297e33f50cf 691 uint8_t *new_image_ptr) {
embeddedartists 0:9297e33f50cf 692 _On_EPD_read_flash=0;
embeddedartists 0:9297e33f50cf 693 stage_handle(EPD_type_index,new_image_ptr,Stage1,COG_parameters[EPD_type_index].horizontal_size);
embeddedartists 0:9297e33f50cf 694 stage_handle(EPD_type_index,new_image_ptr,Stage2,COG_parameters[EPD_type_index].horizontal_size);
embeddedartists 0:9297e33f50cf 695 stage_handle(EPD_type_index,new_image_ptr,Stage3,COG_parameters[EPD_type_index].horizontal_size);
embeddedartists 0:9297e33f50cf 696 }
embeddedartists 0:9297e33f50cf 697
embeddedartists 0:9297e33f50cf 698 /**
embeddedartists 0:9297e33f50cf 699 * \brief Write image data from Flash memory to the EPD
embeddedartists 0:9297e33f50cf 700 * \note This function is additional added here for developer if the image data
embeddedartists 0:9297e33f50cf 701 * is stored in Flash.
embeddedartists 0:9297e33f50cf 702 *
embeddedartists 0:9297e33f50cf 703 * \param EPD_type_index The defined EPD size
embeddedartists 0:9297e33f50cf 704 * \param previous_image_flash_address The start address of memory that stores previous image
embeddedartists 0:9297e33f50cf 705 * \param new_image_flash_address The start address of memory that stores new image
embeddedartists 0:9297e33f50cf 706 * \param On_EPD_read_flash Developer needs to create an external function to read flash
embeddedartists 0:9297e33f50cf 707 */
embeddedartists 0:9297e33f50cf 708 void EPD_display_from_flash_prt (uint8_t EPD_type_index, long previous_image_flash_address,
embeddedartists 0:9297e33f50cf 709 long new_image_flash_address,EPD_read_flash_handler On_EPD_read_flash) {
embeddedartists 0:9297e33f50cf 710
embeddedartists 0:9297e33f50cf 711 uint8_t line_len;
embeddedartists 0:9297e33f50cf 712 line_len=LINE_SIZE;
embeddedartists 0:9297e33f50cf 713 if(line_len==0) line_len=COG_parameters[EPD_type_index].horizontal_size;
embeddedartists 0:9297e33f50cf 714
embeddedartists 0:9297e33f50cf 715 _On_EPD_read_flash=On_EPD_read_flash;
embeddedartists 0:9297e33f50cf 716 stage_handle_ex(EPD_type_index,new_image_flash_address,Stage1,line_len);
embeddedartists 0:9297e33f50cf 717 stage_handle_ex(EPD_type_index,new_image_flash_address,Stage2,line_len);
embeddedartists 0:9297e33f50cf 718 stage_handle_ex(EPD_type_index,new_image_flash_address,Stage3,line_len);
embeddedartists 0:9297e33f50cf 719 }
embeddedartists 0:9297e33f50cf 720
embeddedartists 0:9297e33f50cf 721
embeddedartists 0:9297e33f50cf 722 /**
embeddedartists 0:9297e33f50cf 723 * \brief Write Dummy Line to COG
embeddedartists 0:9297e33f50cf 724 * \note A line whose all Scan Bytes are 0x00
embeddedartists 0:9297e33f50cf 725 *
embeddedartists 0:9297e33f50cf 726 * \param EPD_type_index The defined EPD size
embeddedartists 0:9297e33f50cf 727 */
embeddedartists 0:9297e33f50cf 728 static inline void dummy_line(uint8_t EPD_type_index) {
embeddedartists 0:9297e33f50cf 729 uint8_t i;
embeddedartists 0:9297e33f50cf 730 for (i = 0; i < (COG_parameters[EPD_type_index].vertical_size/8); i++) {
embeddedartists 0:9297e33f50cf 731 switch(EPD_type_index) {
embeddedartists 0:9297e33f50cf 732 case EPD_144:
embeddedartists 0:9297e33f50cf 733 COG_Line.line_data_by_size.line_data_for_144.scan[i]=0x00;
embeddedartists 0:9297e33f50cf 734 break;
embeddedartists 0:9297e33f50cf 735 case EPD_200:
embeddedartists 0:9297e33f50cf 736 COG_Line.line_data_by_size.line_data_for_200.scan[i]=0x00;
embeddedartists 0:9297e33f50cf 737 break;
embeddedartists 0:9297e33f50cf 738 case EPD_270:
embeddedartists 0:9297e33f50cf 739 COG_Line.line_data_by_size.line_data_for_270.scan[i]=0x00;
embeddedartists 0:9297e33f50cf 740 break;
embeddedartists 0:9297e33f50cf 741 }
embeddedartists 0:9297e33f50cf 742 }
embeddedartists 0:9297e33f50cf 743 /* Set charge pump voltage level reduce voltage shift */
embeddedartists 0:9297e33f50cf 744 epd_spi_send_byte (0x04, COG_parameters[EPD_type_index].voltage_level);
embeddedartists 0:9297e33f50cf 745
embeddedartists 0:9297e33f50cf 746 /* Sending data */
embeddedartists 0:9297e33f50cf 747 epd_spi_send (0x0A, (uint8_t *)&COG_Line.uint8, COG_parameters[EPD_type_index].data_line_size);
embeddedartists 0:9297e33f50cf 748
embeddedartists 0:9297e33f50cf 749 /* Turn on Output Enable */
embeddedartists 0:9297e33f50cf 750 epd_spi_send_byte (0x02, 0x07);
embeddedartists 0:9297e33f50cf 751 }
embeddedartists 0:9297e33f50cf 752
embeddedartists 0:9297e33f50cf 753
embeddedartists 0:9297e33f50cf 754 /**
embeddedartists 0:9297e33f50cf 755 * \brief Write Border(Input) Dummy Line
embeddedartists 0:9297e33f50cf 756 * \note Set Border byte 0xFF to write Black and set 0xAA to write White
embeddedartists 0:9297e33f50cf 757 *
embeddedartists 0:9297e33f50cf 758 * \param EPD_type_index The defined EPD size
embeddedartists 0:9297e33f50cf 759 */
embeddedartists 0:9297e33f50cf 760 static void border_dummy_line(uint8_t EPD_type_index)
embeddedartists 0:9297e33f50cf 761 {
embeddedartists 0:9297e33f50cf 762 uint16_t i;
embeddedartists 0:9297e33f50cf 763 for (i = 0; i < COG_parameters[EPD_type_index].data_line_size; i++)
embeddedartists 0:9297e33f50cf 764 {
embeddedartists 0:9297e33f50cf 765 COG_Line.uint8[i] = 0x00;
embeddedartists 0:9297e33f50cf 766 }
embeddedartists 0:9297e33f50cf 767
embeddedartists 0:9297e33f50cf 768 *data_line_border_byte=BORDER_BYTE_B;
embeddedartists 0:9297e33f50cf 769 //Write a Border(B) Dummy Line
embeddedartists 0:9297e33f50cf 770 epd_spi_send (0x0a, (uint8_t *)&COG_Line.uint8, COG_parameters[EPD_type_index].data_line_size);
embeddedartists 0:9297e33f50cf 771 //Turn on OE
embeddedartists 0:9297e33f50cf 772 epd_spi_send_byte (0x02, 0x07);
embeddedartists 0:9297e33f50cf 773
embeddedartists 0:9297e33f50cf 774 sys_delay_ms(40);
embeddedartists 0:9297e33f50cf 775
embeddedartists 0:9297e33f50cf 776 *data_line_border_byte=BORDER_BYTE_W;
embeddedartists 0:9297e33f50cf 777 //Write a Borde(B) Dummy Line
embeddedartists 0:9297e33f50cf 778 epd_spi_send (0x0a, (uint8_t *)&COG_Line.uint8, COG_parameters[EPD_type_index].data_line_size);
embeddedartists 0:9297e33f50cf 779 //Turn on OE
embeddedartists 0:9297e33f50cf 780 epd_spi_send_byte (0x02, 0x07);
embeddedartists 0:9297e33f50cf 781
embeddedartists 0:9297e33f50cf 782 sys_delay_ms(200);
embeddedartists 0:9297e33f50cf 783
embeddedartists 0:9297e33f50cf 784
embeddedartists 0:9297e33f50cf 785 }
embeddedartists 0:9297e33f50cf 786
embeddedartists 0:9297e33f50cf 787
embeddedartists 0:9297e33f50cf 788 /**
embeddedartists 0:9297e33f50cf 789 * \brief Power Off COG Driver
embeddedartists 0:9297e33f50cf 790 * \note For detailed flow and description, please refer to the COG G2 document Section 6.
embeddedartists 0:9297e33f50cf 791 *
embeddedartists 0:9297e33f50cf 792 * \param EPD_type_index The defined EPD size
embeddedartists 0:9297e33f50cf 793 */
embeddedartists 0:9297e33f50cf 794 uint8_t EPD_power_off(uint8_t EPD_type_index) {
embeddedartists 0:9297e33f50cf 795 uint8_t y;
embeddedartists 0:9297e33f50cf 796
embeddedartists 0:9297e33f50cf 797 if(EPD_type_index==EPD_144 || EPD_type_index==EPD_200) {
embeddedartists 0:9297e33f50cf 798 border_dummy_line(EPD_type_index);
embeddedartists 0:9297e33f50cf 799 dummy_line(EPD_type_index);
embeddedartists 0:9297e33f50cf 800 }
embeddedartists 0:9297e33f50cf 801
embeddedartists 0:9297e33f50cf 802 delay_ms (25);
embeddedartists 0:9297e33f50cf 803 if(EPD_type_index==EPD_270) {
embeddedartists 0:9297e33f50cf 804 EPD_border_low();
embeddedartists 0:9297e33f50cf 805 delay_ms (200);
embeddedartists 0:9297e33f50cf 806 EPD_border_high();
embeddedartists 0:9297e33f50cf 807 }
embeddedartists 0:9297e33f50cf 808
embeddedartists 0:9297e33f50cf 809 //Check DC/DC
embeddedartists 0:9297e33f50cf 810 if((SPI_R(0x0F,0x00) & 0x40) == 0x00) return ERROR_DC;
embeddedartists 0:9297e33f50cf 811
embeddedartists 0:9297e33f50cf 812 //Turn on Latch Reset
embeddedartists 0:9297e33f50cf 813 epd_spi_send_byte (0x03, 0x01);
embeddedartists 0:9297e33f50cf 814 //Turn off OE
embeddedartists 0:9297e33f50cf 815 epd_spi_send_byte (0x02, 0x05);
embeddedartists 0:9297e33f50cf 816 //Power off charge pump Vcom
embeddedartists 0:9297e33f50cf 817 epd_spi_send_byte (0x05, 0x0E);
embeddedartists 0:9297e33f50cf 818 //Power off charge pump neg voltage
embeddedartists 0:9297e33f50cf 819 epd_spi_send_byte (0x05, 0x02);
embeddedartists 0:9297e33f50cf 820 //Turn off all charge pump
embeddedartists 0:9297e33f50cf 821 epd_spi_send_byte (0x05, 0x00);
embeddedartists 0:9297e33f50cf 822 //Turn off OSC
embeddedartists 0:9297e33f50cf 823 epd_spi_send_byte (0x07, 0x0D);
embeddedartists 0:9297e33f50cf 824
embeddedartists 0:9297e33f50cf 825 epd_spi_send_byte (0x04, 0x83);
embeddedartists 0:9297e33f50cf 826 delay_ms(120);
embeddedartists 0:9297e33f50cf 827 epd_spi_send_byte (0x04, 0x00);
embeddedartists 0:9297e33f50cf 828
embeddedartists 0:9297e33f50cf 829 epd_spi_detach ();
embeddedartists 0:9297e33f50cf 830 EPD_cs_low();
embeddedartists 0:9297e33f50cf 831 EPD_rst_low();
embeddedartists 0:9297e33f50cf 832 EPD_Vcc_turn_off ();
embeddedartists 0:9297e33f50cf 833 EPD_border_low();
embeddedartists 0:9297e33f50cf 834 delay_ms (10);
embeddedartists 0:9297e33f50cf 835
embeddedartists 0:9297e33f50cf 836 for(y=0;y<10;y++)
embeddedartists 0:9297e33f50cf 837 {
embeddedartists 0:9297e33f50cf 838 EPD_discharge_high ();
embeddedartists 0:9297e33f50cf 839 delay_ms (10);
embeddedartists 0:9297e33f50cf 840 EPD_discharge_low ();
embeddedartists 0:9297e33f50cf 841 delay_ms (10);
embeddedartists 0:9297e33f50cf 842 }
embeddedartists 0:9297e33f50cf 843 return RES_OK;
embeddedartists 0:9297e33f50cf 844 }
embeddedartists 0:9297e33f50cf 845
embeddedartists 0:9297e33f50cf 846 #endif
embeddedartists 0:9297e33f50cf 847
embeddedartists 0:9297e33f50cf 848
embeddedartists 0:9297e33f50cf 849