SPI使用9bit転送のOLED接続

手元にあったMARY-OBというOLEDボード(2011)を整備が進んできたSPIドライバー
経由で接続することにチャレンジしたので、まとめておく。

SPIドライバーは当初、GPIOが26ピンだったためSPIがバス1本のStandardSPIのみの
サポートで、基本的に8bit単位の転送しかできなかった。
40ピンの時代になってBCM2835が搭載され、拡張SPIへの本格的取組が行われてきた。
カーネルが4.4.13以降、何回かの錯誤を経て、SPIバス2本が使える形に仕上がって
来ている。
拡張されたauxiliary SPI側では、LoSSIやワードサイズの指定が(限定的に)できる。
詳細は、ここを参照するとよい。

【準備】

1.BCM2835が載ったRaspberryPiを用意する。
2.カーネル4.4.y(又は4.9.y)のRaspbianOSを
  インストールして起動する。
3.「 ls /dev/spi*」コマンドで、
  /dev/spidev0.0 /dev/spidev0.1 /dev/spidev1.0 /dev/spidev1.1
  の4ポートが出現するように設定する。そのためには、
 ・config.txtに
  dtoverlay=pi3-disable-bt
  dtoverlay=spi1-2cs
  を追加する。       (注意:/dev/ttyS0との共存はできない)
 ・/boot/cmdline.txtに
  console=ttyS0,115200
  があれば、この部分を削除する。
4.pigpioライブラリーをインストールする。
  http://abyz.co.uk/rpi/pigpio/download.html (ガイド付き)
  または、いつもの、
  sudo apt-get install pigpio python-pigpio python3-pigpio
5.環境をテストする(make -j4を実施した時)。
  sudo ./x_pigpio

【OLEDサンプルプログラム】
  OLEDユニット UG-2828GDEDF11 に使われているコントローラーは、
  SOLOMON SYSTECH社のSSD1351でした。

SPIのピンヘッダの利用は次の通り。
    

SPI Function Header Pin Broadcom Pin Name Broadcom Pin Function
MOSI P1-38 GPIO20 SPI1_MOSI
SCLK P1-40 GPIO21 SPI1_SCLK
CE0 P1-12 GPIO18 SPI1_CE0_N
CE1 P1-11 GPIO17 SPI1_CE1_N

GPIO16をVCC_POWER_ONに利用している。焼き付き防止に有効。
任意のOUTPUT端子で良いが、ここではGPIO23をモジュールのリセットに使う。
この他に、VCC5V、VDD3.3V、GNDの接続がそれぞれ必要である。

SPIバスのオープン
int spiOpen(unsigned spiChan, unsigned baud, unsigned spiFlags);
spiChanでチップセレクトの出力先を、baudにはクロックスピードを設定する。
spiFlagsの意味
spiFlagsは下位22ビットが次のように定義されている。
21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
 b  b  b  b  b  b  R  T  n  n  n  n  W  A u2 u1 u0 p2 p1 p0  m  m

    このサンプルでは、次のようにオープンしている。

static uint16_t mode = 0x160;

    Aをオンにし、auxSPIを使用する。
    u0,u1をオンにし、二つのポートCE0,1の制御をライブラリに委ねている。

static uint16_t bits = 9;

    bits of word は9ビットを指定

static uint32_t speed = 10000000;

    speedはPiZeroやPi3に合わせて要求した。P12は倍でもOK。実速度は異なる。

spiOpen(0, speed, bits<<16 | mode );

    /dev/spidev1.0 のオープン

ソースファイル

//=========================================================
// File Name : oledspi2.c
// Function  : OLED Control
//---------------------------------------------------------
//---------------------------------------------------------
// Copyright (C) 2010-2011 Munetomo Maruyama
//=========================================================
// ---- License Information -------------------------------
// Anyone can FREELY use this code fully or partially
// under conditions shown below.
// 1. You may use this code only for individual purpose,
//    and educational purpose.
//    Do not use this code for business even if partially.
// 2. You can copy, modify and distribute this code.
// 3. You should remain this header text in your codes
//   including Copyright credit and License Information.
// 4. Your codes should inherit this license information.
//=========================================================
// ---- Patent Notice -------------------------------------
// I have not cared whether this system (hw + sw) causes
// infringement on the patent, copyright, trademark,
// or trade secret rights of others. You have all
// responsibilities for determining if your designs
// and products infringe on the intellectual property
// rights of others, when you use technical information
// included in this system for your business.
//=========================================================
// ---- Disclaimers ---------------------------------------
// The function and reliability of this system are not
// guaranteed. They may cause any damages to loss of
// properties, data, money, profits, life, or business.
// By adopting this system even partially, you assume
// all responsibility for its use.
//=========================================================
#include <stdio.h>
#include <inttypes.h>
#include <pigpio.h>
#include "oled.h"
#include "font.h"

