part.2 Renesas RA MCU
GPIOでLED制御

目的

Renesas RAファミリビギナーズガイドのサンプルコード(Chapter.8)を利用してEK-RA6M4評価基板のGPIO(LED1,2,3)を制御し、
GPIOの基本操作についての理解を進める。
また付属のLEDだけでなく、P611ポート(Arudino D8)に外部のLED回路を追加し、基板付属のLEDと外部LEDを点灯することも検討する。

全体フロー

  • 検討(1)  LED2,3 交互点滅
  • 検討(2)  LED1,2,3 BCD点滅
  • 検討(3)  LED1,2,3/外部LED BCD点滅

準備

  • ルネサスRAファミリビギナーズガイド
    RAシリーズを初めて触るビギナーが読むべき入門書という位置づけ。本編で説明しているHelloWorldに相当するLED Blinkyサンプルプログラムだけでなく、FSPによる割り込み処理や今では広く使われているRTOSであるFreeRTOSなど、RAで組み込みをするなら一度は目にしておいたほうがよい内容が書かれている。
    本編はChapter.8の内容と以下のサンプルコードを利用する。
    https://www.renesas.com/jp/ja/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ra-book#document
  • RA Family Beginner’s Guide Example Projects (サンプルコード)
    アーカイブにはビギナーズガイドで説明している各チャプターのプロジェクトとソースコードが含まれている。

  • (Optional) ブレッドボード/330Ω リード抵抗/リードLED/ジャンパーケーブル
    評価基板のみで済む検討(1), (2)までであれば不要。検討(3)ではコネクタ経由でGPIOを制御しているので、検討(3)で確認する場合は
    用意する。

本編

検討(1) LED2,3 交互点滅

サンプルプロジェクト インポート

ダウンロードしたRA Family Beginner’s Guide Example Projectsのアーカイブ(210313_RA-Book_ExampleProjects_FSP-2-3-0.zip)
を展開する。
すると各チャプターのサンプルプロジェクトが含まれるアーカイブが展開されるので、その中にある「RA-Book_Solution_Chapter8.zip」を
適当なフォルダに展開する。

e2studioを起動しメニューから「ファイル → インポート」を選択すると以下のダイアログが開くので、ルートディレクトリの選択に
{zip展開先フォルダ}\RA-Book_Solution_Chapter8」を指定する。
プロジェクトのボックスに「MyBlinkyProject」が表示されることを確認したら、終了ボタンをクリックする。

コンフィギュレーション / プロジェクト ビルド / プログラム書き込み

インポートが完了すると、プロジェクト・エクスプローラにMyBlinkProjectのプロジェクトが生成される。
コンフィギュレーションから自動生成ファイルを生成するため、configuration.xmlを開く。

このサンプルプロジェクトはFSP V2.3.0なので、対応バージョンが入っていないと標準のFSP V4.0.0が選択される。
特に影響はないので、そのままOKを押して先に進む。


特に編集する箇所はないので、右上のGenerate Project Contentをクリックする。

自動生成ファイルが生成されれば、そのままビルドすることが可能。ただ、デフォルトのプロジェクト設定だとビルドした後に生成されるプログラムはELF形式となり、J-Flash Liteで使用できるIntel HEX形式が生成されない。そのため、プロジェクトの設定を一部変更する。

プロジェクトを右クリックしてメニューから「C/C++ Project Settings」を選択する。

左メニューから「C/C++ ビルド / 設定」、タブは「ツール設定」を選び、さらに「GNU ARM Cross Create Flash Image / General
を選択する。
Output file formatという欄はビルド後に出力するファイル形式が選択できるので、デフォルトの「Motorora S-record」から「Intel HEX」に
変更する。

設定が完了したら、画面左上のビルドアイコンをクリックしてプロジェクトをビルドする。

正常終了するとコンソールウィンドウには、「MyBlinkyProject.elf」と「MyBLinkyProject.hex」が生成されたことを
示すメッセージが表示される。

