2018年8月28日火曜日

NucleoF446RE(mbed-cli)でu8g2を使う。


Arduinoの汎用モノクロディスプレイ用ライブラリのu8g2をmbedにPortしたライブラリが公開されています。

u8g2-mbed https://github.com/domantascibas/u8g2-mbed

mbed-cliで使うようになっています。mbed-cliのインストール、使い方は前回の「NucleoF446REでmbed-cliを使う。(メモ)」にあります。

Github:u8g2-mbed」からZipファイルを入手して作業ディレクトリに展開します。

作業ディレクトリ
D:\Users\gizmo\Documents\mbed\u8g2-mbed-master
展開したディレクトリに移動してmbedプロジェクトを作成。

PS D:\Users\gizmo\Documents\mbed\u8g2-mbed-master> mbed new .
[mbed] WARNING: Directory "D:\Users\gizmo\Documents\mbed\u8g2-mbed-master" is not empty.
---
[mbed] Creating new program "u8g2-mbed-master" (git)
[mbed] Adding library "mbed-os" from "https://github.com/ARMmbed/mbed-os" at branch/tag "latest"
[mbed] Updating reference "mbed-os" -> "https://github.com/ARMmbed/mbed-os/#f8b140f8d7cb226e41486c5df66ac4f3ce699219"
The following paths are ignored by one of your .gitignore files:
mbed-os.lib
Use -f if you really want to add them..

続いてデプロイします。

PS D:\Users\gizmo\Documents\mbed\u8g2-mbed-master> mbed deploy
[mbed] Updating library "mbed-os" to rev #f8b140f8d7cb (tags: latest, mbed-os-5.9.5)
[mbed] Adding library "u8g2" from "https://github.com/olikraus/u8g2" at rev #eb1b12fde776

ディレクトリの確認

PS D:\Users\gizmo\Documents\mbed\u8g2-mbed-master> ls


    ディレクトリ: D:\Users\gizmo\Documents\mbed\u8g2-mbed-master


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2018/08/26     17:11                .vscode
d-----       2018/08/26     17:11                fonts
d-----       2018/08/26     17:21                mbed-os
d-----       2018/08/26     17:11                src
d-----       2018/08/26     17:23                u8g2
-a----       2017/11/27      5:42             71 .gitignore
-a----       2018/08/26     17:23              8 .mbed
-a----       2017/11/27      5:42             48 .mbedignore
-a----       2017/11/27      5:42           1067 LICENSE
-a----       2018/08/26     17:21             78 mbed-os.lib
-a----       2018/08/26     17:21           1469 mbed_settings.py
-a----       2017/11/27      5:42           1508 README.md
-a----       2017/11/27      5:42             75 u8g2.lib

手持ちのI2C接続のSSD1306 OLED 128x32でテストしました。

ブレッドボード配線図

src/main.cppを以下のように書き換えました。

#include "mbed.h"
#include "u8g2.h"

DigitalOut led(D13);