//=================
// Font Parameters
//=================
#define OLED_FONT_XSIZE 8
#define OLED_FONT_YSIZE 8

//======================
// Define OLED Commands
//======================
#define OLED_COMMAND 1
#define OLED_DATA    2
//
#define C_SET_COLUMN_ADDRESS 0x0215
#define C_SET_ROW_ADDRESS    0x0275
#define D_START_ADDRESS 2
#define D_END_ADDRESS   3
//
#define C_WRITE_RAM_COMMAND 0x005c
#define C_READ_RAM_COMMAND  0x005d
//
#define C_SET_REMAP_COLOR_DEPTH 0x01a0
#define D_SET_REMAP_COLOR_DEPTH 2
//
#define C_SET_DISPLAY_START_LINE 0x01a1
#define D_SET_DISPLAY_START_LINE 2
//
#define C_SET_DISPLAY_OFFSET 0x01a2
#define D_SET_DISPLAY_OFFSET 2
//
#define C_SET_DISPLAY_MODE_ALL_OFF 0x00a4
#define C_SET_DISPLAY_MODE_ALL_ON  0x00a5
#define C_SET_DISPLAY_MODE_RESET   0x00a6
#define C_SET_DISPLAY_MODE_INVERSE 0x00a7
//
#define C_FUNCTION_SELECTION 0x01ab
#define D_FUNCTION_SELECTION 2
//
#define C_SET_SLEEP_MODE_ON  0x00ae
#define C_SET_SLEEP_MODE_OFF 0x00af
//
#define C_SET_RESET_PRECHARGE_PERIOD 0x01b1
#define D_SET_RESET_PRECHARGE_PERIOD 2
//
#define C_ENHANCE_DRIVING_SCHEME_CAPABILITY 0x03b2
#define D_ENHANCE_DRIVING_SCHEME_CAPABILITY_1 2
#define D_ENHANCE_DRIVING_SCHEME_CAPABILITY_2 3
#define D_ENHANCE_DRIVING_SCHEME_CAPABILITY_3 4
//
#define C_FRONT_CLOCK_DRIVER_OSCILLATOR_FREQUENCY 0x01b3
#define D_FRONT_CLOCK_DRIVER_OSCILLATOR_FREQUENCY 2
//
#define C_SET_SEGMENT_LOW_VOLTAGE 0x03b4
#define D_SET_SEGMENT_LOW_VOLTAGE_1 2 // 0xa0 or 0xa2
#define D_SET_SEGMENT_LOW_VOLTAGE_2 3 // 0xb5
#define D_SET_SEGMENT_LOW_VOLTAGE_3 4 // 0x55
//
#define C_SET_GPIO 0x01b5
#define D_SET_GPIO 2
//
#define C_SET_SECOND_PRECHARGE_PERIOD 0x01b6
#define D_SET_SECOND_PRECHARGE_PERIOD 2
//
#define C_LOOKUP_TABLE_FOR_GRAY_SCALE_PULSE_WIDTH 0x3fb8
static const uint8_t GAMMA_TABLE[63] =
{
    0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
    0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
    //
    0x12, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f,
    0x21, 0x23, 0x25, 0x27, 0x2a, 0x2d, 0x30, 0x33,
    //
    0x36, 0x39, 0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4c,
    0x50, 0x54, 0x58, 0x5c, 0x60, 0x64, 0x68, 0x6c,
    //
    0x70, 0x74, 0x78, 0x7d, 0x82, 0x87, 0x8c, 0x91,
    0x96, 0x9b, 0xa0, 0xa5, 0xaa, 0xaf, 0xb4
};
//
#define C_USE_BUILT_IN_LINEAR_LUT 0x00b9
//
#define C_SET_PRECHARGE_VOLTAGE 0x01bb
#define D_SET_PRECHARGE_VOLTAGE 2
//
#define C_SET_VCOMH_VOLTAGE 0x01be
#define D_SET_VCOMH_VOLTAGE 2
//
#define C_SET_CONTRAST_CURRENT_FOR_COLOR_ABC 0x03c1
#define D_SET_CONTRAST_CURRENT_FOR_COLOR_A 2
#define D_SET_CONTRAST_CURRENT_FOR_COLOR_B 3
#define D_SET_CONTRAST_CURRENT_FOR_COLOR_C 4
//
#define C_MASTER_CONTRAST_CURRENT_CONTROL 0x01c7
#define D_MASTER_CONTRAST_CURRENT_CONTROL 2
//
#define C_SET_MUX_RATIO 0x01ca
#define D_SET_MUX_RATIO 2
//
#define C_SET_COMMAND_LOCK 0x01fd
#define D_SET_COMMAND_LOCK 2
//
#define C_HORIZONTAL_SCROLL 0x0596
#define D_HORIZONTAL_SCROLL_A 2
#define D_HORIZONTAL_SCROLL_B 3
#define D_HORIZONTAL_SCROLL_C 4
#define D_HORIZONTAL_SCROLL_D 5
#define D_HORIZONTAL_SCROLL_E 6
//
#define C_STOP_MOVING  0x009e
#define C_START_MOVING 0x009f

