製作モジュール一覧

ラベル Nucleo F446RE の投稿を表示しています。 すべての投稿を表示
ラベル Nucleo F446RE の投稿を表示しています。 すべての投稿を表示

2022年10月27日木曜日

SSD1306 OLEDをSTM32で動かす。 afiskonライブラリ

afiskonライブラリafiskon/stm32-ssd1306はSSD1306は4iloライブラリからforkされたものの様で、SSD1306 OLEDのI2C版とSPI版に対応しています。

Nucleo-F446REとNucleo-G431KBで動作確認しました。

以下の記事を参考にさせていただきました。

「afiskon」さん(本家) https://github.com/afiskon/stm32-ssd1306
「hacksOnTable」さん 「STM32 OLED TUTORIAL(Youtube)」

HALを使ったプログラミングはSTM32CubeIDEの登場でかなり便利になりましたが、MPUのシリーズによって特徴があり、設定やプログラミングが方法がそれぞれ少しずつ異なります。冗長になりますが、Nucleo-F446REとNucleo-G431GBで、SSD1306のI2C版とSPI版の使い方を説明します。

STM32CubeIDEのバージョン: 1.10.1

I2C版 Nucleo-F446RE


Board SelecotorでNuckeo-F446REを指定してDefult Modeで初期化。

MXの設定


Pinout & Configuration
  Connectivity
    I2C1
      Mode
        I2C: I2C
      Configuration
        Parameter Settings
          Master Features
            I2C Speed Mode: Standard Mode
        GPIO Settings
          PB8 I2C1_SCL
          PB9 I2C1_SDA

afiskonライブラリではデフォルトでI2C1を使う設定になっています。I2C2やI2C3などを使う場合は「ssd1306_conf_template.h」を適宜書き換えます。

ハードウェアの準備


SSD1306 F446RE Arduino Header
GND GND GND
VDD 3V3 3V3
SCK PB8 D15
SDA PB9 D14

ブレッドボード配線図

ライブラリの準備


GitHubのafiskon/stm32-ssd1306からZIPファイルをダウンロードします。
  • ssd1306.h
  • ssd1306_conf_templates.h
  • ssd1306_fonts.h
  • ssd1306_tests.h
を「<Projectフォルダ>\Core\Inc\」に
  • ssd1306.c
  • ssd1306_fonts.c
  • ssd1306_tests.c
を「<Projectフォルダ>\Core\Src\」にコピーします。IDEのProject ExplorerでProjectフォルダを右クリックし「Refresh」します。

「Core/Inc/ssd1306_conf_template.h」の内容を以下のように書き換えます。

// Choose a microcontroller family
//#define STM32F0
#define STM32F4

重要:「ssd1306_conf_template.h」を「ssd1306_conf.h」にRenameします。

ソースコード


MXでコード生成して、Core\Src\main.cに以下のコードを追加します。

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ssd1306.h"
#include "ssd1306_fonts.h"
#include "ssd1306_tests.h"
/* USER CODE END Includes */

<略>

  /* USER CODE BEGIN 2 */
  ssd1306_TestAll();
  /* USER CODE END 2 */

実行している様子

FPS表示値

Standard Mode 9
Fast Mode 34

F446REの駆動クロックはHSI/84MHz。

I2C信号波形

F446RE I2C Fast Mode 2.2kΩ Pullup


C1:SDA C2:SCL

I2C版 Nucleo-G431KB


Board SelecotorでNuckeo-G431KBを指定してDefult Modeで初期化。

MXの設定


Pinout & Configuration
  Connectivity
    I2C1
      Mode
        I2C: I2C
      Configuration
        Parameter Settings
          Master Features
            I2C Speed Mode: Standard Mode
        GPIO Settings
          PA15 I2C1_SCL
          PB7  I2C1_SDA

ブレッドボード配線図


SSD1306 G431KB Arduino Header
GND GND GND
VDD 3V3 3V3
SCK PA15 D5
SDA PB7 D4

