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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EPD_COG_process_v230_G2.cpp Source File

EPD_COG_process_v230_G2.cpp

Go to the documentation of this file.
00001 /**
00002 * \file
00003 *
00004 * \brief The waveform driving processes and updating stages of G2 COG with V230 EPD
00005 *
00006 * Copyright (c) 2012-2014 Pervasive Displays Inc. All rights reserved.
00007 *
00008 * \asf_license_start
00009 *
00010 * \page License
00011 *
00012 * Redistribution and use in source and binary forms, with or without
00013 * modification, are permitted provided that the following conditions are met:
00014 *
00015 * 1. Redistributions of source code must retain the above copyright notice,
00016 *    this list of conditions and the following disclaimer.
00017 *
00018 * 2. Redistributions in binary form must reproduce the above copyright notice,
00019 *    this list of conditions and the following disclaimer in the documentation
00020 *    and/or other materials provided with the distribution.
00021 *
00022 * 3. The name of Atmel may not be used to endorse or promote products derived
00023 *    from this software without specific prior written permission.
00024 *
00025 * 4. This software may only be redistributed and used in connection with an
00026 *    Atmel microcontroller product.
00027 *
00028 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
00029 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00030 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00031 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
00032 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00033 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00034 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00035 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00036 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00037 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00038 * POSSIBILITY OF SUCH DAMAGE.
00039 *
00040 * \asf_license_stop
00041 **/
00042 
00043 #include "EPD_COG_process.h"
00044 #ifdef COG_V230_G2
00045 
00046 #define ADDRESS_NULL        0xffffffff
00047 //EPD Panel parameters
00048 const struct COG_parameters_t COG_parameters[COUNT_OF_EPD_TYPE]  = {
00049     {
00050         // FOR 1.44"
00051         {0x00,0x00,0x00,0x00,0x00,0x0F,0xFF,0x00},
00052         0x03,
00053         (128/8),
00054         96,
00055         ((((128+96)*2)/8)+1),
00056         0,
00057         480
00058     },
00059     {
00060         // For 2.0"
00061         {0x00,0x00,0x00,0x00,0x01,0xFF,0xE0,0x00},
00062         0x03,
00063         (200/8),
00064         96,
00065         ((((200+96)*2)/8)+1),
00066         0,
00067         480
00068     },
00069     {
00070         // For 2.7"
00071         {0x00,0x00,0x00,0x7F,0xFF,0xFE,0x00,0x00},
00072         0x00,
00073         (264/8),
00074         176,
00075         ((((264+176)*2)/8)+1),
00076         0,
00077         630
00078     }
00079 };
00080 
00081 /* \brief EPD Waveform parameters
00082  * \note the parameters of waveform table below is different from the G2 COG document due to
00083  *       use block size is easier to achieve than accurate block time for different MCU.
00084  *       The approach is also working.
00085  * */
00086  const struct EPD_WaveformTable_Struct E_Waveform[COUNT_OF_EPD_TYPE][3]  = {
00087         {// FOR 1.44"
00088             {//50 �� T �� 40
00089                 4,              //stage1_frame1
00090                 16,             //stage1_block1
00091                 2,              //stage1_step1              
00092                 155,            //stage2_t1
00093                 155,            //stage2_t2
00094                 4,              //stage2_cycle
00095                 4,              //stage3_frame3
00096                 16,             //stage3_block3
00097                 2               //stage3_step3
00098             }
00099             ,{//40 �� T �� 10
00100                 4,              //stage1_frame1
00101                 16,             //stage1_block1
00102                 2,              //stage1_step1              
00103                 155,            //stage2_t1
00104                 155,            //stage2_t2
00105                 4,              //stage2_cycle
00106                 4,              //stage3_frame3
00107                 16,             //stage3_block3
00108                 2               //stage3_step3
00109             },
00110             {//10 �� T �� 0
00111                 2,              //stage1_frame1
00112                 42,             //stage1_block1
00113                 6,              //stage1_step1
00114                 392,            //stage2_t1
00115                 392,            //stage2_t2
00116                 4,              //stage2_cycle
00117                 2,              //stage3_frame3
00118                 42,             //stage3_block3
00119                 6               //stage3_step3
00120             }
00121             
00122         },
00123         {// For 2.0"
00124             {//50 �� T �� 40
00125                 4,              //stage1_frame1
00126                 36,             //stage1_block1
00127                 2,              //stage1_step1              
00128                 196,            //stage2_t1
00129                 196,            //stage2_t2
00130                 4,              //stage2_cycle
00131                 4,              //stage3_frame3
00132                 36,             //stage3_block3
00133                 2               //stage3_step3
00134             },
00135             {//40 �� T �� 10
00136                 2,              //stage1_frame1
00137                 36,             //stage1_block1
00138                 2,              //stage1_step1
00139                 196,            //stage2_t1
00140                 196,            //stage2_t2
00141                 4,              //stage2_cycle
00142                 2,              //stage3_frame3
00143                 36,             //stage3_block3
00144                 2               //stage3_step3
00145             },
00146             {//10 �� T �� 0
00147                 2,              //stage1_frame1
00148                 36,             //stage1_block1
00149                 2,              //stage1_step1
00150                 392,            //stage2_t1
00151                 392,            //stage2_t2
00152                 4,              //stage2_cycle
00153                 2,              //stage3_frame3
00154                 36,             //stage3_block3
00155                 2               //stage3_step3
00156             }
00157         },
00158         {// For 2.7"
00159             {//50 �� T �� 40
00160                 4,              //stage1_frame1
00161                 28,             //stage1_block1
00162                 4,              //stage1_step1
00163                 196,            //stage2_t1
00164                 196,            //stage2_t2
00165                 4,              //stage2_cycle
00166                 4,              //stage3_frame3
00167                 28,             //stage3_block3
00168                 4               //stage3_step3
00169             },
00170             {//40 �� T �� 10
00171                 2,              //stage1_frame1
00172                 28,             //stage1_block1
00173                 2,              //stage1_step1
00174                 196,            //stage2_t1
00175                 196,            //stage2_t2
00176                 4,              //stage2_cycle
00177                 2,              //stage3_frame3
00178                 28,             //stage3_block3
00179                 2               //stage3_step3
00180             },
00181             {//10 �� T �� 0
00182                 2,              //stage1_frame1
00183                 28,             //stage1_block1
00184                 4,              //stage1_step1
00185                 392,            //stage2_t1
00186                 392,            //stage2_t2
00187                 4,              //stage2_cycle
00188                 2,              //stage3_frame3
00189                 28,             //stage3_block3
00190                 4               //stage3_step3
00191             }
00192         },
00193      
00194  };
00195 
00196 const uint8_t   SCAN_TABLE[4] = {0xC0,0x30,0x0C,0x03};
00197     
00198 static struct EPD_WaveformTable_Struct *action__Waveform_param;
00199 static COG_line_data_packet_type COG_Line;
00200 static EPD_read_flash_handler _On_EPD_read_flash;
00201 static uint8_t  *data_line_even;
00202 static uint8_t  *data_line_odd;
00203 static uint8_t  *data_line_scan;
00204 static uint8_t  *data_line_border_byte;
00205 
00206 /**
00207 * \brief According to EPD size and temperature to get stage_time
00208 * \note Refer to COG document Section 5.3 for more details
00209 *
00210 * \param EPD_type_index The defined EPD size
00211 */
00212 static void set_temperature_factor(uint8_t EPD_type_index) {
00213     int8_t temperature;
00214     temperature = get_temperature();    
00215         if (50 >= temperature  && temperature > 40){
00216             action__Waveform_param=(struct EPD_WaveformTable_Struct *)&E_Waveform[EPD_type_index][0];
00217         }else if (40 >= temperature  && temperature > 10){
00218             action__Waveform_param=(struct EPD_WaveformTable_Struct *)&E_Waveform[EPD_type_index][1];
00219         }else if (10 >= temperature  && temperature > 0){
00220             action__Waveform_param=(struct EPD_WaveformTable_Struct *)&E_Waveform[EPD_type_index][2];
00221         }else action__Waveform_param=(struct EPD_WaveformTable_Struct *)&E_Waveform[EPD_type_index][1]; //Default
00222 }
00223 
00224 /**
00225 * \brief Initialize the EPD hardware setting
00226 */
00227 void EPD_init(void) {
00228     EPD_display_hardware_init();
00229     EPD_cs_low();
00230     EPD_rst_low();
00231     EPD_discharge_low();
00232     EPD_border_low();
00233 }
00234 
00235 /**
00236 * \brief Select the EPD size to get line data array for driving COG
00237 *
00238 * \param EPD_type_index The defined EPD size
00239 */
00240 void COG_driver_EPDtype_select(uint8_t EPD_type_index) {
00241     switch(EPD_type_index) {
00242         case EPD_144:
00243         data_line_even = &COG_Line.line_data_by_size.line_data_for_144.even[0];
00244         data_line_odd  = &COG_Line.line_data_by_size.line_data_for_144.odd[0];
00245         data_line_scan = &COG_Line.line_data_by_size.line_data_for_144.scan[0];
00246         data_line_border_byte = &COG_Line.line_data_by_size.line_data_for_144.border_byte;
00247         break;
00248         case EPD_200:
00249         data_line_even = &COG_Line.line_data_by_size.line_data_for_200.even[0];
00250         data_line_odd  = &COG_Line.line_data_by_size.line_data_for_200.odd[0];
00251         data_line_scan = &COG_Line.line_data_by_size.line_data_for_200.scan[0];
00252         data_line_border_byte = &COG_Line.line_data_by_size.line_data_for_200.border_byte;
00253         break;
00254         case EPD_270:
00255         data_line_even = &COG_Line.line_data_by_size.line_data_for_270.even[0];
00256         data_line_odd  = &COG_Line.line_data_by_size.line_data_for_270.odd[0];
00257         data_line_scan = &COG_Line.line_data_by_size.line_data_for_270.scan[0];
00258         data_line_border_byte = &COG_Line.line_data_by_size.line_data_for_270.border_byte;
00259         break;
00260     }
00261 }
00262 
00263 /**
00264 * \brief Power on COG Driver
00265 * \note For detailed flow and description, please refer to the COG G2 document Section 3.
00266 */
00267 void EPD_power_on (void) {  
00268     /* Initial state */
00269     EPD_Vcc_turn_on(); //Vcc and Vdd >= 2.7V    
00270     EPD_cs_high();
00271     EPD_border_high();
00272     EPD_rst_high();
00273     delay_ms(5);    
00274     EPD_rst_low();
00275     delay_ms(5);
00276     EPD_rst_high();
00277     delay_ms(5);
00278 }
00279 
00280 
00281 /**
00282 * \brief Initialize COG Driver
00283 * \note For detailed flow and description, please refer to the COG G2 document Section 4.
00284 *
00285 * \param EPD_type_index The defined EPD size
00286 */
00287 uint8_t EPD_initialize_driver (uint8_t EPD_type_index) {
00288     
00289     uint16_t i;
00290     // Empty the Line buffer
00291     for (i = 0; i <= LINE_BUFFER_DATA_SIZE; i ++) {
00292         COG_Line.uint8[i] = 0x00;
00293     }
00294     // Determine the EPD size for driving COG
00295     COG_driver_EPDtype_select(EPD_type_index);
00296 
00297     // Sense temperature to determine Temperature Factor
00298     set_temperature_factor(EPD_type_index);
00299     i = 0;
00300     
00301     while (EPD_IsBusy()) {
00302         if((i++) >= 0x0FFF) return ERROR_BUSY;
00303     }
00304     
00305     //Check COG ID
00306     if((SPI_R(0x72,0x00) & 0x0f) !=0x02) return ERROR_COG_ID;
00307 
00308     //Disable OE
00309     epd_spi_send_byte(0x02,0x40);   
00310 
00311     //Check Breakage
00312     if((SPI_R(0x0F,0x00) & 0x80) != 0x80) return ERROR_BREAKAGE;
00313     
00314     //Power Saving Mode
00315     epd_spi_send_byte(0x0B, 0x02);
00316 
00317     //Channel Select
00318     epd_spi_send (0x01, (uint8_t *)&COG_parameters[EPD_type_index].channel_select, 8);
00319 
00320     //High Power Mode Osc Setting
00321     epd_spi_send_byte(0x07,0xD1);
00322 
00323     //Power Setting
00324     epd_spi_send_byte(0x08,0x02);
00325 
00326     //Set Vcom level
00327     epd_spi_send_byte(0x09,0xC2);
00328 
00329     //Power Setting
00330     epd_spi_send_byte(0x04,0x03);
00331 
00332     //Driver latch on
00333     epd_spi_send_byte(0x03,0x01);
00334 
00335     //Driver latch off
00336     epd_spi_send_byte(0x03,0x00);
00337 
00338     delay_ms(5);
00339 
00340     //Chargepump Start
00341     i=0;
00342     do {
00343         //Start chargepump positive V
00344         //VGH & VDH on
00345         epd_spi_send_byte(0x05,0x01);
00346 
00347         delay_ms(240);
00348 
00349         //Start chargepump neg voltage
00350         //VGL & VDL on
00351         epd_spi_send_byte(0x05,0x03);
00352 
00353         delay_ms(40);
00354 
00355         //Set chargepump
00356         //Vcom_Driver to ON
00357         //Vcom_Driver on
00358         epd_spi_send_byte(0x05,0x0F);
00359 
00360         delay_ms(40);
00361 
00362         //Check DC/DC
00363         if((SPI_R(0x0F,0x00) & 0x40) != 0x00) break;    
00364         
00365     }while((i++) != 4);
00366     
00367     if(i>=4) 
00368     {
00369         //Output enable to disable
00370         epd_spi_send_byte(0x02,0x40);
00371         return ERROR_CHARGEPUMP;
00372     }
00373     else  return RES_OK;
00374 }
00375 
00376 /**
00377 * \brief Initialize the parameters of Block type stage 
00378 *
00379 * \param EPD_type_index The defined EPD size
00380 * \param EPD_V230_G2_Struct The Block type waveform structure
00381 * \param block_size The width of Block size
00382 * \param step_size The width of Step size
00383 * \param frame_cycle The width of Step size
00384 */
00385 void stage_init(uint8_t EPD_type_index,struct EPD_V230_G2_Struct *S_epd_v230,
00386                 uint8_t block_size,uint8_t step_size,
00387                 uint8_t frame_cycle)
00388 {
00389     S_epd_v230->frame_y0 = 0;
00390     S_epd_v230->frame_y1 = 176;
00391     S_epd_v230->block_y0 = 0;
00392     S_epd_v230->block_y1 = 0;
00393     S_epd_v230->step_y0 = 0;
00394     S_epd_v230->step_y1 = 0;
00395     S_epd_v230->block_size = action__Waveform_param->stage1_block1;
00396     S_epd_v230->step_size =action__Waveform_param->stage1_step1;
00397     S_epd_v230->frame_cycle = action__Waveform_param->stage1_frame1;
00398     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;
00399     
00400 }
00401 
00402 /**
00403 * \brief For Frame type waveform to update all black/white pattern
00404 *
00405 * \param EPD_type_index The defined EPD size
00406 * \param bwdata Black or White color to whole screen
00407 * \param work_time The working time
00408 */
00409 static inline void same_data_frame (uint8_t EPD_type_index, uint8_t bwdata, uint32_t work_time) {
00410     uint16_t i;
00411     for (i = 0; i <  COG_parameters[EPD_type_index].horizontal_size; i++) {
00412         data_line_even[i]=bwdata;
00413         data_line_odd[i]=bwdata;
00414     }
00415     start_EPD_timer();
00416     do 
00417     {   
00418         for (i = 0; i < COG_parameters[EPD_type_index].vertical_size; i++) {
00419             
00420             /* Scan byte shift per data line */
00421             data_line_scan[(i>>2)]=SCAN_TABLE[(i%4)];
00422             
00423             /* Sending data */
00424             epd_spi_send (0x0A, (uint8_t *)&COG_Line.uint8, COG_parameters[EPD_type_index].data_line_size);
00425          
00426             /* Turn on Output Enable */
00427             epd_spi_send_byte (0x02, 0x07);
00428         
00429             data_line_scan[(i>>2)]=0;
00430             
00431         }
00432     } while (get_current_time_tick()<(work_time));
00433         /* Stop system timer */
00434         stop_EPD_timer();
00435 }
00436 
00437 /**
00438 * \brief Write nothing Line to COG
00439 * \note A line whose all Scan Bytes are 0x00
00440 *
00441 * \param EPD_type_index The defined EPD size
00442 */
00443 void nothing_line(uint8_t EPD_type_index) {
00444     uint16_t i;
00445     for (i = 0; i <  COG_parameters[EPD_type_index].horizontal_size; i++) {
00446         data_line_even[i]   =   NOTHING;
00447         data_line_odd[i]    =   NOTHING;
00448     }
00449 }
00450 
00451 
00452 /**
00453 * \brief Get line data of Stage 1 and 3
00454 *
00455 * \note
00456 * - One dot/pixel is comprised of 2 bits which are White(10), Black(11) or Nothing(01).
00457 *   The image data bytes must be divided into Odd and Even bytes.
00458 * - The COG driver uses a buffer to write one line of data (FIFO) - interlaced
00459 *   It's different order from COG_G1
00460 *   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)}
00461 *   Scan byte {S(96), S(95)...}
00462 *   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)}
00463 * - For more details on the driving stages, please refer to the COG G2 document Section 5.
00464 *
00465 * \param EPD_type_index The defined EPD size
00466 * \param image_ptr The pointer of memory that stores image that will send to COG
00467 * \param stage_no The assigned stage number that will proceed
00468 */
00469 
00470 void read_line_data_handle(uint8_t EPD_type_index,uint8_t *image_prt,uint8_t stage_no)
00471 {
00472     int16_t x,k;
00473     uint8_t temp_byte; // Temporary storage for image data check
00474     k=COG_parameters[EPD_type_index].horizontal_size-1; 
00475     for (x =0 ; x < COG_parameters[EPD_type_index].horizontal_size ; x++) {
00476                 temp_byte = *image_prt++;
00477                 switch(stage_no) {
00478                     case Stage1: // Inverse image
00479                     /* Example at stage 1 to get Even and Odd data. It's different order from G1.
00480                     * +---------+----+----+----+----+----+----+----+----+
00481                     * |         |bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|
00482                     * |temp_byte+----+----+----+----+----+----+----+----+
00483                     * |         |  1 |  0 |  1 |  1 |  0 |  1 |  0 |  0 |
00484                     * +---------+----+----+----+----+----+----+----+----+ */
00485                     data_line_odd[x]       = ((temp_byte & 0x40) ? BLACK3  : WHITE3); // WHITE3 = 0x80 = 1000 0000
00486                     data_line_odd[x]      |= ((temp_byte & 0x10) ? BLACK2  : WHITE2); // BLACK2 = 0x30 = 0011 0000
00487                     data_line_odd[x]      |= ((temp_byte & 0x04) ? BLACK1  : WHITE1); // BLACK1 = 0x0C = 0000 1100
00488                     data_line_odd[x]      |= ((temp_byte & 0x01) ? BLACK0  : WHITE0); // WHITE0 = 0x02 = 0000 0010
00489                     /* data_line_odd[x] = 1000 0000 | 0011 0000 | 0000 1100 | 0000 0010 = 1011 1110 ==> 1011 1110
00490                     * See Even data row at the table below*/
00491                     
00492                     data_line_even[k]    = ((temp_byte & 0x80) ? BLACK0  : WHITE0); // BLACK0 = 0x03 = 0000 0011
00493                     data_line_even[k]   |= ((temp_byte & 0x20) ? BLACK1  : WHITE1); // BLACK1 = 0x0C = 0000 1100
00494                     data_line_even[k]   |= ((temp_byte & 0x08) ? BLACK2  : WHITE2); // WHITE2 = 0x20 = 0010 0000
00495                     data_line_even[k--] |= ((temp_byte & 0x02) ? BLACK3  : WHITE3); // WHITE3 = 0x80 = 1000 0000
00496                     /* data_line_even[k] = 0000 0011 | 0000 1100 | 0010 0000 | 1000 0000 = 1010 1111 ==> 1111 1010
00497                     * See Odd data row at the table below
00498                     * +---------+----+----+----+----+----+----+----+----+
00499                     * |         |bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|
00500                     * |temp_byte+----+----+----+----+----+----+----+----+
00501                     * |         |  1 |  0 |  1 |  1 |  0 |  1 |  0 |  0 |
00502                     * +---------+----+----+----+----+----+----+----+----+
00503                     * | Color   |  W |  B |  W |  W |  B |  W |  B |  B | W=White, B=Black, N=Nothing
00504                     * +---------+----+----+----+----+----+----+----+----+
00505                     * | Stage 1 |  B |  W |  B |  B |  W |  B |  W |  W | Inverse
00506                     * +---------+----+----+----+----+----+----+----+----+
00507                     * | Input   | 11 | 10 | 11 | 11 | 10 | 11 | 10 | 10 | W=10, B=11, N=01
00508                     * +---------+----+----+----+----+----+----+----+----+
00509                     * |Even data| 11 |    | 11 |    | 10 |    | 10 |    | = 1111 1010
00510                     * +---------+----+----+----+----+----+----+----+----+
00511                     * |Odd data |    | 10 |    | 11 |    | 11 |    | 10 | = 1011 1110
00512                     * +---------+----+----+----+----+----+----+----+----+ */
00513                     break;              
00514                     case Stage3: // New image
00515                         data_line_odd[x]         = ((temp_byte & 0x40) ? WHITE3  : BLACK3 );
00516                         data_line_odd[x]        |= ((temp_byte & 0x10) ? WHITE2  : BLACK2 );
00517                         data_line_odd[x]        |= ((temp_byte & 0x04) ? WHITE1  : BLACK1 );
00518                         data_line_odd[x]        |= ((temp_byte & 0x01) ? WHITE0  : BLACK0 );
00519 
00520                         data_line_even[k]        = ((temp_byte & 0x80) ? WHITE0  : BLACK0 );
00521                         data_line_even[k]       |= ((temp_byte & 0x20) ? WHITE1  : BLACK1 );
00522                         data_line_even[k]       |= ((temp_byte & 0x08) ? WHITE2  : BLACK2 );
00523                         data_line_even[k--]     |= ((temp_byte & 0x02) ? WHITE3  : BLACK3 );
00524                     break;
00525                 }
00526         }   
00527 }
00528 
00529 
00530 /**
00531 * \brief The base function to handle the driving stages for Frame and Block type
00532 *
00533 * \note
00534 * - There are 3 stages to complete an image update on COG_V230_G2 type EPD.
00535 * - For more details on the driving stages, please refer to the COG G2 document Section 5.4
00536 *
00537 * \param EPD_type_index The defined EPD size
00538 * \param image_ptr The pointer of image array that stores image that will send to COG
00539 * \param image_data_address The address of memory that stores image
00540 * \param stage_no The assigned stage number that will proceed
00541 * \param lineoffset Line data offset
00542 */
00543 void stage_handle_Base(uint8_t EPD_type_index,uint8_t *image_prt,long image_data_address,
00544                         uint8_t stage_no,uint8_t lineoffset)
00545 {   
00546     struct EPD_V230_G2_Struct S_epd_v230;
00547     int16_t cycle,m,i; //m=number of steps
00548     //uint8_t isLastframe = 0;  //If it is the last frame to send Nothing at the fist scan line
00549     uint8_t isLastBlock=0;      //If the beginning line of block is in active range of EPD
00550     int16_t scanline_no=0;
00551     uint8_t *action_block_prt;
00552     long action_block_address;
00553     uint8_t byte_array[LINE_BUFFER_DATA_SIZE];
00554     /** Stage 2: BLACK/WHITE image, Frame type */
00555     if(stage_no==Stage2)
00556     {
00557         for(i=0;i<action__Waveform_param->stage2_cycle;i++)
00558         {
00559             same_data_frame (EPD_type_index,ALL_BLACK,action__Waveform_param->stage2_t1);
00560             same_data_frame (EPD_type_index,ALL_WHITE,action__Waveform_param->stage2_t2);
00561         }
00562         return;
00563     }
00564     /** Stage 1 & 3, Block type */
00565     // The frame/block/step of Stage1 and Stage3 are default the same.
00566     stage_init(EPD_type_index,
00567                 &S_epd_v230,
00568                 action__Waveform_param->stage1_block1,
00569                 action__Waveform_param->stage1_step1,
00570                 action__Waveform_param->stage1_frame1);
00571      
00572      /* Repeat number of frames */
00573      for (cycle = 0; cycle < (S_epd_v230.frame_cycle ); cycle++)
00574      {
00575         
00576         // if (cycle == (S_epd_v230.frame_cycle - 1)) isLastframe = 1;
00577          
00578          isLastBlock = 0;
00579          S_epd_v230.step_y0 = 0;
00580          S_epd_v230.step_y1 = S_epd_v230.step_size ;
00581          S_epd_v230.block_y0 = 0;
00582          S_epd_v230.block_y1 = 0;
00583          /* Move number of steps */
00584          for (m = 0; m < S_epd_v230.number_of_steps; m++)    
00585          {          
00586              S_epd_v230.block_y1 += S_epd_v230.step_size;
00587              S_epd_v230.block_y0 = S_epd_v230.block_y1 - S_epd_v230.block_size;
00588             /* reset block_y0=frame_y0 if block is not in active range of EPD */
00589              if (S_epd_v230.block_y0 < S_epd_v230.frame_y0) S_epd_v230.block_y0 = S_epd_v230.frame_y0;
00590             
00591             /* if the beginning line of block is in active range of EPD */
00592              if (S_epd_v230.block_y1 == S_epd_v230.block_size) isLastBlock = 1;
00593                 
00594              if(image_prt!=NULL)
00595              {
00596                  action_block_prt=(image_prt+(int)(S_epd_v230.block_y0*lineoffset));    
00597              }
00598              else if(_On_EPD_read_flash!=NULL)  //Read line data in range of block, read first
00599              {
00600                 action_block_address=image_data_address+(long)(S_epd_v230.block_y0*lineoffset);
00601                 _On_EPD_read_flash(action_block_address,(uint8_t *)&byte_array,
00602                                     COG_parameters[EPD_type_index].horizontal_size);
00603                 action_block_prt=(uint8_t *)&byte_array;
00604              }  
00605             /* Update line data */
00606              for (i = S_epd_v230.block_y0; i < S_epd_v230.block_y1; i++)
00607              {      
00608                 
00609                  if (i >= COG_parameters[EPD_type_index].vertical_size) break;
00610                  //if (isLastframe && 
00611                  if ( 
00612                   isLastBlock &&(i < (S_epd_v230.step_size + S_epd_v230.block_y0)))
00613                   {
00614                       nothing_line(EPD_type_index);                 
00615                   }
00616                   else   
00617                   {                              
00618                       read_line_data_handle(EPD_type_index,action_block_prt,stage_no);                  
00619                   }
00620                     
00621                 if(_On_EPD_read_flash!=NULL)    //Read line data in range of block
00622                 {
00623                     action_block_address +=lineoffset;
00624                     _On_EPD_read_flash(action_block_address,(uint8_t *)&byte_array,
00625                     COG_parameters[EPD_type_index].horizontal_size);
00626                     action_block_prt=(uint8_t *)&byte_array;
00627                 }
00628                 else action_block_prt+=lineoffset;
00629                     
00630                 scanline_no= (COG_parameters[EPD_type_index].vertical_size-1)-i;
00631                     
00632                 /* Scan byte shift per data line */
00633                 data_line_scan[(scanline_no>>2)] = SCAN_TABLE[(scanline_no%4)];
00634                    
00635                 /*  the border uses the internal signal control byte. */
00636                 *data_line_border_byte=0x00;
00637                        
00638                 /* Sending data */
00639                 epd_spi_send (0x0A, (uint8_t *)&COG_Line.uint8,
00640                 COG_parameters[EPD_type_index].data_line_size);
00641                 
00642                      
00643                 /* Turn on Output Enable */
00644                 epd_spi_send_byte (0x02, 0x07);
00645                        
00646                 data_line_scan[(scanline_no>>2)]=0;     
00647                                         
00648              }                                              
00649          }
00650             
00651     }   
00652 }
00653 
00654 /**
00655 * \brief The driving stages from image array (image_data.h) to COG
00656 *
00657 * \param EPD_type_index The defined EPD size
00658 * \param image_ptr The pointer of image array that stores image that will send to COG
00659 * \param stage_no The assigned stage number that will proceed
00660 * \param lineoffset Line data offset
00661 */
00662 void stage_handle(uint8_t EPD_type_index,uint8_t *image_prt,uint8_t stage_no,uint8_t lineoffset)
00663 {
00664     stage_handle_Base(EPD_type_index,image_prt,ADDRESS_NULL,stage_no,lineoffset);   
00665 }
00666 
00667 /**
00668 * \brief The driving stages from memory to COG
00669 *
00670 * \note
00671 * - This function is additional added here for developer if the image data
00672 *   is stored in Flash memory.
00673 *
00674 * \param EPD_type_index The defined EPD size
00675 * \param image_data_address The address of flash memory that stores image
00676 * \param stage_no The assigned stage number that will proceed
00677 * \param lineoffset Line data offset
00678 */
00679 static void stage_handle_ex(uint8_t EPD_type_index,long image_data_address,uint8_t stage_no,uint8_t lineoffset) {
00680     stage_handle_Base(EPD_type_index,NULL,image_data_address,stage_no,lineoffset);
00681 }
00682 
00683 /**
00684 * \brief Write image data from memory array (image_data.h) to the EPD
00685 *
00686 * \param EPD_type_index The defined EPD size
00687 * \param previous_image_ptr The pointer of memory that stores previous image
00688 * \param new_image_ptr The pointer of memory that stores new image
00689 */
00690 void EPD_display_from_array_prt (uint8_t EPD_type_index, uint8_t *previous_image_ptr,
00691         uint8_t *new_image_ptr) {   
00692     _On_EPD_read_flash=0;
00693     stage_handle(EPD_type_index,new_image_ptr,Stage1,COG_parameters[EPD_type_index].horizontal_size);   
00694     stage_handle(EPD_type_index,new_image_ptr,Stage2,COG_parameters[EPD_type_index].horizontal_size);   
00695     stage_handle(EPD_type_index,new_image_ptr,Stage3,COG_parameters[EPD_type_index].horizontal_size);   
00696 }
00697 
00698 /**
00699 * \brief Write image data from Flash memory to the EPD
00700 * \note This function is additional added here for developer if the image data
00701 * is stored in Flash.
00702 *
00703 * \param EPD_type_index The defined EPD size
00704 * \param previous_image_flash_address The start address of memory that stores previous image
00705 * \param new_image_flash_address The start address of memory that stores new image
00706 * \param On_EPD_read_flash Developer needs to create an external function to read flash
00707 */
00708 void EPD_display_from_flash_prt (uint8_t EPD_type_index, long previous_image_flash_address,
00709     long new_image_flash_address,EPD_read_flash_handler On_EPD_read_flash) {
00710         
00711     uint8_t line_len;
00712     line_len=LINE_SIZE;
00713     if(line_len==0) line_len=COG_parameters[EPD_type_index].horizontal_size;
00714         
00715     _On_EPD_read_flash=On_EPD_read_flash;   
00716     stage_handle_ex(EPD_type_index,new_image_flash_address,Stage1,line_len);
00717     stage_handle_ex(EPD_type_index,new_image_flash_address,Stage2,line_len);
00718     stage_handle_ex(EPD_type_index,new_image_flash_address,Stage3,line_len);    
00719 }
00720 
00721 
00722 /**
00723 * \brief Write Dummy Line to COG
00724 * \note A line whose all Scan Bytes are 0x00
00725 *
00726 * \param EPD_type_index The defined EPD size
00727 */
00728 static inline void dummy_line(uint8_t EPD_type_index) {
00729     uint8_t i;
00730     for (i = 0; i < (COG_parameters[EPD_type_index].vertical_size/8); i++) {
00731         switch(EPD_type_index) {
00732             case EPD_144:
00733             COG_Line.line_data_by_size.line_data_for_144.scan[i]=0x00;
00734             break;
00735             case EPD_200:
00736             COG_Line.line_data_by_size.line_data_for_200.scan[i]=0x00;
00737             break;
00738             case EPD_270:
00739             COG_Line.line_data_by_size.line_data_for_270.scan[i]=0x00;
00740             break;
00741         }
00742     }
00743     /* Set charge pump voltage level reduce voltage shift */
00744     epd_spi_send_byte (0x04, COG_parameters[EPD_type_index].voltage_level);
00745     
00746     /* Sending data */
00747     epd_spi_send (0x0A, (uint8_t *)&COG_Line.uint8, COG_parameters[EPD_type_index].data_line_size);
00748 
00749     /* Turn on Output Enable */
00750     epd_spi_send_byte (0x02, 0x07);
00751 }
00752 
00753 
00754 /**
00755 * \brief Write Border(Input) Dummy Line
00756 * \note Set Border byte 0xFF to write Black and set 0xAA to write White
00757 *
00758 * \param EPD_type_index The defined EPD size
00759 */
00760 static void border_dummy_line(uint8_t EPD_type_index)
00761 {
00762     uint16_t    i;
00763     for (i = 0; i < COG_parameters[EPD_type_index].data_line_size; i++)
00764     {
00765         COG_Line.uint8[i] = 0x00;
00766     }
00767     
00768     *data_line_border_byte=BORDER_BYTE_B;
00769     //Write a Border(B) Dummy Line
00770     epd_spi_send (0x0a, (uint8_t *)&COG_Line.uint8, COG_parameters[EPD_type_index].data_line_size);
00771     //Turn on OE
00772     epd_spi_send_byte (0x02, 0x07);
00773     
00774     sys_delay_ms(40);
00775     
00776     *data_line_border_byte=BORDER_BYTE_W;
00777     //Write a Borde(B) Dummy Line
00778     epd_spi_send (0x0a, (uint8_t *)&COG_Line.uint8, COG_parameters[EPD_type_index].data_line_size);
00779     //Turn on OE
00780     epd_spi_send_byte (0x02, 0x07);
00781 
00782     sys_delay_ms(200);
00783     
00784     
00785 }
00786 
00787 
00788 /**
00789 * \brief Power Off COG Driver
00790 * \note For detailed flow and description, please refer to the COG G2 document Section 6.
00791 *
00792 * \param EPD_type_index The defined EPD size
00793 */
00794 uint8_t EPD_power_off(uint8_t EPD_type_index) {
00795     uint8_t y;      
00796 
00797     if(EPD_type_index==EPD_144 || EPD_type_index==EPD_200)  {
00798         border_dummy_line(EPD_type_index);
00799         dummy_line(EPD_type_index);
00800     }
00801 
00802     delay_ms (25);
00803     if(EPD_type_index==EPD_270) {
00804         EPD_border_low();
00805         delay_ms (200);
00806         EPD_border_high();
00807     }
00808 
00809     //Check DC/DC
00810     if((SPI_R(0x0F,0x00) & 0x40) == 0x00) return ERROR_DC;
00811     
00812     //Turn on Latch Reset
00813     epd_spi_send_byte (0x03, 0x01);
00814     //Turn off OE
00815     epd_spi_send_byte (0x02, 0x05);
00816     //Power off charge pump Vcom
00817     epd_spi_send_byte (0x05, 0x0E);
00818     //Power off charge pump neg voltage
00819     epd_spi_send_byte (0x05, 0x02);
00820     //Turn off all charge pump 
00821     epd_spi_send_byte (0x05, 0x00);
00822     //Turn off OSC
00823     epd_spi_send_byte (0x07, 0x0D);
00824     
00825     epd_spi_send_byte (0x04, 0x83);
00826     delay_ms(120);
00827     epd_spi_send_byte (0x04, 0x00);
00828     
00829     epd_spi_detach ();
00830     EPD_cs_low();
00831     EPD_rst_low();
00832     EPD_Vcc_turn_off ();
00833     EPD_border_low();
00834     delay_ms (10);
00835         
00836     for(y=0;y<10;y++)
00837     {
00838         EPD_discharge_high ();      
00839         delay_ms (10);      
00840         EPD_discharge_low ();   
00841         delay_ms (10);  
00842     }
00843     return RES_OK;
00844 }
00845 
00846 #endif
00847 
00848 
00849