#define MAX_WORKBUF 64
uint8_t *xvsnprintf(uint8_t *str, int32_t length, const char *format)
{
    uint8_t *ptr;

    ptr = (uint8_t*) format;
    while(*ptr != '\0')
    {
            if (length > 0) {*str++ = *ptr; length--;}
            ptr++;
    }
    //
    if (str != NULL) *str = '\0';
    return str;
}

#
//=============
// Globals
//=============
volatile uint32_t gOLED_printf_Font   = OLED_FONT_SMALL;
volatile uint32_t gOLED_printf_ColorF = OLED_WHT;
volatile uint32_t gOLED_printf_ColorB = OLED_BLK;
volatile uint32_t gOLED_printf_PosX = 0;
volatile uint32_t gOLED_printf_PosY = 0;
//
volatile uint32_t gOELD_Orientation_Mode = OLED_TOP_N;

static uint16_t mode = 0x160;	/* SPI1,u1,u0 */
static uint16_t bits = 9;
static uint32_t speed = 10000000;
    uint32_t oled[65];
//======================
// Initialize OLED
//======================


/*
int gpioSetMode(unsigned gpio, unsigned mode);
int gpioGetMode(unsigned gpio);
int gpioSetPullUpDown(unsigned gpio, unsigned pud);
int gpioRead(unsigned gpio);
int gpioWrite(unsigned gpio, unsigned level);
int gpioTrigger(unsigned user_gpio, unsigned pulseLen, unsigned level);
int spiRead(unsigned handle, char *buf, unsigned count);
int spiWrite(unsigned handle, char *buf, unsigned count);
int spiXfer(unsigned handle, char *txBuf, char *rxBuf, unsigned count);
*/
int Init_OLED(void)
{
    uint32_t i;

    // Display OFF

    oled[OLED_COMMAND] = C_SET_DISPLAY_MODE_ALL_OFF;
    OLED_Send_Command(oled);
    //
    // Initialization Sequence of OLED
    //
    oled[OLED_COMMAND] = C_SET_COMMAND_LOCK;
    oled[D_SET_COMMAND_LOCK] = 0x112; // unlock
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_COMMAND_LOCK;
    oled[D_SET_COMMAND_LOCK] = 0x1b1; // unlock
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_SLEEP_MODE_ON;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_FRONT_CLOCK_DRIVER_OSCILLATOR_FREQUENCY;
    oled[D_FRONT_CLOCK_DRIVER_OSCILLATOR_FREQUENCY] = 0xf1;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_MUX_RATIO;
    oled[D_SET_MUX_RATIO] = 0x17f;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_DISPLAY_OFFSET;
    oled[D_SET_DISPLAY_OFFSET] = 0x100;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_DISPLAY_START_LINE;
    oled[D_SET_DISPLAY_START_LINE] = 0x100;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_REMAP_COLOR_DEPTH;
    oled[D_SET_REMAP_COLOR_DEPTH] = 0x174; // 64k colors
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_GPIO;
    oled[D_SET_GPIO] = 0x100;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_FUNCTION_SELECTION;
    oled[D_FUNCTION_SELECTION] = 0x101;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_SEGMENT_LOW_VOLTAGE;
    oled[D_SET_SEGMENT_LOW_VOLTAGE_1] = 0x1a0; // use external VSL
    oled[D_SET_SEGMENT_LOW_VOLTAGE_2] = 0x1b5;
    oled[D_SET_SEGMENT_LOW_VOLTAGE_3] = 0x155;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_CONTRAST_CURRENT_FOR_COLOR_ABC;
    oled[D_SET_CONTRAST_CURRENT_FOR_COLOR_A] = 0x1c8;
    oled[D_SET_CONTRAST_CURRENT_FOR_COLOR_B] = 0x180;
    oled[D_SET_CONTRAST_CURRENT_FOR_COLOR_C] = 0x1c8;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_MASTER_CONTRAST_CURRENT_CONTROL;
    oled[D_MASTER_CONTRAST_CURRENT_CONTROL] = 0x10f;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_LOOKUP_TABLE_FOR_GRAY_SCALE_PULSE_WIDTH;
    for (i = 2; i < 65; i++)
    {
        oled[i] = (uint32_t) GAMMA_TABLE[i - 2] | 0x100;
    }
    OLED_Send_Command(oled);
    //
  //oled[OLED_COMMAND] = C_USE_BUILT_IN_LINEAR_LUT;
  //OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_RESET_PRECHARGE_PERIOD;
    oled[D_SET_RESET_PRECHARGE_PERIOD] = 0x132;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_ENHANCE_DRIVING_SCHEME_CAPABILITY;
    oled[D_ENHANCE_DRIVING_SCHEME_CAPABILITY_1] = 0x1a4;
    oled[D_ENHANCE_DRIVING_SCHEME_CAPABILITY_2] = 0x100;
    oled[D_ENHANCE_DRIVING_SCHEME_CAPABILITY_3] = 0x100;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_PRECHARGE_VOLTAGE;
    oled[D_SET_PRECHARGE_VOLTAGE] = 0x117;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_SECOND_PRECHARGE_PERIOD;
    oled[D_SET_SECOND_PRECHARGE_PERIOD] = 0x101;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_VCOMH_VOLTAGE;
    oled[D_SET_VCOMH_VOLTAGE] = 0x105;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_DISPLAY_MODE_RESET;
    OLED_Send_Command(oled);
    //
    // Clear Screen
    oled[OLED_COMMAND] = C_SET_COLUMN_ADDRESS;
    oled[D_START_ADDRESS] = 0x100;
    oled[D_END_ADDRESS]   = 0x17f;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_SET_ROW_ADDRESS;
    oled[D_START_ADDRESS] = 0x100;
    oled[D_END_ADDRESS]   = 0x17f;
    OLED_Send_Command(oled);
    //
    oled[OLED_COMMAND] = C_WRITE_RAM_COMMAND;
    OLED_Send_Command(oled);
    //
}

