RL78/G13でI2Cを使ってみる

最近アマゾンで、Arduino向けデバイスが格安で入手できる、中華製で、品質は
それなりではあるけれども、値段が恐ろしく安い。(送料も大抵無料)
評価欄で、低評価をしてる人がいて笑ってしまうのだが、こんだけ安くて、何が不満な
のだろうか?
部品を正規ルートで買って組み立てたら10倍以上の値段になるだろうか・・
「当り」、「はずれ」は当然として、不満なら正規品を買えば良いだけの事と思うのだ
が・・
※スイッチサイエンスや、ストロベリーリナックスで、同じような「製品」は入手でき
る、その場合のコストを考えてほしいと思う。

-----
さて、シリアル入出力は、割り込みにも対応できて、機能的にはとりあえず十分なので
何か外にデバイスを接続したくなる。
RL78/G13には、SAU(シリアル・アレイ・ユニット)を簡易I2Cとして使
う機能があるが、他に、IICA(I2Cアレイ)が1チャネルあり、I2Cの仕様を
全て満足する事が出来るので、当然ながら、こちらを使う事になる。

ハードウェアーマニュアルを読んでも、イマイチ使い方がピンとこなかったが、以前に
R8Cで、I2Cをソフトウェアーだけで実現した経験があったので、それが役立った、
出来上がってみると、R8Cで実装した構成とほぼ同じようになった。
新規のデバイスを使うのは、困難が伴う、I2Cは動作が複雑なのでなおさらだ。
ハードウェアー・マニュアルの不備などに悩まされ、ルネサスさんのサンプルコードも
参考にして、ようやく動作した。
まだ、ポーリング動作なので、遅いI2Cは、割り込みにする必要があるのだけど。
※R8CのソフトウェアーI2Cもフル機能がある。

構成が複雑化してくると、バイナリーが肥大化してきた、これを解消する為、このプロ
ジェクトから、最適化オプション「-O2」を「-Os」とした。
これは、「-O2」から、バイナリサイズが大きくなる可能性のある最適化オプションを取
り除いたもので、サイズはかなり縮小する。
※おおよそ1/4になった。

使ったデバイスは、DS3231で、RTCだ、このモジュールは中華製で、危険なほど
安い!(確か220円とかだった)
このRTCは、OSCの発振周波数が非常に正確なのが特徴で、普通にチップだけ買って
も500円はするが、このモジュールは、バッテリーバックアップ、それにEEPROM
まで付いている。

IMG_0804s

DS3231サンプル・プロジェクト

RL78/G13のスタートアップルーチン修正

const 領域の問題が解決したと思って、コンパイラに含む問題は解決されたと
思っていたのだが、何だか、動作が怪しい・・・

少し調べると、クラスの初期化リストが正しく動いていないように感じた。

xxxx.lst を見ながら、xxxx.mot ファイルのバイナリーを色々調査すると、明
らかに呼ばれていない関数がある事が判った。

00004c96 <__GLOBAL__sub_I__Z5wait_v>:

このアドレス「0x00004c96」は、どうやら、「.ctor」に積まれているようだ。

今まで、スタティックに定義したクラスのコンストラクターは、

extern void rl78_run_preinit_array(void);
extern void rl78_run_init_array(void);
extern void rl78_run_fini_array(void);

の3つを走らせれば良いのだと思っていたが、どうやら、「ctor」に積まれた
アドレスもコールしておく必要があるようだ・・

そこで、リンカースクリプトに「ctor」、「dtor」リストのシンボルを追加して、
「start.s」に関数を呼ぶエントリーを追加、「init.c」から呼ぶようにしてみ
た。
※どの順番で呼ぶのか不明なので、ctor を最初に呼ぶようにした。
※ctor、dtor のエントリーアドレスを得る方法が判らないので、シンボル追加。
この「無理やり」な解決方法が合っているか不明ではあるけど・・・

とりあえず、初期化が正しく行われ、正常に動作しているようだ。

まだまだ、スタートアップの方法に問題を含んでいるのかもしれない・・・

ここは、時間が出来たら、もう少し厳密な調査をしたい。

RL78/G13でインターバルタイマーを使ってみる。

RL78も、UARTが動作し始めた事で、佳境に入った感が出て来た。

