電子ペーパーで所在を表示しておくプレートのプログラムです

Dependencies:   SDFileSystem mbed

eink.cpp

Committer:
kohacraft
Date:
2017-05-23
Revision:
2:3ca92c70070c
Parent:
1:bd1c3875fb64

File content as of revision 2:3ca92c70070c:

/* 電子ペーパーを制御してbmpを表示します */

#include "mbed.h"
#include "extdio.h"
#include "eink.h"

int clPulseCount = 0;   //CLパルスのカウント

//ポートの初期化
void initPort()
{
    setCL( 0 );
    setContBus( LE , 0);
    setContBus( OE , 0);
    setContBus( NC10 , 1);
    setContBus( SPH , 1);

    setContBus( GMODE , 0);
    setContBus( SPV , 1);
    setContBus( CKV , 0);
    setContBus( EN , 0);

    setDataBus( 0b00000001 );
    setDataBus( 0b00000000 );
    
    return;
}

//ページの開始シーケンス
void pageStart()
{   

    setContBus( GMODE , 1 );
    setContBus( CKV , 1 );
    wait_us(11);
    setContBus( SPV , 0 ); 
    wait_us(11);
    setContBus( CKV , 0 );
    wait_us(10);
    setContBus( CKV , 1 );
    wait_us(10);
    setContBus( SPV , 1 ); 
    wait_us(12);

    setContBus( CKV , 0 );
    wait_us(10);
    setContBus( CKV , 1 );
    wait_us(22);
    setContBus( CKV , 0 );
    wait_us(10);
    setContBus( CKV , 1 );
    wait_us(22);
    setContBus( CKV , 0 );
    wait_us(10);
    setContBus( CKV , 1 );
    wait_us(1);
    
    return;
}

//行ごとの開始シーケンス
void lineStart()
{
    
    setContBus( LE , 0 );
    setContBus( OE , 1 );
    setContBus( SPH , 0 );
    
    clPulseCount = 0;
    
    return;
}

//1行の中央でのシーケンス
void changeSPH()
{
    setContBus( SPH , 1 );
    setContBus( NC10 , 0 );
    
    return;    
}

//4ピクセル分の描画データの転送シーケンス
void setDrawData( char data )
{
    setDataBus( data );
    setCL( 1 );
    setCL( 0 );
    
    //200パルス出力したらSPHを交代する
    clPulseCount++;
    if( clPulseCount == EDP_WIDTH/8 )
    {
        changeSPH();
    }
    
    return;
}

//行の終わりのシーケンス
void lineEnd()
{
    setContBus( NC10 , 1 );
    setContBus( CKV , 0 );
    wait_us(10);
    
    setContBus( OE , 0 );
    setContBus( LE , 1 );
    setContBus( CKV , 1 );
    wait_us(1);
}

//ページの終わりのシーケンス
void pageEnd()
{
    setContBus( LE , 0 );
    setContBus( OE , 1 );
    
    for( int i=0 ; i<EDP_WIDTH/4 ; i++ )
    {
        setCL( 1 );
        setCL( 0 );
    }
    setContBus( CKV , 0 );
    wait_us(10);    
    setContBus( OE , 0 );
    wait_us(330);
    setContBus( GMODE , 0 );
    wait_us(130);

}


//電子ペーパーの回路の電源を切る
void powerOff()
{
    setDataBus( 0b00000000 );

    setCL( 0 );
    setContBus( LE , 0);
    setContBus( OE , 0);
    setContBus( NC10 , 0);
    setContBus( SPH , 0);

    setContBus( GMODE , 0);
    setContBus( SPV , 0);
    setContBus( CKV , 0);
    
    setContBus( EN , 1);
    
    return;
    
}

//電子ペーパーの回路の電源を入れる
void powerOn()
{
    setContBus( EN , 0);
    wait_us(100);
    
    return;
}

//画面をクリアする
//drawMode EDP_WHITE:白でクリア EDP_BLACK:黒でクリア
void clrDisp( char drawMode )
{
    char data;
    if( drawMode ==  EDP_WHITE)
        data = 0b01010101;    //全てのピクセルを白にする
    else
        data = 0b10101010;    //全てのピクセルを黒にする

    pageStart();
    for( int j=0 ; j<EDP_HEIGHT ; j++)
    {
        lineStart(); 
        for( int i=0 ; i<EDP_WIDTH ; i+=4 )            
        {
            setDrawData( data );
        }
        lineEnd();
        
    }
    pageEnd();
    
    return;
}