//==================================
// Initialize OLED with Orientation
//==================================
void Init_OLED_with_Orientation(uint32_t mode)
{
    uint8_t command;

    Init_OLED();
    gOELD_Orientation_Mode = mode;
    //
    command = (mode == OLED_TOP_W)? 0x25 :
              (mode == OLED_TOP_S)? 0x26 :
              (mode == OLED_TOP_E)? 0x37 : 0x34;
    oled[OLED_COMMAND] = C_SET_REMAP_COLOR_DEPTH;
    oled[D_SET_REMAP_COLOR_DEPTH] = command | 0x100;
    OLED_Send_Command(oled);
}

//=====================
// OLED Send Command
//=====================
void OLED_Send_Command(uint32_t *oled)
{
    uint32_t i;
    uint32_t count,countR;
    uint16_t bus;

    count = (oled[OLED_COMMAND] >> 8) & 0x0ff;

    bus = oled[OLED_COMMAND] & 0xFF;
    for (i=0;i<=count;i++) {
        countR = spiWrite( oled[0], (char *)&bus, 2);
        bus = oled[OLED_DATA+i] | 0x100;
    }	
    //
}

//=====================
// OLED Send Data
//=====================
void OLED_Send_Data(uint32_t *oled, int count)
{
    uint32_t i;
    uint16_t bus;

    for (i=0;i<count;i++) {
       bus = (oled[OLED_DATA+i] & 0xff) | 0x100;
       spiWrite( oled[0], (char *)&bus, 2);
    }	
}