とりあえず、現在使ってみた感想を述べてみる~
・バイナリーは、R8Cより少なくなる感じではあるけど、基本内部は8ビット構成な
ので、16ビットや32ビットを扱うと、肥大化は免れない。
・ミラー領域のおかげで、64K領域を超えた場合も、ある程度普通に扱う事が出来る。
・32MHzで動作するので、速度面でもかなり有利に感じる。
・RL78/G13は、コアは「S-2」なので、掛け算や割り算命令は無いものの、
外部に「乗除積和算器」があり、コンパイラオプション「-mmul=g13」で、コンパイラ
はこのリソースを使う為、それなりの速度で動作する。
※但し、割り込みルーチン内で使う場合には注意を要すると思われる。
・トータルメモリーのサイズから考えると、コストパフォーマンスに優れている。
・消費電力が非常に小さい。

いつもは、LED点滅の後くらいに、インターバルタイマーを実装するけど、RL78
のインターバルタイマーは、1ユニットで、12ビットレンジ、低速で、シンプルすぎ
るので、イマイチ意欲が沸かなかったが、必要な機能ではあるので、粛々と実装した、
動いた。

ただ、残念なのは、カウンターの値を読み出す事が出来ないので、正確なタイマーを実
装したい場合などに使えない。

単に設定したインターバルを待つだけのものでしか無い。

-----

ついでなので、ソフトディレイも実装した。
RL78/G13では、32MHz動作なので、より細かい単位も可能だけど、とりあえ
ず良く使うだろう、1uS(1マイクロ秒)単位の関数にした、これは、R8Cと同じ仕
様。
最初、アセンブラは、覚えなくても良いとか言ってたけど、結局、なんだかんだで、覚え
る必要が出てきて、ソフトウェアーマニュアルを読む事になった・・・

void micro_second(uint16_t us)
{    
    while(us > 0) {
        --us;
    }
}

上のようなコードは、最適化(-O2)して、以下のように展開される

(2) decw    0xffef0
(1) movw    ax, 0xffef0
(1) cmpw    ax, #0
(1) skz
(3) br      !!4922 <.L629>

最適化されても、ワークメモリーが使われているが、マシンサイクルから考えると、なる
ほど、ペナルティーは意外と少ない。
RL78のような、アーキュムレーターが基本のCPUでは、レジスターだけに割り振る
コードを出すのは難しいのかもしれない・・
※()内がマシンサイクル

この結果を考慮して、全体で32クロックになるように「nop」命令を置く。

・次のコードで実験してみた。

    while(1) {
        utils::delay::micro_second(10);
        P4.B3 = !P4.B3();
    }

10uS毎にポートを変化させてみた。
IMG_0802s
大体合ってる~

インターバルタイマーソースコード

RL78/G13でUARTを使ってみる

暇をみて、I/O関係の定義を粛々と実装しているけど、まずはシリアル通信だろう~
※I/Oポートの定義は実装した。

早速、SAU(シリアル・アレイ・ユニット)の定義を作った。
RXマイコンやR8Cのハードウェアーマニュアルでは、レジスター名の命名は、規則的
で、一貫性があり、作りやすいのだけど、RL78は、一貫性が無く、ハードウェアー
マニュアルと乖離しないように、考えながら実装しないと駄目な感じで疲れる。
※R8Cは、多少古いので、部分的に微妙な部分もあるけど・・

例えば、I/Oポート:
「P1」はP1グループ(P10~P17)を指す。
「P10」は、「P1」ポートの「0」ビットなんだけど・・・
P10グループ(P100~P107)のポートも同時に存在する為、「当たる」・・・
従って、ビット指定の令名はプログラム上から行えない。
なので、「P1.B0」とするようにした、これは、RXやR8Cもそうしているので、
問題ないけど・・、何でそうなるの?、作った人って何考えてるか・・・

I/Oポートでそんな感じだから、他も、かなり酷い、でもまぁ仕方無い、なるべく、
ハードウェアーマニュアルの記述を取り込むように、考えながら実装してみた。

それで、早速UART0を使った、送信、受信のクラスを書いてみた。

RXともR8Cとも違う構成のレジスター郡で、RL78はNEC系なんだと思うが、
理解と動作するまでに、それなりに時間がかかった・・・

文字列を出力する簡単なプログラムが、思ったように動作しない事が主な原因だった。
※この問題は、「RL78のミラー領域」で詳細を解説してある。

とりあえず、ポーリングによる実装のみしてあり、これから、割り込みを使った物や
DMAを使った実装を行いたい。

追記:
割り込みを使った実装を行った、以前に書いた、R8C用のコードをほぼそのまま
使ったが、問題無く動作する。
この辺り、C++は、再利用性が高い、これは、実装段階で、再利用を考えながら
ハードの依存を極力減らして書いている事が大きいのだけど・・・