ここまで完了したら、J-Flash Liteを起動し、Data Fileに
{workspaceフォルダ}\MyBlinkyProject\Debug\MyBlinkyProject.hexを指定して、PCを接続したEK-RA6M4評価基板にプログラム
を書き込む。Logに「Done.」が表示されたら書き込みは成功。

書き込み完了した後のサンプルプログラムの動作は以下の通り。LED2, LED3が1秒間隔で交互に点滅する様子がわかる。

検討(2) LED1,2,3 BCD点滅

Chapter.8の内容はLED2,3の交互点滅だが、評価ボードにはLED2,3だけでなくLED1も実装されている。
Chapter.8のコードを修正し、0から7の値をBCD表現することでLED1,2,3を点滅させようというのが本検討となる。

MyBlinkyProject\src\下にあるfile:hal_entry.cを開いて、関数:hal_entry()の内容を変更する。

file:hal_entry.cの変更内容は以下の赤字で示す箇所となる。

for文で変数selを0から7までインクリメントし、if文で各LEDに対応したbit値(LED1:0x1 LED2:0x2: LED3:0x4)が変数selに含まれていれば
led_level変数にBSP_IO_LEVEL_HIGHまたはBSP_IO_LEVEL_LOWと代入する。
関数:g_ioport.p_api->pinWrite()
の第3引数にBSP_IO_LEVEL_HIGHが設定されれば第2引数で指定したLEDは点灯、BSP_IO_LEVEL_LOW
であれば消灯となる。

点滅のタイミングを早めるため、関数:R_BSP_SoftwareDelayに500msを指定した。

void hal_entry(void)
{
   unsigned char sel = 0;
   extern bsp_leds_t g_bsp_leds;
   bsp_leds_t Leds = g_bsp_leds;
   bsp_io_level_t led_level;

   while (1)
   {
       for(sel=0; sel<8; sel++){ 

           /* LED1 turn on or off */ 
           led_level = (sel & 0x01) ? BSP_IO_LEVEL_HIGH : BSP_IO_LEVEL_LOW; 
           g_ioport.p_api->pinWrite(&g_ioport_ctrl, Leds.p_leds[BSP_LED_LED1], led_level);

           /* LED2 turn on or off */
           led_level = (sel & 0x02) ? BSP_IO_LEVEL_HIGH : BSP_IO_LEVEL_LOW;
           g_ioport.p_api->pinWrite(&g_ioport_ctrl, Leds.p_leds[BSP_LED_LED2], led_level);

           /* LED3 turn on or off */
           led_level = (sel & 0x04) ? BSP_IO_LEVEL_HIGH : BSP_IO_LEVEL_LOW;
           g_ioport.p_api->pinWrite(&g_ioport_ctrl, Leds.p_leds[BSP_LED_LED3], led_level);

           /* wait for 500ms */
           R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS);
       }
   }

#if BSP_TZ_SECURE_BUILD
   /* Enter non-secure code */
   R_BSP_NonSecureEnter();
#endif
}

変更したコードを再ビルドし評価基板に書き込むと、以下のようにBCD表記でLED1,2,3が500ms間隔で点滅する様子が確認できる。

検討(3) LED1,2,3/外部LED BCD点滅

評価基板のLED1,2,3に加え、外部コネクタにLED回路を接続して1byte分(4bit)の表示をおこなう。

評価基板にはArduino互換のピン配列のコネクタ(J18/J19/J23/J24)が実装されており、ここではArduio D8に相当するP611ポートに
LED回路を接続することとした。

接続するLED回路は330Ωの抵抗とLED(黄色)の直列回路となる。回路は単純なので、検討の際はブレッドボードを使用している。

同じくfile:hal_entry.c関数:hal_entry()に赤字の部分を追加、修正する。4bit分の表示なので、sel関数の入力範囲は0から15に修正する。