//====================
// OLED Send a Pixel
//====================
void OLED_Send_Pixel(uint32_t color)
{
    oled[OLED_DATA+0] = (color >> 8) ;
    oled[OLED_DATA+1] = color;

    OLED_Send_Data(oled, 2);
}
//===================
// OLED Clear Screen
//===================
void OLED_Clear_Screen(uint32_t color)
{
    uint32_t i;
    uint32_t bus;

    oled[OLED_COMMAND] = C_WRITE_RAM_COMMAND;
    OLED_Send_Command(oled);
    bus = (color & 0xff00)<<8  | (color & 0xff) | 0x01000100;
    for (i=0;i<128*128;i++) {
       spiWrite( oled[0], (char *)&bus, 4);
    }	
}

//=======================
// OLED Draw a Character
//=======================
// scale should be 0, 1 or 2
void OLED_Draw_Char(char ch, uint32_t posx, uint32_t posy, uint32_t color_f, uint32_t color_b, uint32_t scale)
{
    uint32_t x0, y0;
    uint32_t xsize, ysize;
    uint32_t x, y;
    uint32_t xfont, yfont;
    uint32_t pixel;
    uint32_t color;
    //
    uint32_t col0, col1, row0, row1;

    ch = (ch < 0x20)? 0x20 : (ch > 0x7f)? 0x7f : ch;
    //
    x0 = posx * (OLED_FONT_XSIZE << scale);
    y0 = posy * (OLED_FONT_YSIZE << scale);
    //
    xsize = OLED_FONT_XSIZE * (1 << scale);
    ysize = OLED_FONT_YSIZE * (1 << scale);
    //
    if ((x0 <= (128 - xsize)) && (y0 <= (128 - ysize)))
    {
        col0 = (gOELD_Orientation_Mode == OLED_TOP_W)? y0       :
               (gOELD_Orientation_Mode == OLED_TOP_S)? x0 :
               (gOELD_Orientation_Mode == OLED_TOP_E)? y0 : x0;
        col1 = (gOELD_Orientation_Mode == OLED_TOP_W)? y0 + ysize - 1 :
               (gOELD_Orientation_Mode == OLED_TOP_S)? x0 + xsize - 1 :
               (gOELD_Orientation_Mode == OLED_TOP_E)? y0 + ysize - 1 : x0 + xsize - 1;
        row0 = (gOELD_Orientation_Mode == OLED_TOP_W)? x0 :
               (gOELD_Orientation_Mode == OLED_TOP_S)? y0 :
               (gOELD_Orientation_Mode == OLED_TOP_E)? x0 : y0;
        row1 = (gOELD_Orientation_Mode == OLED_TOP_W)? x0 + xsize - 1 :
               (gOELD_Orientation_Mode == OLED_TOP_S)? y0 + ysize - 1 :
               (gOELD_Orientation_Mode == OLED_TOP_E)? x0 + xsize - 1 : y0 + ysize - 1;
        //
       
        oled[OLED_COMMAND] = C_SET_COLUMN_ADDRESS;
        oled[D_START_ADDRESS] = (col0 > 127)? 127 : col0;
        oled[D_END_ADDRESS]   = (col1 > 127)? 127 : col1;
        OLED_Send_Command(oled);
        //
        oled[OLED_COMMAND] = C_SET_ROW_ADDRESS;
        oled[D_START_ADDRESS] = (row0 > 127)? 127 : row0;
        oled[D_END_ADDRESS]   = (row1 > 127)? 127 : row1;
        OLED_Send_Command(oled);
        //
        oled[OLED_COMMAND] = C_WRITE_RAM_COMMAND;
        OLED_Send_Command(oled);
        //
        for (y = 0; y < ysize; y++)
        {
            for (x = 0; x < xsize; x++)
            {
                xfont = x >> scale;
                yfont = y >> scale;
                pixel = FONT[((uint32_t) ch - 0x20) * 8 + yfont];
                pixel = (pixel >> (OLED_FONT_XSIZE - 1 - xfont)) & 0x01;
                color = (pixel == 1)? color_f : color_b;
                OLED_Send_Pixel(color);
            }
        }
    }
}