DMAは、転送量があまり多く無いシリアル通信の為に使うと、もったいない気が
する、SDカードの読み書き、LCDへの転送など、転送量が多いデバイス用に確
保する方が良いと思った、また、DMAでは、結局、同期を取ったり、その他の部
分のマネージメントが色々ありそうなので、とりあえず保留とする事にした。

-----
RL78内蔵の「シリアル・アレイ・ユニット」は、このデバイスでは、2ユニット
、6チャネルの通信回路が使えて、UART回線なら3回線を同時に使える。

「G13/sau.hpp、common/uart_io.hpp」テンプレートでは、これを扱えるように工夫
してある。
RL78/G13 では、シリアル通信は、偶数チャネルで送信動作、奇数チャネルで受信動
作を行う為、送信チャネル、受信チャネルを別々に指定する。
※制限もあるので、複数チャネルを使う場合には注意が必要。

UART0を宣言する場合は以下のようにする。
※現在は使われていないが、送信バッファと受信バッファの大きさを指定する。

    device::uart_io<device::SAU00, device::SAU01, 128, 128> uart0_io_;

他のチャネルは動作テストはしていないけど、同じように扱う事が出来ると思う。

    device::uart_io<device::SAU02, device::SAU03, 128, 128> uart1_io_;
    device::uart_io<device::SAU10, device::SAU11, 128, 128> uart2_io_;

UART の簡単なテスト

IMG_0800s

-----
フラッシュへのプログラムと、UARTとの通信では、共に、RxD,TxDなどを
使う、これらの切り替えを出来るように、2回路のスイッチを設けて、書き込み回路
もテスト基板に追加した。
※書き込み器は、デバイスの「/RESET」信号を制御するので、「RTS」信号を必要とす
る。

RL78_Flash_UART

RL78/G13のミラー領域

UARTの実装を行っている過程で、文字列を出力する簡単なプログラムが、思ったよう
に動作しないで、随分悩んだ・・・

調べると、ミラー領域に関する認識が甘かったようで、データフラッシュ領域と当たって
いた事が判った。

8/16ビットマイコンでは、ポインターは16ビットサイズで、基本64キロバイトの
領域しかダイナミックにアクセス出来ない。

RL78では、物理的なメモリー空間は1Mバイト(64Kが16ページ)ある。
プログラム領域は、0番地から始まり、128Kバイト品(R5F100LGAFB)の場合、
0x1FFFFまで使える。

RAM領域は、128キロバイト品の場合、12キロバイトあり、0xFCF00から
始まる。

データフラッシュは128キロバイト品の場合、8キロバイトあり、0xF1000
から0xF2FFFまである。
※64キロバイト品では、半分の4キロバイト

RL78のgccでは、R/Wアクセスする領域は、常に0xF0000~
0xFFFFFをベースとしていて、RAM領域をベースにアクセスするようになって
いる。
ここで問題になるのが、プログラム領域に置かれた読み出し専用データのアクセスとなる。
RL78では、「ミラー領域」を使ってこれを解決していて、RAM領域、
データフラッシュ領域以外は、ROM領域のアクセスと同等となる
仕組みがある。