uint8_t u8x8_gpio_and_delay_mbed(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
u8g2_t myScreen;

extern const uint8_t XLargeFont[] U8G2_FONT_SECTION("XLargeFont");
extern const uint8_t LargeFont[] U8G2_FONT_SECTION("LargeFont");

void setup() {
  //u8g2_Setup_ssd1306_i2c_128x64_noname_f(&myScreen, U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_mbed);
  u8g2_Setup_ssd1306_i2c_128x32_univision_f(&myScreen, U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_mbed);
  u8g2_InitDisplay(&myScreen);
  u8g2_SetPowerSave(&myScreen, 0);
  u8g2_ClearBuffer(&myScreen);

  // u8g2_SetFont(&myScreen, XLargeFont);
  // u8g2_DrawUTF8(&myScreen, 0, 32, "53");
  // u8g2_SetFont(&myScreen, LargeFont);
  // u8g2_DrawUTF8(&myScreen, 0, 32, "Hello world");
  u8g2_SetFont(&myScreen, u8g2_font_f16_t_japanese1);
  u8g2_DrawUTF8(&myScreen, 0, 20, "こんにちは世界");
  // u8g2_SetFont(&myScreen, u8g2_font_unifont_t_chinese2);
  // u8g2_DrawUTF8(&myScreen, 0, 62, "你好世界");

  u8g2_SendBuffer(&myScreen);
}

int main() {
  led = 0;
  // printf("Hello world");
  setup();
  
  while(1) {
    led = !led;
    wait(1.0);
  }
  return 0;
}

mbed-cliにMakefileみたいなものがあるのかわかりませんが、mbed compileするとfonts/以下の*.cファイル(フォント・データ)はコンパイルされるようです。

PS D:\Users\gizmo\Documents\mbed\u8g2-mbed-master> ls .\BUILD\NUCLEO_F446RE\GCC_ARM\fonts


    ディレクトリ: D:\Users\gizmo\Documents\mbed\u8g2-mbed-master\BUILD\NUCLEO_F446RE\GCC_ARM\fonts


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2018/08/28     12:29            150 LargeFont.d
-a----       2018/08/28     12:29           9880 LargeFont.o
-a----       2018/08/28     12:29            152 MediumFont.d
-a----       2018/08/28     12:29           8588 MediumFont.o
-a----       2018/08/28     12:29            150 SmallFont.d
-a----       2018/08/28     12:29           6084 SmallFont.o
-a----       2018/08/28     12:29            152 XLargeFont.d
-a----       2018/08/28     12:29           2464 XLargeFont.o

オブジェクトファイルは生成されますが、「XLargeFont」や「LargeFont」はmain.cppで宣言されていなくてコンパイル・エラーになるのでexternで宣言しました。

extern const uint8_t XLargeFont[] U8G2_FONT_SECTION("XLargeFont");
extern const uint8_t LargeFont[] U8G2_FONT_SECTION("LargeFont");

変数名のあとに付いている「U8G2_FONT_SECTION()」はメモリ空間を指定するマクロのようです。

I2C接続のSSD1306 128x64を使うようになっているのでI2C接続のSSD1306 128x32のものを使うように初期化関数を変更。

  //u8g2_Setup_ssd1306_i2c_128x64_noname_f(&myScreen, U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_mbed);
  u8g2_Setup_ssd1306_i2c_128x32_univision_f(&myScreen, U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_mbed);

「u8g2_font_f16_t_japanese1」というフォントはu8g2.hで宣言されています。一覧は「olikraus/u8g2」の「fntlistall」にあります。

コンパイル

PS D:\Users\gizmo\Documents\mbed\u8g2-mbed-master> mbed compile -t GCC_ARM -m NUCLEO_F446RE
Building project u8g2-mbed-master (NUCLEO_F446RE, GCC_ARM)
Scan: .
Scan: env
Scan: mbed
Compile [100.0%]: main.cpp
Link: u8g2-mbed-master
Elf2Bin: u8g2-mbed-master
+------------------+--------+-------+------+
| Module           |  .text | .data | .bss |
+------------------+--------+-------+------+
| [fill]           |    115 |     4 |   14 |
| [lib]\c.a        |  24641 |  2472 |   56 |
| [lib]\gcc.a      |   3168 |     0 |    0 |
| [lib]\misc       |    252 |    16 |   28 |
| mbed-os\drivers  |    192 |     4 |  100 |
| mbed-os\hal      |   1697 |     4 |   68 |
| mbed-os\platform |   2764 |   260 |  133 |
| mbed-os\rtos     |   8498 |   168 | 6073 |
| mbed-os\targets  |   8583 |     4 |  552 |
| src\delay.o      |      4 |     0 |    0 |
| src\main.o       |    194 |     4 |  156 |
| src\u8g2_mbed.o  |    204 |     4 |   56 |
| u8g2\csrc        |  50114 |     0 |  512 |
| Subtotals        | 100426 |  2940 | 7748 |
+------------------+--------+-------+------+
Total Static RAM memory (data + bss): 10688 bytes
Total Flash memory (text + data): 103366 bytes

Image: .\BUILD\NUCLEO_F446RE\GCC_ARM\u8g2-mbed-master.bin

ピンをアサイン


ピン名はPinNames.hで定義されています。Nucleo F446REの場合は

https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/TARGET_NUCLEO_F446RE/PinNames.h

I2C_SCL     = PB_8,
I2C_SDA     = PB_9,

と定義されています。

u8g2のピンアサインはu8g2-mbed-master\u8g2\cppsrc\U8g2lib.hで定義されています。


class U8G2_SSD1306_128X32_UNIVISION_1_SW_I2C : public U8G2 {
  public: U8G2_SSD1306_128X32_UNIVISION_1_SW_I2C(const u8g2_cb_t *rotation, uint8_t clock, uint8_t data, uint8_t reset = U8X8_PIN_NONE) : U8G2() {
    u8g2_Setup_ssd1306_i2c_128x32_univision_1(&u8g2, rotation, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_arduino);
    u8x8_SetPin_SW_I2C(getU8x8(), clock,  data,  reset);
  }
};

「u8g2-mbed-master\u8g2\cppsrc\」下はArduino用のラッパーで、そのままではmbedで使えません。

I2Cで信号線がSCL/SDAの2本だけのものならピン固定で使えそうですが、SPIだとRESETやDS線が必要なのでピンアサインできるようにしないとダメですがちょっとしんどそう(@@;;;

<追記:2018.09.01>

ピンアサインについてですが、u8g2-mbedのsrc/u8g2_mbed.cppを見てみると

DigitalInOut i2c_scl(PB_8);
DigitalInOut i2c_sda(PB_9);

とI2Cに使うピン名がハードコーディングされていました。(しかもSTM32のピン名)

u8g2-mbedは、u8g2の全体を移植したものではなく、STM32でI2CのSSD1306を使うためのものと考えたほうが良さそうです。

</追記>

0 件のコメント:

コメントを投稿