//====================
// OLED Make Color
//====================
//      RGB num
// BLK  000 0000-003f (< 64)
// BLU  001 0040-007f (<128)
// CYN  011 0080-00bf (<192)
// GRN  010 00c0-00ff (<256)
// YEL  110 0100-013f (<320)
// WHT  111 0140-017f (<384)
// MAG  101 0180-01bf (<448)
// RED  100 01c0-01ff (<512)
// BLK  000

//===========================
// OLED Set printf() Position
//===========================
void OLED_printf_Position(uint32_t posx, uint32_t posy)
{
    gOLED_printf_PosX = posx;
    gOLED_printf_PosY = posy;
}

//=====================
// OLED printf
//=====================
void OLED_printf(const char *format, ...)
{
    uint8_t buf[256];
    uint8_t *pStr;

    xvsnprintf(buf, 256, format);

    pStr = buf;
    while(*pStr != '\0')
    {
        if (*pStr == '\n')
        {
            gOLED_printf_PosX = 0;
            gOLED_printf_PosY++;
        }
        else
        {
            OLED_Draw_Char(*pStr, gOLED_printf_PosX, gOLED_printf_PosY,
                    gOLED_printf_ColorF, gOLED_printf_ColorB, gOLED_printf_Font);
            gOLED_printf_PosX++;
        }
        pStr++;
        //
        if (gOLED_printf_PosX >= (128 / (OLED_FONT_XSIZE << gOLED_printf_Font)))
        {
            gOLED_printf_PosX = 0;
            gOLED_printf_PosY++;
        }
        if (gOLED_printf_PosY >= (128 / (OLED_FONT_YSIZE << gOLED_printf_Font)))
        {
            gOLED_printf_PosY = 0;
        }
    }
}
//=====================
// Display BITMAP
//=====================
//-----------------------
// Main Routine
//-----------------------
#define BMP 1   // select which BMP you want to see.
#define BUD 30  // select which BUD part you want to see.


  #include "../bmp/lego8.bmp.plt.h"
  #include "../bmp/lego8.bmp.rgb.h"


  #include "../bmp/nana8.bmp.plt.h"
  #include "../bmp/nana8.bmp.rgb.h"


int main() {
    uint32_t x, y, i;
    uint8_t  index, orien;
    uint32_t palette;
    uint32_t red, blu, grn;
    uint32_t oled1, oled2, pixel;

   if (gpioInitialise() < 0) return -1;

    gpioSetMode(16,1);
    gpioSetMode(23,1);

    gpioWrite(16,1);    // OLED Vcc PowerON
    time_sleep( 0.1 );  // wait for 100ms
    // OLED Reset
    // OLED_/RES GPIO OUT
    gpioWrite(23,0);
    time_sleep( 0.1 );  // wait for 100ms
    gpioWrite(23,1);    // high (reset)
    time_sleep( 0.1 );  // wait for 100ms

    // Initialize Hardware
    oled1 = spiOpen(0, speed, bits<<16 | mode );
    oled2 = spiOpen(1, speed, bits<<16 | mode );
  for (orien=100; orien>0; orien--) {
    // Initialization
    //
    oled[0] = oled1;	
    Init_OLED_with_Orientation(orien & 3);
	OLED_Clear_Screen(OLED_BLK) ;   
    //
    // Send Bitmap Data1
    //
    i = 0;
    for (y = 0; y < 128; y++)
    {
        for (x = 0; x < 128; x++)
        {
            index = BMP_RGB[i++];
            palette = BMP_PLT[index];

            red = (palette >> (16 + 3)) & 0x01f;
            grn = (palette >> ( 8 + 2)) & 0x03f;
            blu = (palette >> ( 0 + 3)) & 0x01f;
            pixel = (red << 11) + (grn << 5) + (blu << 0);
            OLED_Send_Pixel(pixel);
        }
    }
    // Display ON
    oled[OLED_COMMAND] = C_SET_SLEEP_MODE_OFF;
    OLED_Send_Command(oled);
    // Dummy Print (to make correct link)
    OLED_printf_Position(0, 0);
    OLED_printf("RaspberryPi");
    //
    // Send Bitmap Data2
    //
    time_sleep( 1 );  // wait for 1s
  }
   gpioWrite(16,0);    // OLED Vcc PowerOFF
   spiClose(oled1);
   spiClose(oled2);
   gpioTerminate();

}
//=========================================================
// End of Program
//=========================================================