ライブラリの準備


必要なファイルをコピーします。
  • Core/Inc/ssd1306.h
  • Core/Inc/ssd1306_conf_templates.h
  • Core/Inc/ssd1306_fonts.h
  • Core/Inc/ssd1306_tests.h
  • Core/Src/ssd1306.c
  • Core/Src/ssd1306_fonts.c
  • Core/Src/ssd1306_tests.c
「Core/Inc/ssd1306_conf_template.h」の内容を以下のように書き換えます。

// Choose a microcontroller family
//#define STM32F0
#define STM32G4

「#define STM32G4」はコメントアウトで用意されていないので書き加えます。「ssd1306.h」では

#elif defined(STM32G4)
#include "stm32g4xx_hal.h"

と、STM32G4を使用する場合の定義があります。

重要:「ssd1306_conf_template.h」を「ssd1306_conf.h」にRenameします。

ソースコード


MXでコード生成して、Core\Src\main.cに以下のコードを追加します。

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ssd1306.h"
#include "ssd1306_fonts.h"
#include "ssd1306_tests.h"
/* USER CODE END Includes */

<略>

  /* USER CODE BEGIN 2 */
  ssd1306_TestAll();
  /* USER CODE END 2 */

main.cへのソースコードの追加はI2C版 Nucleo-F446REと同じです。

実行している様子

FPS表示値

Standard Mode 9
Fast Mode 35
Fast Mode Plus 76

※Fast Mode Plusで使用する場合は2.2kΩ程度で外部Pullupする。

G431KBの駆動クロックはHSI/170MHz。

I2C信号波形

G431RB I2C Fast Mode Plus 2.2kΩ Pullup


C1:SDA C2:SCL

SPI版 Nucleo-F446RE


Board SelecotorでNuckeo-F446REを指定してDefult Modeで初期化。

MXの設定


Pinout & Configuration
  System Core
    Configuration
      GPIO
        PA10 : Output Push Pull : Very High : OLED_Res
        PB4  : Output Push Pull : Very High : OLED_CS
        PB5  : Output Push Pull : Very High : OLED_DC
  Connectivity
    SPI2
      Mode
        Mode: Half Duplex Master
      Configuration
        Parameter Settings
          Clock Parameters
            Prescaler(for Baud Rate): 64
            Clock Polarity(CPOL): High
            Clock Phase(CPHA): 2 Edge
        GPIO Settings
          PB10 SPI2_SCK
          PC1  SPI2_MOSI

Nucleo-F446REでは、SPI1はデフォルトでは使用不可になっているのでSPI2を使用します。MISOは使わないのでModeはHalf Duplex Masterにします。

動作確認のためClock Prescalerは大きめにしてクロック周波数を低く設定します。

重要:Clock Polarity(CPOL)、Clock Phase(CPHA)は上記の通り設定すると動作するようです。

またGPIOで制御信号線(CS、RES、DC)を割り当てます。右側のPinout図でPinをクリックしてGPIO_Outputを選択し、User Labelを設定します。User Labelはssd1306_conf_template.hで定義されているものを入力します。

ハードウェアの準備


SSD1306 F446RE Arduino Header 機能
GND GND GND GND
VDD 3V3 3V3 3.3V Power
D0 PB10 D6 SPI/SCK
D1 PC1 A4 SPI/MOSI
RES PA10 D2 Reset
DC PB5 D4 Data/Command
CS PB4 D5 SPI/CS

ブレッドボード配線図

ライブラリの準備


必要なファイルをコピーします。
  • Core/Inc/ssd1306.h
  • Core/Inc/ssd1306_conf_templates.h
  • Core/Inc/ssd1306_fonts.h
  • Core/Inc/ssd1306_tests.h
  • Core/Src/ssd1306.c
  • Core/Src/ssd1306_fonts.c
  • Core/Src/ssd1306_tests.c
Core\Inc\ssd1306_conf_template.hを以下のように変更します。