//bmp画像1バイト分(8ピクセル)のデータを描画
// data: 描画データ (MSB)b0A b0B b1A b1B b2A b2B b3A bB3(LSB)
//                  b0 b1 b2 b4:各ドットのデータ
//                  AB: 10:黒 01:白 00:透明
// drawMode: EDP_BLACK黒の部分を黒で,白の部分を透明で描画(背景を残す) 
//           EDP_WHITE白の部分を白で,黒の部分を透明で描画(背景を残す)
//           EDP_BLACK_WHITE白の部分を白で,黒の部分を黒で描画
void drowPixels( char data , char drawMode  )
{
    char _data = 0;
    switch( drawMode )
    {
        case EDP_BLACK :
            _data = 0;
            _data |= ((data&0x10)==0)<<7;
            _data |= ((data&0x20)==0)<<5;
            _data |= ((data&0x40)==0)<<3;
            _data |= ((data&0x80)==0)<<1;
            setDrawData( _data );
            _data = 0;
            _data |= ((data&0x01)==0)<<7;
            _data |= ((data&0x02)==0)<<5;
            _data |= ((data&0x04)==0)<<3;
            _data |= ((data&0x08)==0)<<1;
            setDrawData( _data );
            break;
        case EDP_WHITE :
            _data = 0;
            _data |= ((data&0x10)!=0)<<6;
            _data |= ((data&0x20)!=0)<<4;
            _data |= ((data&0x40)!=0)<<2;
            _data |= ((data&0x80)!=0);
            setDrawData( _data );
            _data = 0;
            _data |= ((data&0x01)!=0)<<6;
            _data |= ((data&0x02)!=0)<<4;
            _data |= ((data&0x04)!=0)<<2;
            _data |= ((data&0x08)!=0);
            setDrawData( _data );
            break;
        default :
            _data = 0;
            _data |= ((data&0x10)==0)<<7;
            _data |= ((data&0x10)!=0)<<6;
            _data |= ((data&0x20)==0)<<5;
            _data |= ((data&0x20)!=0)<<4;
            _data |= ((data&0x40)==0)<<3;
            _data |= ((data&0x40)!=0)<<2;
            _data |= ((data&0x80)==0)<<1;
            _data |= ((data&0x80)!=0);
            setDrawData( _data );
            _data = 0;
            _data |= ((data&0x01)==0)<<7;
            _data |= ((data&0x01)!=0)<<6;
            _data |= ((data&0x02)==0)<<5;
            _data |= ((data&0x02)!=0)<<4;
            _data |= ((data&0x04)==0)<<3;
            _data |= ((data&0x04)!=0)<<2;
            _data |= ((data&0x08)==0)<<1;
            _data |= ((data&0x08)!=0);
            setDrawData( _data );
            break;
    }
    
    return;
}

//fpのbmpデータを描画する
// drawMode: EDP_BLACK 黒の部分を黒で描画し,白の部分を透明(背景を残す)で描画
//           EDP_WHITE 白の部分を白で描画し,黒の部分を透明(背景を残す)で描画
//           EDP_BLACK_WHITE 白の部分を白で,黒の部分を黒で描画する
void dispBmp(FILE *fp , char drawMode )
{
    bool paletteWhite = 0;      //白のパレット番号
    char bmpdata[EDP_WIDTH/8];  //1ライン分のデータバッファ
    
    //ファイルポインタが正しいか確認
    if( fp == NULL )
    {
        fclose(fp);
        free(fp);
    
        //ファイルポインタが正しくない
        clrDisp(EDP_WHITE); //白でクリア
        clrDisp(EDP_BLACK); //黒でクリア
        clrDisp(EDP_WHITE); //白でクリア
        clrDisp(EDP_BLACK); //黒でクリア
        
        return;
    }
    
    //画像のサイズ取得
    unsigned int bmpWidth , bmpHeight;
    fseek(fp, 18 , SEEK_SET);//to xsize
    fread( &bmpWidth , sizeof(unsigned int) , 1 , fp);
    fread( &bmpHeight , sizeof(unsigned int) , 1 , fp);
    if( bmpWidth != EDP_WIDTH || bmpHeight != EDP_HEIGHT )
    {
        fclose(fp);
        free(fp);
    
        //画像サイズが正しくない
        clrDisp(EDP_WHITE); //白でクリア
        clrDisp(EDP_BLACK); //黒でクリア
        clrDisp(EDP_WHITE); //白でクリア
        
        return;
    }
    
    //パレットデータを取得
    unsigned char paletteTemp[8];
    fseek(fp, 54 , SEEK_SET);//bitmap headder throw
    fread( paletteTemp , sizeof(char) , 8 , fp);
    int palette0 = (int)paletteTemp[0]+(int)paletteTemp[1]+(int)paletteTemp[2];    //パレット0のRGBの合計
    int palette1 = (int)paletteTemp[4]+(int)paletteTemp[5]+(int)paletteTemp[6];    //パレット1のRGBの合計
    if( palette0 > palette1 )   //輝度が明るいパレット番号を白にする
        paletteWhite = 0;   //パレット0が白
    else
        paletteWhite = 1;   //パレット1が白
    
    //bmp画像データの先頭まで移動
    unsigned int dataOffset;
    fseek(fp, 10 , SEEK_SET);
    fread( &dataOffset , sizeof(unsigned int) , 1 , fp);
    fseek(fp, dataOffset , SEEK_SET);
    
    //電子ペーパーにbmpデータを転送
    pageStart();
    for( int j=0 ; j<EDP_HEIGHT ; j++)
    {
        //1ライン分のbmpデータを読み込み0が黒、1が白になるように変換
        fread( &bmpdata , sizeof(char) , EDP_WIDTH/8 , fp);
        if( paletteWhite == 0 )
        {
            for( int i=0 ; i<EDP_WIDTH/8 ; i++ )
                bmpdata[i] = ~bmpdata[i];
        }
    
        lineStart();
        for( int i=0 ; i<EDP_WIDTH ; i+=8 )
        {
            drowPixels(bmpdata[i/8],drawMode);
        }
        lineEnd();
    
    }
    pageEnd();
    
    return;
}