oled.h

ifndef __OLED_H__
#define __OLED_H__

//===============
// Define Colors
//===============
#define OLED_RED_MAX 0x1f
#define OLED_GRN_MAX 0x3f
#define OLED_BLU_MAX 0x1f
#define OLED_RED_MIN 0x00
#define OLED_GRN_MIN 0x00
#define OLED_BLU_MIN 0x00
#define OLED_RED_MID 0x10
#define OLED_GRN_MID 0x20
#define OLED_BLU_MID 0x10
//
#define OLED_RED ((OLED_RED_MAX << 11) + (OLED_GRN_MIN << 5) + (OLED_BLU_MIN << 0))
#define OLED_GRN ((OLED_RED_MIN << 11) + (OLED_GRN_MAX << 5) + (OLED_BLU_MIN << 0))
#define OLED_BLU ((OLED_RED_MIN << 11) + (OLED_GRN_MIN << 5) + (OLED_BLU_MAX << 0))
#define OLED_BLK ((OLED_RED_MIN << 11) + (OLED_GRN_MIN << 5) + (OLED_BLU_MIN << 0))
#define OLED_WHT ((OLED_RED_MAX << 11) + (OLED_GRN_MAX << 5) + (OLED_BLU_MAX << 0))
#define OLED_YEL ((OLED_RED_MAX << 11) + (OLED_GRN_MAX << 5) + (OLED_BLU_MIN << 0))
#define OLED_CYN ((OLED_RED_MIN << 11) + (OLED_GRN_MAX << 5) + (OLED_BLU_MAX << 0))
#define OLED_MAG ((OLED_RED_MAX << 11) + (OLED_GRN_MIN << 5) + (OLED_BLU_MAX << 0))
#define OLED_GRY ((OLED_RED_MID << 11) + (OLED_GRN_MID << 5) + (OLED_BLU_MID << 0))

//=================
// Font Parameters
//=================
#define OLED_FONT_SMALL  0
#define OLED_FONT_MEDIUM 1
#define OLED_FONT_LARGE  2

//=================
// Orientation Mode
//=================
enum OELD_ORIENTATION_MODE {OLED_TOP_N, OLED_TOP_W, OLED_TOP_S, OLED_TOP_E};

//==============
// Prototypes
//==============
int  Init_OLED(void);
void Init_OLED_with_Orientation(uint32_t mode);
void OLED_Send_Command(uint32_t *oled);
void OLED_Send_Pixel(uint32_t color);
uint32_t OLED_Draw_Text_Small(char *pStr, uint32_t posx, uint32_t posy, uint32_t color_f, uint32_t color_b);
uint32_t OLED_Draw_Text_Medium(char *pStr, uint32_t posx, uint32_t posy, uint32_t color_f, uint32_t color_b);
uint32_t OLED_Draw_Text_Large(char *pStr, uint32_t posx, uint32_t posy, uint32_t color_f, uint32_t color_b);
void OLED_Draw_Char(char ch, uint32_t posx, uint32_t posy, uint32_t color_f, uint32_t color_b, uint32_t scale);
void OLED_Draw_Dot(int32_t x, int32_t y, int32_t size, uint32_t color);
void OLED_Clear_Screen(uint32_t color);
void OLED_Fill_Rect(int32_t x0, int32_t y0, int32_t xsize, int32_t ysize, uint32_t color);
char OLED_Num4_to_Char(uint32_t num4);
uint32_t OLED_Draw_Hex(uint32_t bitlen, uint32_t hex, uint32_t posx, uint32_t posy, uint32_t color_f, uint32_t color_b);
uint32_t OLED_Make_Color(uint32_t num);
//
void OLED_printf_Font(uint32_t font);
void OLED_printf_Color(uint32_t color_f, uint32_t color_b); // corrected 2011.03.20 MM
void OLED_printf_Position(uint32_t posx, uint32_t posy);
void OLED_printf(const char *format, ...);

#endif // __OLED_H__
カテゴリー: RaspberryPi パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です