// Choose a microcontroller family
//#define STM32F0
//#define STM32F1
#define STM32F4
//#define STM32L0
//#define STM32L1
//#define STM32L4
//#define STM32F3
//#define STM32H7
//#define STM32F7
//#define STM32G0

// Choose a bus
//#define SSD1306_USE_I2C
#define SSD1306_USE_SPI

// I2C Configuration
//#define SSD1306_I2C_PORT        hi2c1
//#define SSD1306_I2C_ADDR        (0x3C << 1)

// SPI Configuration
#include "main.h"
#define SSD1306_SPI_PORT        hspi2
#define SSD1306_CS_Port         OLED_CS_GPIO_Port
#define SSD1306_CS_Pin          OLED_CS_Pin
#define SSD1306_DC_Port         OLED_DC_GPIO_Port
#define SSD1306_DC_Pin          OLED_DC_Pin
#define SSD1306_Reset_Port      OLED_Res_GPIO_Port
#define SSD1306_Reset_Pin       OLED_Res_Pin

SPI2を使うのでSSD_1306_SPI_PORTの定義をhspi2に変更します。

あまり感心できるものではありませんが、OLED_CS_GPIO_Portなどが定義されていないというエラーが出るので、直前に
#include "main.h"
という一行を追加して、定義されているヘッダーファイルをインポートします。

重要:「ssd1306_conf_template.h」を「ssd1306_conf.h」にRenameします。

ソースコード


MXでコード生成して、Core\Src\main.cに以下のコードを追加します。

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ssd1306.h"
#include "ssd1306_fonts.h"
#include "ssd1306_tests.h"
/* USER CODE END Includes */

<略>

  /* USER CODE BEGIN 2 */
  ssd1306_TestAll();
  /* USER CODE END 2 */

main.cのコード追加はI2C版と同じです。

実行している様子

FPS表示値

SPI Prescaler:64 (655.25KBits/s) 60
SPI Prescaler:16 (2.625MBits/s) 144
SPI Prescaler: 2 (21.0MBits/s) 217

F446REの駆動クロックはHSI/84MHz。

SPI信号波形

F446RE SPI Prescaler=16


C1:MOSI C2:SCK


SPI版 Nucleo-G431KB


Board SelecotorでNuckeo-G431KBを指定してDefult Modeで初期化。

MXの設定


Pinout & Configuration
  System Core
    Configuration
      GPIO
        PA11 : Output Push Pull : Very High : OLED_Res
        PB4  : Output Push Pull : Very High : OLED_CS
        PB5  : Output Push Pull : Very High : OLED_DC
  Connectivity
    SPI1
      Mode
        Mode: Half Duplex Master
      Configuration
        Parameter Settings
          Basic Parameters
            Data Size: 8bit
          Clock Parameters
            Prescaler(for Baud Rate): 256
            Clock Polarity(CPOL): High
            Clock Phase(CPHA): 2 Edge
        GPIO Settings
          PA5 SPI2_SCK
          PA7 SPI2_MOSI

Nucleo-G431KBではデフォルトでSPI1が使用できるのでSPI1を使います。MISOは使わないのでModeはHalf Duplex Masterにします。重要:Data Sizeがデフォルトでは4bitになっているので、8bitに変更します。

動作確認のためClock Prescalerは大きめにしてクロック周波数を低く設定します。

Clock Polarity(CPOL)、Clock Phase(CPHA)は上記の通り設定すると動作するようです。

またGPIOで制御信号線(CS、RES、DC)を割り当てます。右側のPinout図でPinをクリックしてGPIO_Outputを選択し、User Labelを設定します。User Labelはssd1306_conf_template.hで定義されているものを入力します。

ハードウェアの準備


SSD1306 G431KB Arduino Header 機能
GND GND GND GND
VDD 3V3 3V3 3.3V Power
D0 PA5 A4 SPI/SCK
D1 PA7 A6 SPI/MOSI
RES PA11 D10 Reset
DC PB5 D11 Data/Command
CS PB4 D12 SPI/CS