P611
のGPIOを制御するため、関数:pinWrite()の第2引数には#define宣言されているBSP_IO_PORT_06_PIN_11を指定している。
なお、上記の#defineが宣言されているfile:ra/fsp/src/bsp/mcu/all/bsp_io.hには、他のGPIOのピンの#define宣言も用意されているので、
他のプロジェクトでGPIOを制御する場合は参照するとよい。

file:hal_entry.c

void hal_entry(void)
{
   unsigned char sel = 0;
   extern bsp_leds_t g_bsp_leds;
   bsp_leds_t Leds = g_bsp_leds;
   bsp_io_level_t led_level;

   while (1)
   {
       for(sel=0; sel<16; sel++){ 

           /* LED1 turn on or off */ 
           led_level = (sel & 0x01) ? BSP_IO_LEVEL_HIGH : BSP_IO_LEVEL_LOW; 
           g_ioport.p_api->pinWrite(&g_ioport_ctrl, Leds.p_leds[BSP_LED_LED1], led_level);

           /* LED2 turn on or off */
           led_level = (sel & 0x02) ? BSP_IO_LEVEL_HIGH : BSP_IO_LEVEL_LOW;
           g_ioport.p_api->pinWrite(&g_ioport_ctrl, Leds.p_leds[BSP_LED_LED2], led_level);

           /* LED3 turn on or off */
           led_level = (sel & 0x04) ? BSP_IO_LEVEL_HIGH : BSP_IO_LEVEL_LOW;
           g_ioport.p_api->pinWrite(&g_ioport_ctrl, Leds.p_leds[BSP_LED_LED3], led_level);

           /* arduino D8 (P611) turn on or off */
           led_level = (sel & 0x08) ? BSP_IO_LEVEL_HIGH : BSP_IO_LEVEL_LOW;
           g_ioport.p_api->pinWrite(&g_ioport_ctrl, BSP_IO_PORT_06_PIN_11, led_level);

           /* wait for one second */
           R_BSP_SoftwareDelay(200, BSP_DELAY_UNITS_MILLISECONDS);
       }
   }

#if BSP_TZ_SECURE_BUILD
   /* Enter non-secure code */
   R_BSP_NonSecureEnter();
#endif
}
file:ra/fsp/src/bsp/mcu/all/bsp_io.h

 ...
typedef enum e_bsp_io_port_pin_t
{
    BSP_IO_PORT_00_PIN_00 = 0x0000, ///< IO port 0 pin 0
    BSP_IO_PORT_00_PIN_01 = 0x0001, ///< IO port 0 pin 1
    BSP_IO_PORT_00_PIN_02 = 0x0002, ///< IO port 0 pin 2
    BSP_IO_PORT_00_PIN_03 = 0x0003, ///< IO port 0 pin 3
...
    BSP_IO_PORT_06_PIN_11 = 0x060B, ///< IO port 6 pin 11
...
}

ちなみにpinWrite()の引数をBSP_IO_PORT_06_PIN_11の代わりにARDUINO_D8に置き換えることが可能である。

これはコンフィギュレーションのPinsの設定より、P611のSynbolic Nameには「ARDUINO_D8」と定義されているためである。
これによって自動生成ファイルのfile:ra_cfg/fsp_cfg/bsp/bsp_pin_cfg.hにはBSP_IO_PORT_06_PIN_11のリネームとして
ARDUINO_D8の#define宣言がおこなわれる。

注: Arduinoのコネクタで指定する各ピンのSynbolic NameにはP611のようにArduinoに関連した名前が定義されているので、
評価基板のArduinoコネクタを利用する場合は他のポートの設定を参照しておくとよい。

file:ra_cfg/fsp_cfg/bsp/bsp_pin_cfg.h

...
#define ARDUINO_D8 (BSP_IO_PORT_06_PIN_11)
...

最後にLED1,2,3と外部LEDのBCD点滅させて本編は終了とする。