ここで、以前に修正したリンカースクリプトが問題となった・・・

 .rodata (MAX(__romdatastart + __romdatacopysize, 0x2000)) : {

この「0x2000」のオフセットが何なのか、判ってなかった為、これを無効
(0x0000)としていた・・・
※0x2000の領域が「空く」のは勿体無い・・

当然、「0x0000」にすると、文字列データは、先頭から配置される為、テストして
いたプログラムでは、0x2000以下の領域に配置される、ミラー領域では、このエリ
アは、データフラッシュ領域の為、0xF1000~0xF1FFFがアクセスされてい
た。
それには、途中で気がついて、オフセットを0x2000に戻したが、それでも、直らな
い、良く調べると、128KB品は、データフラッシュが倍の8Kバイトあり、
0xF1000~0xF2FFFまでとなっていた。
そこで、オフセットを「0x3000」とする事で、解決した。

 .rodata (MAX(__romdatastart + __romdatacopysize, 0x3000)) : {

※リンカースクリプトは修正済みでプッシュしてある。

つまり文字列などの固定データは、0x3000以降、0xCF00までに置く必要があ
る。
まぁ、このくらいの領域があれば、当面困る事は無いと思われる。

先頭の空いた領域には、「.lowtext」セクションが割り当ててあるので、ここには、割り込
みルーチンなどを優先的に配置するのが良さそうだと思う。
※割り込みルーチンは、ベクターが16ビット固定なので、必ず64K以内に配置する必要
がある。

また、64K以降のエリアへは、「__far」を使う事で、ポインターを32ビット扱いとして
アクセスする事も出来るが、C++ ではこのキーワードを上手く扱えないようで、悩んでる。
※とりあえず、Cの関数だけで操作するしか無い。

Cの関数宣言では、ポインターが32ビット扱いになり、逆アセンブルリストを観た感じでは
ESレジスター付き20ビットでアクセスするコードになっている。

「コード」の呼び出しは、20ビット対応の「call」命令が使われているので、全域に対して
アクセスでき、64Kの壁を意識する必要は無いようだ。

 12c:   fc be 32 00        call    !!32be <_main>

※コードが64Kを超えて伸びていっても問題は無いと思われる。

-----
RL78は、Z80のようだと思ったら、実際Z80(78K0)がベースのようだwww

※昔、ゲームボーイのプログラムで、Z80のアセンブラを随分扱ったので、馴染みがある。
でも、32MHzで動くZ80となると、かなり話が違う。

プログラムでプログラムを生成する

最近、RL78用のデバイス定義ファイル生成用のプログラムを実装している。

sed、grep、awk、perl、などなど、スクリプトを駆使しても良いが、C++ では、
文字列の処理もかなり、柔軟に書けるので、制限が多いスクリプトはあまり使わ
なくなった。

基本的な流れとしては、必要最低限の表現で記述された定義ファイルを読み込ん
で、それから、C++ のコードを生成するもの。
もう一つは、テキスト化されたファイル(元は PDF )から、フィルターを駆使し
て、必要な部分を抜き出して、定義ファイルを作成する事。

しかし、PDF をテキスト化する過程の制限や、キーワードを自動で「抜く」のは難
しい事が判った。
この部分は、しばらくは手作業で行う事になる・・・
また、RL78、M32C、RX のハードウェアーマニュアルの違いで、一律では出来ない。

-----

それでも、以前に比べれば、冗長な記述を長い時間をかけて、だらだら書くのに比べ
れば、非常に軽減され、ミスも少なくなった。
そして、構成を変えるのも苦にならない、単純に、プログラムを修正して作りなおす
だけなので。

定義ファイルは、JSON とか使えば良いだろうと思うかもしれないが、以前から、もっ
と軽量な物を模索していたので、一度、自分で書いてみる事にした。
もちろん、XML は、史上最悪なフォーマットである事は言うまでもない、これを有難が
る人がいる事に、驚くばかりである、疫病のように世間に広まってしまっているけど・・

実装してみると、以外と奥が深く、色々な書き方に柔軟に対応するのは難しい事が判っ
た。
以前に、自分のアプリ用にプリファレンスを読み書きするクラスを書いたけど、これは、
人間が編集する事を前提としていないのと、構造が今回とは違う物なので、採用しなか
った。

定義ファイルはこんな感じで書く:

base {
    .title     "RL78/G13 グループ・ポート・レジスター定義",
               "Copyright 2016 Kunihito Hiramatsu"
    .author    "平松邦仁 (hira@rvf-rc45.net)"
    .file      "common/io_utils.hpp"
    .space     "device"
}

reg {
    .title     "クロック動作モード制御レジスタ(CMC)",
               "リセット時:00H"
    .base      "rw8_t"
    .address   "0xFFFA0"
    .name      "CMC"

    bit {
        .title  "高速システム・クロック端子の動作モード"
        .def    7, 1
        .name   EXCLK
    }
}

変換すると、以下のように C++ コードを作る~

#pragma once
//=====================================================================//
/*! @file
    @brief  RL78/G13 グループ・ポート・レジスター定義 @n
            Copyright 2016 Kunihito Hiramatsu
    @author 平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "common/io_utils.hpp"

namespace device {

    /// @brief CMC レジスタ定義
    typedef rw8_t<0xFFFA0> cmc_rw;
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    /*!
        @brief  クロック動作モード制御レジスタ(CMC) @n
                リセット時:00H
    */
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    struct cmc_rw_t : public cmc_rw {
        using cmc_rw::operator =;
        using cmc_rw::operator ();
        using cmc_rw::operator |=;
        using cmc_rw::operator &=;

        bit_rw_t<cmc_rw, 7> EXCLK;    ///< 高速システム・クロック端子の動作モード
    };
    static cmc_rw_t CMC;
}

これらの処理を簡潔に行う為に、色々なユーティリティ-を実装したが、その一つが、
「text_edit」クラスで、この実装で、エディターで行うような操作をプログラムから
行う事が出来るようになった。
まだ、通常のエディターが備えている機能には程遠いので、これから、ボチボチ機能を
追加したい。
この実装、設計は、なかなか楽しい!

これらソースコード一式は、GitHub にある。
iod_make

RL78/G13スタートアップルーチンと起動テスト

フラッシュへの書き込みプログラムを先に作ろうと思ったけど、まず、動かしてみない
事には始まらない~

gcc はビルドしてあるので、スタートアップルーチンを作って起動するまでの道を作る。

(1)まず、リンカースクリプトを精査する。

/usr/local/rl78-elf/rl78-elf/lib/rl78.ld

を雛形にして改造すれば良さそうだ~
※標準のリンカースクリプトは、RL78/G13 (Flash:64K / RAM:4K) 仕様のようだ。
このリンカースクリプトを参考に、4つのデバイス用を作成
※オリジナルでは、0x0000 ~ 0x1FFF までは、開発用のブート領域のようで、使わない
ので、それを無効にした。

    .rodata (MAX(__romdatastart + __romdatacopysize, 0x2000)) : {

    .rodata (MAX(__romdatastart + __romdatacopysize, 0x0000)) : {

追記:
この0x2000は、ミラー領域内で、データフラッシュ領域をバイパスするオフセットで、
重要な事が判明、又、128KB、256KB品では、データフラッシュ領域は、倍なので、
オフセットを0x3000にする必要がある・・

※「ミラー領域」の事が良く判ってなかった・・・

また、ハードウェアーベクターセクションに多少の問題がある。

  .vec :
  {
    *(.vec)
  } > VEC

通常、ハードウェアーベクターはソフトウェアーからは参照されないので、何もしないと、
最適化で、省かれてしまう・・・

  .vec :
  {
    KEEP(*(.vec))
  } > VEC

そこで、「KEEP」キーワードで囲む必要がある。
※「ivec」(割り込みベクターテーブル)も同じ。

また、各種デバイス用に、ROM、RAM の開始アドレス、長さなど設定して、4つのデバイス用
リンカースクリプトを作成した。

R5F100LCAFB:   32K (0x00000 - 0x07FFF) /  2K (0xFF700 - 0xFFEFF) / 4K (0xF1000 - 0xF1FFF)
R5F100LEAFB:   64K (0x00000 - 0x0FFFF) /  4K (0xFEF00 - 0xFFEFF) / 4K (0xF1000 - 0xF1FFF)
R5F100LGAFB:  128K (0x00000 - 0x1FFFF) / 12K (0xFCF00 - 0xFFEFF) / 8K (0xF1000 - 0xF2FFF)
R5F100LJAFB:  256K (0x00000 - 0x3FFFF) / 20K (0xFAF00 - 0xFFEFF) / 8K (0xF1000 - 0xF2FFF)

RL78/G13リンカースクリプト
※データフラッシュ領域は記述が無いので、何らかの対応を行う必要があると思う。

(2)次にスタートアップルーチン
今までは、独自に、スタックをセットするとか、アセンブラで書いたのだけど、ライブラリー
に含まれる標準のスタートアップオブジェクト「crt0.o」を、objdump でアセンブルソースを
出力して、参考にする方法が確実で簡単な事が判った。

rl78-elf-objdump -h -S crt0.o > crt0.lst

※これなら、まねるだけなので、アセンブラを詳細に理解する必要がほぼ無い。
※最低限の知識は必要だが、手本があれば、非常に簡単だ。
「crt0.o」は、以下の構成のようだ。

・ハードウェアースタックの設定
※スタックの開始アドレスは、リンカースクリプトで指定されたラベルを使う、また、
スタックの深さは、リンカースクリプトで指示する。(通常は、RAM 領域の最後から取る)
・ROM 領域から RAM 領域への転送
※定数などを読み書き可能な変数として設定している場合は、変数はRAM上に配置されるの
で、初期値をコピーしておく必要がある。
・.bss セクションのクリア
・C++ コンストラクター呼び出し
※rl78_run_preinit_array()、rl78_run_init_array()、rl78_run_fini_array()
※C++ では、main が始まる前にコンストラクターを走らせて、初期化しておく必要性がある。
・init 関数呼び出し
・main 関数呼び出し
・exit 関数呼び出し

とりあえず、適等に切り貼りして、「start.s」を作成。
呼び出し部は、「init.c」で実行。
最後に、リセットベクターに、start.sの開始アドレスを指示する必要がある。「vect.c」

const void* vec_[] __attribute__ ((section (".vec"))) = {
    start,
};

これで、全て準備が整った、後は、自分のプログラムをコンパイルして、先に作ったプログラムを
リンクするだけで起動するはず。

-nostartfiles    ----->    標準のスタートファイルを使わない
-T xxxxx    ----->    xxxxx のリンカースクリプトを使う

リンカーオプションでは、以上の二つが重要となる。

(3)LED点滅を書いて、実行してみる・・
以上で、main 関数が実行される準備が整った。
今回、LEDを接続するポートとして、P43を使った。
最初、LEDは点灯したままだったが、無効ループが短すぎたようだ、そこで、以下のように無効
ループの回数を増やした。
※「int」型は16ビットなので、「uint32_t」を使った。

int main(int argc, char* argv[])
{
    device::PM4.B3 = 0;  // output

    bool f = false;
    while(1) {
        for(uint32_t i = 0; i < 100000; ++i) {
	    asm("nop");
        }
        device::P4.B3 = f;
        f = !f;
    }
}

※無効ループ内では、「asm("nop")」を実行する、そうしないと最適化で、ループ自体が無くな
ってしまう。

これで、無事にLEDの点滅まで出来た。

プロジェクト全体のソースコードは、GitHub に全てある、

  cd FIRST_test
  make

で、実行バイナリー、「first_sample.mot」が出来るので、これを、「Flash Programmer」でデバイス
に書き込む。
※書き込み後、リセットが有効になっているので、書き込み機のリセットラインをオフラインにする
必要がある。

IMG_0798s

RL78を始める~ gcc の構築から~

R8C/M120 は確かにコスパが高く、パッケージも手頃で、良いのだけど、RAM容量が少なく、もう少しだけリッチなマイコンが欲しいと思っていたのだった・・・
※メモリーはせめて2Kバイトくらいは欲しい、128×64のビットマップLCDとかを扱う場合、フレームメモリーで1Kバイト消費するし、SDカードでファイルを扱う場合も、バッファ
がある程度必要だし・・

現在の自分の環境では、R8C の上位は、いきなり RX になってしまう、まぁそれはそれで良いのかもしれないけど、RX では高機能過ぎるし、デバイスが少しコスト高なので、AVR 328 くらいのデバイスも扱えれば良いなぁーって思っていた。

R8C/M120 の上位を使えば、もう少し話は早いけど、R8C 系は、既に古いデバイスで、上位のデバイスは割安感が無い、そこで、やはりと言うか、RL78 に落ち着く訳だけど、値段、デバイスの種類、機能など、バランスが良い事に改めて気づく。
ただ、自作で使っている人は少ないのか、製作記時は少ないようだ・・
※パッケージが基本、フラットパッケージのみなので敬遠されているのかもしれない。

何故、ARM を選択しないのかと思うかもしれないが、日本人だからルネサスを使うだけの事で、少し意地になっているかもしれないけど、ルネサスのラインナップは豊富だし、入手性も良く、値段もこなれていて安定している、マニュアルも日本語なので、開発のハードルは低いと感じている。
逆に、「日本人」なのに、何故海外製のマイコンに走るのか、聞いてみたい。
※ AVR は随分使ったけど、マイクロチップに買収されてしまったしなぁ・・

RL78 のラインナップは凄まじく多くて、どれを使うか非常に迷うけど、入手性と値段で、「G13」グループをとりあえず選択してみた。
「秋月電子」で安く購入出来る。

プログラムフラッシュ/RAM/データフラッシュ
・R5F100LCAFB:  32K/ 2K/4K @250円
・R5F100LEAFB:  64K/ 4K/4K @290円
・R5F100LGAFB: 128K/12K/8K @340円
・R5F100LJAFB: 256K/20K/8K @400円
・R5F100LGAFB搭載変換モジュール     @420円

早速、290円、340円を数個購入してみた、後で気がついたけど、340円のデバイスが、変換基板にハンダ付けされたタイプが420円で売られていた、これは安い!
※0.5mmピッチのハンダ付けはコツがいるので、自信の無い人は、モジュールを選べば良いだろう~
IMG_0795s
※変換基板にピンを立てて、ソケット化すると、交換が出来て便利ではあるけど、ソケットのコストが痛いので、このような安いデバイスは、直で、ユニバーサル基板に乗せている。

まず gcc を構築してみた、以前に R8C、RX で行った方法がそのまま使える。
※ gcc-4.9.3 を使った。
詳しい方法は、以下のリンクを参照して欲しい。
My GitHub RL78

次に、フラッシュプログラミング環境を整える。
最初、シリアルポートで簡単に接続出来ると思ったのだが、ドキュメントを読むと、多少の付加回路が必要な事が判った。
RL78 には、プログラミング時の専用端子「TOOL0」があり、「/RESET」のタイミングで、通信を行う事で、プログラミングモードに移行する。
※通常動作では、抵抗を介してプルダウンしておく。

・「ルネサスの参考回路」
リンクの参考回路(タイプB)では、トライステートバッファ(オープンドレインゲートとして利用)と、インバーターを使っている、少し考えて、トライステートをダイオードで置き換え、
インバーターをNチャネルのFETで置き換え、簡易回路を作成してみた。
RL78_FlashProgrammer
※自分が使った部品は、3.3V~5Vの環境に対応している、電圧降下が少ないショットキーダイオードを使ったが、リークの少ない物を使用している。
※/RESET のプルアップ抵抗は、デバイスに直接取り付けてあるので、省く。

※同じような変換回路を既に製作していた~ 「簡易UART書き込み器」

RL78/G13のデバイスは電源が少なくて、配線が楽だ!
・Vss、Vdd、EVss、EVddに0.1uFのパスコンを付け電源に接続する。
・REGCは0.47~1uFのコンデンサでVssに接続する。
※1uFを選択した。

IMG_0796s

とりあえず、「ルネサスの Flash Programmer 」と接続して、認識できる事を確認出来た。
※3.3Vの電源を接続

今回はここまで・・
次は、書き込みプログラムを実装してみようと思う。(MacBook で使いたい!)

LEDライト購入と、中華クオリティー再び~

LEDライトは、色々持ってるけど、凄く明るいのは持って無かった・・
それと、18650リチウムイオン電池で使うタイプが欲しかったのだけど、アマゾンで、以下の物を見つけて、購入してみたー

WOLFTEETH 4005N ズーム機能付き ズーム 超明るい LED 1200Lm LED 懐中電灯 ハンディライト ハンドライト  フラッシュライト 【2x18650電池 USB充電器】 ブラック

以下のようなセット内容・・・
Light18650

2200mAだけど、リチウムイオン電池が2本付いて、充電器も付いてるので、1988円は、お得かなと思って買った~

ライトは、凄く明るく、ズーム機能があったりで、値段の割に(ライトだけだと1178円)納得の物だったが・・・

がしかし・・・

流石な中華クオリティー、充電器は偽者だった・・・

そもそも、この充電器、充電ランプも無いし、かなり怪しい物だったが・・・

「USB充電器」とあるので、素直に、付属のケーブルを繋いでみたが、電池が熱くなり、USBアダプターの保護回路が働いたようだった。
中がどうなってるのか気になって、分解してみると、(予想はしてたけど・・)単なる電池ボックスで、丸ミニプラグに「直」で繋がってるだけだった(怒)
多分、専用の充電アダプターを繋げる物なのだけど、肝心の充電アダプターは入っていないので、普通の人は、そのままUSBに繋げると思う。

まぁ、中華とはそんな物だなとも思い、先日購入した、リチウムイオン充電モジュール(190円)を繋いで、充電できるようにしてみた。

HiLetgo 5V 1A 18650 リチウムバッテリー チャージボード Micro USB チャージモジュール プロテクト [並行輸入品]
参考回路

まぁ、これも中華なんだけどね・・・

IMG_0791s

・充電電流は1Aに設定されており、PCのUSBからの給電では駄目で、1A以上の電流が流せる、アダプターからの給電が必要。
・いくつかのリチウム電池を充電してみたが、問題なく充電出来る、1Aだと、充電ICはかなり熱くなるが、まぁ問題ないレベルと思うが、ケースに入れる場合には、基板の放熱を考慮した方が良いだろう~
・このモジュールには、他に、電池を外部と分離するFETスイッチが付いているようで、設定された電圧よりリチウムイオン電池の電圧が下がると、OFFになる機構が付いているので、過放電の保護にも。
TP4056 (A Standalone Linear Li-lon Battery Charger with Thermal)
DW01A (One Cell Lithium-ion/Polymer Battery Protection)

「電池ボックスの憂鬱」
充電する場合、意外と盲点になりやすいのが、「電池ボックスの仕様」だ!
上記の充電モジュールは、1Aの電流を流す事が出来るものだけど、良く売られている電池ボックスでは、接触力が弱く、接触抵抗が不安定なので、
1Aの電流を、安定して流す事は出来ない。(接触抵抗が安定せず、充電電圧が変動してしまい、正しい充電が行えない場合がある)
今回、付属の「電池ボックス」は、バネのテンションがそこそこ強く、1Aでも、ギリギリ使えそうではある。

俺俺 RX マイコンボードを作ろう!(その2)

以前、RX630Nで始めた、RXマイコンボード開発・・
途中、R8Cに注力してた事もあり、頓挫してました。
それと、例のピッチがズレた、秋月製、変換ボードの事もあり、あやふやな状態になっていました・・・
IMG_0665s

そんなこんなで、気分をリセットして、もう一度始めようかと思ってたら、RX64Mがオンライ
ンになっていました。
「RX71M」を待つってゆー選択もアリですがー、そんな事言ってたら、いつまでたっても始ま
らないのは明白なので、賞味期限が切れないうちにチャッチャと始めようと思います。

RX64M、2Mバイトフラッシュ版は、チップ1ストップで、2000円くらいです。
それに、内臓RAMは512Kバイト(+32K+8K)もあり、120MHz動作で、RXv2
コアで、パフォーマンスが高いです~
値段は、RX63Nに比べると少しは高いのですが、色々考えた末、RX64Mで作りなおす事に
しました。
IMG_0784s
※10個買うと、@1600円で、送料無料なので、10個買いました・・
※10個なら、トレイに入ってくると思ったので、それも動機になってます。
※チップ単体で欲しい方は、実費でお分けします。(1600+消費税+送料)

そして、変換基板は、アイテムラボさんの基板を使ってみました。
この基板、490円で、安くて、品質が高いです、169ピンでも極限まで小さくしているのも
良いです!
※送料が無料になるオーバー3000円分、他の基板も色々買ってしまいました。

いつも多少苦労する、0.5mmピッチのハンダ付け、今まで、大きな失敗は無いですが、視力
が落ちている事もあり、失敗すると、チップも変換基板も無駄になるのでストレスがかかる作業
です。
やり方は色々だと思いますが、自分の方法を簡単に書いておきます。
・最初に、チップを正確にパッドに乗せて、ルーペで良く観て、少しでもズレていたら妥協せず、
確実に中心に置く。
・プリント基板用フラックスをまんべんなく端子に塗り、とりあえず、1ピンだけハンダ付け。
・その状態でズレがないか再度確認。
・対角線上のもう1ピンを半田付け。(2点付けると、もうやり直しはほとんど出来ないので注意)
・隅の8点を、付けて、全体をハンダ付けしていく。(ハンダが多すぎるとブリッジするので、
少なめに、足りない場合は、少しコテ先にハンダを乗せて、塗ったフラックスに頼って流す感じ)
・ブリッジしたら、フラックスを塗って、コテ先で、こするように再加熱すると、意外と綺麗に
取れる。(パッケージの根元のピンにコテ先が触れて、ブリッジすると取れにくいので注意)
・それでも、ブリッジが取れない場合は、吸い取り腺を使うが、少しだけ呼び水的にハンダを
吸い取り腺にも溶かしておくと良い。
・吸い取り腺でハンダを除く場合、限度を超えて長い時間熱しないように注意する。
・ルーペで斜めから確認して、パッドと、ピンの「きわ」にハンダが流れているかを3度くらい
確認。
・もし「怪しい」ピンを見つけたら、フラックスを塗って、再度ハンダを流す。
・全て確認して、大丈夫と思ったら、パーツクリーナーなどで洗浄して、エアーダスターで、
ゴミなどを飛ばす。
・最後に、綺麗になった基板を、もう一度ルーペで確認して、問題無ければ終了!

IMG_0786s

この基板は、スルホールが裏にあるので、基板を直付けする場合、ショートするかもしれない
ので、絶縁しておきます。
最近は、ピンヘッダーは使わなくなっています、意外とコストがかかるのと、外して、別基板
で使う可能性が低い事(新規にデバイスを付けた方が安上がり)、高さが邪魔になるとか、色
々な事を考えて、大きい基板に直付けしています。

と、ゆー事で、今回はここまで。

Just another WordPress site