ブレッドボード配線図


ライブラリの準備


必要なファイルをコピーします。
  • Core/Inc/ssd1306.h
  • Core/Inc/ssd1306_conf_templates.h
  • Core/Inc/ssd1306_fonts.h
  • Core/Inc/ssd1306_tests.h
  • Core/Src/ssd1306.c
  • Core/Src/ssd1306_fonts.c
  • Core/Src/ssd1306_tests.c
Core\Inc\ssd1306_conf_template.hを以下のように変更します。

// Choose a microcontroller family
//#define STM32F0
//#define STM32F1
//#define STM32F4
//#define STM32L0
//#define STM32L1
//#define STM32L4
//#define STM32F3
//#define STM32H7
//#define STM32F7
//#define STM32G0
#define STM32G4

// Choose a bus
//#define SSD1306_USE_I2C
#define SSD1306_USE_SPI

// I2C Configuration
//#define SSD1306_I2C_PORT        hi2c1
//#define SSD1306_I2C_ADDR        (0x3C << 1)

// SPI Configuration
#include "main.h"
#define SSD1306_SPI_PORT        hspi1
#define SSD1306_CS_Port         OLED_CS_GPIO_Port
#define SSD1306_CS_Pin          OLED_CS_Pin
#define SSD1306_DC_Port         OLED_DC_GPIO_Port
#define SSD1306_DC_Pin          OLED_DC_Pin
#define SSD1306_Reset_Port      OLED_Res_GPIO_Port
#define SSD1306_Reset_Pin       OLED_Res_Pin

あまり感心できるものではありませんが、OLED_CS_GPIO_Portなどが定義されていないというエラーが出るので、直前に
#include "main.h"
という一行を追加して、定義されているヘッダーファイルをインポートします。

重要:「ssd1306_conf_template.h」を「ssd1306_conf.h」にRenameします。


ソースコード


MXでコード生成して、Core\Src\main.cに以下のコードを追加します。


/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ssd1306.h"
#include "ssd1306_fonts.h"
#include "ssd1306_tests.h"
/* USER CODE END Includes */

<略>

  /* USER CODE BEGIN 2 */
  ssd1306_TestAll();
  /* USER CODE END 2 */

main.cはいずれも同じコードです。

実行している様子

FPS表示値

SPI Prescaler:256 (654.062KBits/s) 69
SPI Prescaler: 64 (2.65625MBits/s) 199
SPI Prescaler: 8 (21.25MBits/s) 437
SPI Prescaler: 4 (42.5MBits/s) 動作せず

G431REの駆動クロックはHSI/170MHz。

SPI信号波形

G431KB SPI Prescaler=64


C1:MOSI C2:SCK


2022年10月24日月曜日

SSD1306 OLEDをSTM32で動かす。 4iloライブラリ

Nucleo-F446REとNucleo-G431KBで4lioライブラリを使ってみました。4iloライブラリはI2C版のみの対応です。SPI版のSSD1306 OLEDを使用するには派生ライブラリのafiskonライブラリafiskon/stm32-ssd1306を使います。(次回予定)

以下の記事を参考にさせていただきました。


使用したSTM32CubeIDEのバージョン: 1.10.1

なお、久しぶりにSTM32CubeIDEを立ち上げると延々とUpdateがかかるので事前に一度起動してUpdateを完了させると良いと思います。ST-LinkのファームウェアのアップデートもあるのでLチカなども走らせましょう。

Nucleo-F446RE


Board SelecotorでNuckeo-F446REを指定してDefult Modeで初期化。

MXの設定


STM32CubeIDEでは「Device Configuration Tool」と呼ばれるもので、「.ioc」ファイルを開くとIDE内で起動します。STM32CubeMXと機能的にはほぼ同等なので、このBlogではMXと呼んでいます。STM32CubeMXを別途立ち上げる必要はありません。

Pinout & Configuration
  Connectivity
    I2C1
      Mode
        I2C: I2C
      Configuration
        Parameter Settings
          Master Features
            I2C Speed Mode: Standard Mode
        GPIO Settings
          PB8 I2C1_SCL
          PB9 I2C1_SDA

Parameter Settingsはデフォルトのまま、Standard Mode (100kHz)でOKです。Fast Mode(400kHz)でも動作します。

GPIO Settingsは右側のPinout図で設定すると左下のConfigurationペインに反映されます。ピン割当はArduinoヘッダのD14(PB8)、D15(PB9)に変更しました。

ハードウェアの準備


ブレッドボード配線図
SSD1306 F446RE Arduino Header
GND GND GND
VDD 3V3 3V3
SCK PB8 D15
SDA PB9 D14

ライブラリの準備


4ilo/ssd1306-stm32HALからZIPファイルをダウンロード(右上の「Code」-「Download ZIP」をクリック)して展開しておきます。
  • ssd1306.h
  • fonts.h
を「<Projectフォルダ>\Core\Inc\」に
  • ssd1306.c
  • fonts.c
を「<Projectフォルダ>\Core\Src\」にコピーします。IDEのProject ExplorerでProjectフォルダを右クリックし「Refresh」します。

ソースコード


MXでコード生成して、Core\Src\main.cに以下のコードを追加します。

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ssd1306.h"
#include "fonts.h"
/* USER CODE END Includes */

<略>

  /* USER CODE BEGIN 2 */
  // Init lcd using one of the stm32HAL i2c typedefs
  ssd1306_Init(&hi2c1);

  // Write data to local screenbuffer
  ssd1306_SetCursor(0, 36);
  ssd1306_WriteString("4ilo", Font_11x18, White);

  // Copy all data from local screenbuffer to the screen
  ssd1306_UpdateScreen(&hi2c1);
  /* USER CODE END 2 */

実行している様子

I2C信号波形


外部Pullupなし Fast Mode(400kHz)

C1:SDA C2:SCL

I2CのSCLとSDAは、SSD1306モジュール上でPullupされているので、外部Pullupしなくても動作します。

外部Pullup 10kΩ  Fast Mode(400kHz)

C1:SDA C2:SCL

外部Pullupすると信号波形がきれいになります。

外部Pullup 2.2kΩ  Fast Mode(400kHz)

C1:SDA C2:SCL

外部Pullupの抵抗値を小さくしても400kHzクロックではあまり変わりませんね。

Nucleo-G431KB


Board SelecotorでNuckeo-G431KBを指定して「Defult Mode」で初期化。

MXの設定


Pinout & Configuration
  Connectivity
    I2C1
      Mode
        I2C: I2C
      Configuration
        Parameter Settings
          I2C Speed Mode: Standard Mode
        GPIO Settings
          PA15: I2C1_SCL
          PB7:  I2C1_SDA

I2C Speed ModeはまずStandard Modeで動作確認し、Fast Mode、Fast Plus Modeに変更して動作確認しました。

ハードウェアの準備


ブレッドボード配線図
SSD1306 G431KB Arduino Header
GND GND GND
VDD 3V3 3V3
SCK PA15 D4
SDA PB9 D5

ライブラリの準備


Nucleo-F446REと同様にファイルをコピーします。

Core/Inc/fonts.h
Core/Inc/ssd1306.h
Core/Src/fonts.c
Core/Src/fonts.h

重要: STMG431KBを使うので、Core/Inc/ssd1306.hを以下のように変更します。

//#include "stm32f4xx_hal.h"
#include "stm32g4xx_hal.h"

main.cへのソースコードの追加はNucleo-F446REの場合と同じです。

実行している様子

I2C Speed Mode


10kΩの外部Pullupした場合、Standard Mode、Fast Modeでは動作しましたが、Fast Mode Plusでは動作しませんでした。外部Pullupを2.2kΩに変更するとFast Mode Plusでも動作しました。

Standard Mode(100kHz) 外部Pullup 10kΩ 

C1:SDA C2:SCL

Fast Mode(400kHz) 外部Pullup 10kΩ 

C1:SDA C2:SCL

Fast Mode Plus(1000kHz) 外部Pullup 10kΩ 

C1:SDA C2:SCL

9bit目でACKされておらず(HIGHに引っ張りきれていない)、以降のI2C通信が失敗しています。

Fast Mode Plus(1000kHz) 外部Pullup 2.2kΩ 

C1:SDA C2:SCL

Pullup抵抗の抵抗値を小さくすると、ACKが認識されて正常に通信が行われています。

注)オシロ波形の下に周波数を表示させていますが、C1:SDAの値です。クロック周波数を知るためにはC2:SCLの値を表示させるべきでした。クロック周波数はC2(青色)の波形数と目盛りから概算できます。

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を使うためのものと考えたほうが良さそうです。

</追記>

2018年8月26日日曜日

NucleoF446REでmbed-cliを使う。(メモ)

だいぶ前になりますが、以下のサイトを参考にしてmbed-cliの環境を構築しました。(Windows10)

オフィシャルのドキュメント
「Github: Arm Mbed Command Line Interface https://github.com/ARMmbed/mbed-cli」
「arm MBED https://os.mbed.com/docs/v5.9/tools/installation-and-setup.html」

日本語の解説
「Toyomasa Watarai」さんの「mbed オフラインの開発環境」
「Yoshihiro TSUBOI」さんの「[lang:ja] mbed CLIをWindowsで使ってみる(環境構築編)」
@matsujirushiさんの「Arm Mbed CLIの環境構築 for Windows」

WindowsまたはMac OS Xの場合は専用のインストーラーがあるようですが、もろもろのツールを手動インストールしていました。

以下、PowerShellで作業しました。

手動でインストールしたプログラムの確認


Python


PS D:\> python --version
Python 2.7.14

Git

PS D:\> git --version
git version 2.16.2.windows.1

Mercurial

PS D:\> hg --version
Mercurial - 分散構成管理ツール(バージョン 4.6.1)
(詳細は https://mercurial-scm.org を参照)

Copyright (C) 2005-2018 Matt Mackall and others
本製品はフリーソフトウェアです。
頒布条件に関しては同梱されるライセンス条項をお読みください。
市場適合性や特定用途への可否を含め、 本製品は無保証です。

GCC

PS D:\> arm-none-eabi-gcc --version
arm-none-eabi-gcc.exe (GNU Tools for Arm Embedded Processors 7-2018-q2-update) 7.3.1 20180622 (release) [ARM/embedded-7-branch revision 261907]
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

GCCはGCC 7をインストールしてPATHを通していますが、mbed-cliでcompileするとエラーが出たので、別にインストールしているGCC 6をmbed-cliの環境設定で指定して使用しました(後述)。

エラーメッセージ

PS D:\Users\gizmo\Documents\mbed\mbed-os-example-blinky>  mbed compile -t GCC_ARM -m NUCLEO_F446RE
[Error] @,: Compiler version mismatch: Have 7.3.1; expected version >= 6.0.0 and < 7.0.0

mbed-cliのアップデート

PS D:\Users\gizmo\Documents\mbed> pip install -U mbed-cli
Collecting mbed-cli
  Downloading https://files.pythonhosted.org/packages/dc/42/8c4d0ac81a063074a62143aeb136035c9d80517bdaf611603fefe2b67856/mbed_cli-1.7.5-py2-none-any.whl (47kB)
    100% |################################| 51kB 1.2MB/s
Installing collected packages: mbed-cli
  Found existing installation: mbed-cli 1.7.3
    Uninstalling mbed-cli-1.7.3:
      Successfully uninstalled mbed-cli-1.7.3
Successfully installed mbed-cli-1.7.5
You are using pip version 9.0.1, however version 18.0 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.

mbed-cliを新規インストールする場合は
pip install mbed-cli
とUpdateするオプションの「-U」を省いてやればだいじょうぶだと思います。

念の為ですが、パスの「gizmo」はWindowsのUser名で「D:\Users\gizmo\Documents\mbed\」をmbedの作業フォルダとしています。

mbed-cliはPythonスクリプトでPythonのインストール・フォルダ下にあります。
C:\Python27\Scripts

Exampleのインポート


まずはLチカです。mbed-os-example-blinkyをインポートしました。

インポートにまずまず時間はかかりますが、インポート完了時に反応がないので適当にEnterキーを押します。

PS D:\Users\gizmo\Documents\mbed> mbed import mbed-os-example-blinky
[mbed] Importing program "mbed-os-example-blinky" from "https://github.com/ARMmbed/mbed-os-example-blinky" at latest revision in the current branch
[mbed] Adding library "mbed-os" from "https://github.com/ARMmbed/mbed-os" at rev #f8b140f8d7cb

インポートしたフォルダのサイズ:695MB

環境変数の設定

前述の通り、mbed-cliの環境設定でGCC 6のパスを指定します。

PS D:\Users\gizmo\Documents\mbed\mbed-os-example-blinky> mbed config -G GCC_ARM_PATH "D:\GNU Tools ARM Embedded\6.2 2016q4\bin"
[mbed] D:\GNU Tools ARM Embedded\6.2 2016q4\bin now set as global GCC_ARM_PATH

mbed-cliの設定の確認

PS D:\Users\gizmo\Documents\mbed\mbed-os-example-blinky> mbed config --list
[mbed] Global config:
GCC_ARM_PATH=D:\GNU Tools ARM Embedded\6.2 2016q4\bin

[mbed] Local config (D:\Users\gizmo\Documents\mbed\mbed-os-example-blinky):
No local configuration is set

パソコンに繋がっているmbedボードの検出

mbedボード(今回はNucleo F446RE)をUSBでパソコンに繋ぎ、確認します。

PS D:\Users\gizmo\Documents\mbed\mbed-os-example-blinky> mbed detect

[mbed] Detected NUCLEO_F446RE, port COM4, mounted I:, interface version 0221:
[mbed] Supported toolchains for NUCLEO_F446RE
+---------------+-----------+-----------+-----------+-----------+-----------+
| Target        | mbed OS 2 | mbed OS 5 |    ARM    |  GCC_ARM  |    IAR    |
+---------------+-----------+-----------+-----------+-----------+-----------+
| NUCLEO_F446RE | Supported | Supported | Supported | Supported | Supported |
+---------------+-----------+-----------+-----------+-----------+-----------+
Supported targets: 1
Supported toolchains: 3

コンパイル


PS D:\Users\gizmo\Documents\mbed\mbed-os-example-blinky> mbed compile -t GCC_ARM -m NUCLEO_F446RE
Building project mbed-os-example-blinky (NUCLEO_F446RE, GCC_ARM)
Scan: .
Scan: mbed
Scan: env
Compile [  0.2%]: mbed_tz_context.c
<中略>
Compile [100.0%]: test_env.cpp
Link: mbed-os-example-blinky
Elf2Bin: mbed-os-example-blinky
+------------------+-------+-------+------+
| Module           | .text | .data | .bss |
+------------------+-------+-------+------+
| [fill]           |   119 |     4 |   14 |
| [lib]\c.a        | 24641 |  2472 |   56 |
| [lib]\gcc.a      |  3168 |     0 |    0 |
| [lib]\misc       |   252 |    16 |   28 |
| main.o           |    68 |     4 |   28 |
| mbed-os\drivers  |   192 |     4 |  100 |
| mbed-os\hal      |  1653 |     4 |   68 |
| mbed-os\platform |  2764 |   260 |  133 |
| mbed-os\rtos     |  8498 |   168 | 6073 |
| mbed-os\targets  |  8583 |     4 |  552 |
| Subtotals        | 49938 |  2936 | 7052 |
+------------------+-------+-------+------+
Total Static RAM memory (data + bss): 9988 bytes
Total Flash memory (text + data): 52874 bytes

Image: .\BUILD\NUCLEO_F446RE\GCC_ARM\mbed-os-example-blinky.bin

出来上がった「.\BUILD\NUCLEO_F446RE\GCC_ARM\mbed-os-example-blinky.bin」をオンラインコンパイラと同じようにNucleoF446REのフォルダにDrag&Dropすれば実行されます。

<追記:2018.09.20>

コマンドラインに「-f」オプションを付けると、compile後、自動的にパソコンにつないでいるTarget Boardにバイナリが書き込まれます。


> mbed compile -t GCC_ARM -m NUCLEO_F446RE -f

</追記>

プロジェクトの新規作成

Lチカ・プログラムを新規作成します。プログラム名はblink2としてExampleより素早くチカチカするようにしました。

空のプロジェクトを作成します。

PS D:\Users\gizmo\Documents\mbed> mbed new blink2
[mbed] Creating new program "blink2" (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> cd blink2

PS D:\Users\gizmo\Documents\mbed\blink2> mbed config --list
[mbed] Global config:
GCC_ARM_PATH=D:\GNU Tools ARM Embedded\6.2 2016q4\bin

[mbed] Local config (D:\Users\gizmo\Documents\mbed\blink2):
No local configuration is set

main.cppを作成

#include "mbed.h"

DigitalOut led1(LED1);

// main() runs in its own thread in the OS
int main() {
    while (true) {
        led1 = !led1;
        wait(0.1);
        led1 = !led1;
  wait(0.1);
    }
}

ファイルの確認

PS D:\Users\gizmo\Documents\mbed\blink2> ls


    ディレクトリ: D:\Users\gizmo\Documents\mbed\blink2


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2018/08/26     14:58                mbed-os
-a----       2018/08/26     14:59              8 .mbed
-a----       2018/08/26     15:00            215 main.cpp
-a----       2018/08/26     14:59             78 mbed-os.lib
-a----       2018/08/26     14:59           1469 mbed_settings.py

コンパイル

PS D:\Users\gizmo\Documents\mbed\blink2> mbed compile -t GCC_ARM -m NUCLEO_F446RE
Building project blink2 (NUCLEO_F446RE, GCC_ARM)
Scan: .
Scan: mbed
Scan: env
Compile [  0.2%]: mbed_tz_context.c
<中略>
Compile [100.0%]: test_env.cpp
Link: blink2
Elf2Bin: blink2
+------------------+-------+-------+------+
| Module           | .text | .data | .bss |
+------------------+-------+-------+------+
| [fill]           |    87 |     4 |   14 |
| [lib]\c.a        | 24641 |  2472 |   56 |
| [lib]\gcc.a      |  3168 |     0 |    0 |
| [lib]\misc       |   252 |    16 |   28 |
| main.o           |   100 |     4 |   28 |
| mbed-os\drivers  |   192 |     4 |  100 |
| mbed-os\hal      |  1653 |     4 |   68 |
| mbed-os\platform |  2764 |   260 |  133 |
| mbed-os\rtos     |  8498 |   168 | 6073 |
| mbed-os\targets  |  8583 |     4 |  552 |
| Subtotals        | 49938 |  2936 | 7052 |
+------------------+-------+-------+------+
Total Static RAM memory (data + bss): 9988 bytes
Total Flash memory (text + data): 52874 bytes

Image: .\BUILD\NUCLEO_F446RE\GCC_ARM\blink2.bin

出来上がった「.\BUILD\NUCLEO_F446RE\GCC_ARM\blink2.bin」をDrag&Dropです。

複数のプロジェクトを管理

下記のドキュメントを参考にすれば、mbed-osをダウンロードする時間とディスクスペースを節約できそうです。

「Managing multiple Mbed projects」