「電子工作な日々」カテゴリーアーカイブ

電子工作に関連するお話など・・

18650リチウムイオンセル

去年くらいに、18650タイプのリチウムイオンセルを複数購入していた。

img_0876s

モバイルバッテリーを自作したかったのが主な理由だったが、大きな電流を流
す場合、電池ボックスでは、接触抵抗が大きくて駄目なのがハッキリしている。
そこで、スポット溶接機を自作する予定で、部品を集めだしたが、面倒になっ
て、伸び伸びになっている・・・

最近、YouTube を観ていたら、「eBay Fake 18650 cell」関連の動画がかなり
眼に止まり、以前に買ったセルの容量を確認しておく必要があるだろうと思い
たった。
Fake ebay batteries 18650
※中国には、「Fake USB Memory」など、巧妙に騙してお金を稼ぐ商売が普通に
あり、注意(安いだけの事はある)しなければならない、恐ろしい国だ・・・
酷いセルは、中に砂が詰められているだけの物もある~

そこで、フル充電を行ったセルで、放電を行い、容量を確認してみた。

※充電には、TP4056を使った中華のリチウム・イオン・バッテリー・
チャージャー・モジュール(110円)。
img_0878s
このモジュールは、1A程度で充電が行え、バッテリーの過放電保護、インジケ
ーターLEDなども付いている優れ物だ。
充電中は「赤」、充電完了で「青」
普通に考えて、これだけの物を110円で作る事は到底不可能だ・・・

※放電試験には、「PERFECT NEO」を使い、0.5Aで放電を行った。
img_0882s
このマルチチャージャー、ディスチャージャーは、機能が豊富。
※リチウムイオン電池に表示されている容量は、定電流で放電を行い、終始
電圧になった時の積算時間から決めているようだ。
当然、内部抵抗はそれなりにあるので、放電レートを大きくする程、みかけ
の容量は小さくなってしまう。
一般には、0.2C(2500mAhのセルで500mA)程度で試験する
ようだ。
また、終始電圧は2.75V前後のようだが、通常の運用では、セルの寿命
を考えた場合、3V程度にする方が良さそうで、その場合、容量は若干少な
くなる。

(1)SANYO UR18650A: 3.6V 2250mA
(2.75V)実測:41g(規格表の値:43g)
・Amazonで購入(@635円)
最終電圧:2.9V、236:41 (2003mA)※これは問題無し!

(2)ICR 18650: 3.7V、2200mA
(2.75V)、実測:42g
※マイナス側に「UltraFire」の刻印があるが、保護回路は内臓さ
れていないようだ。
・Amazonで購入(@400円)
6番セル(仮名)
最終電圧:2.9V、175:22 (1510mAh)※不良か?
※このセルは6本買ったが、どれも、容量が大幅に小さく、Fakeを掴ま
されたようだ・・・(涙)

(3)Li-ion 18650 3.7V、2600mA(プルタブ付)
47g
・Yahooオークションで購入(@420円)
最終電圧:2.9V、286:16 (2453mAh)※問題無し!

-----
自作機器に使う場合は、プルタブが付いている方が便利なので、ノートPC
用のバッテリーパック(新古)を購入して、分解してセルを取り出した方が
良いのではと思っている。
オークションでは、そのような分解セルを購入する事もできる。

-----
通常、購入時には、保管に適した(50%充電)状態で来る、この時、電圧
は3.8V前後となっており、それが、著しく低い場合などは、セルの不良
が考えられる。
※ICRの6番セルがそれにあたる。

RXマイコン用スタートアップのバグ

今まで、RXマイコンで、挙動が怪しい事があって、その原因が判らなかったが、
やっと判明した・・・

症状としては、
・スタックに配置した変数が書き換わる場合
・割り込みが多重に起動するような場合に多く発生
・多重じゃなくても割り込み関連が絡む場合など

どうもスタックが壊れている感じではあるけど、プログラムを追っても、問題無
さそう・・・

RXマイコンでは、スタックは、割り込み用スタック(ISP)と、ユーザース
タック(USP)に分かれていて、起動時、「start.s」のアセンブラプログラム
で設定されている。
ISPをメモリーの後半に置き、その手前にUSPを設定している。
当初、ISPの容量は32バイトくらいしか無かったので、256バイトにした
が、症状に変化は無い・・・

    .text
    .global  _start
    .type    _start,@function
_start:

# スタックの設定(SP:__stack、USP:__stack - 128)
    mov.l       #__stack, r0
    mvtc        r0, isp
    sub         #128,r0
    mvtc        r0, usp

ソフトウェアーマニュアルを読み直していたら、何と「R0」レジスタと「SP」
は扱いが同一となっていた!

汎用レジスタ R0 には、汎用レジスタとしての機能に加えて、スタックポインタ
(SP)としての機能が割り当てられています。

あ!、「R0」は使ったら駄目なんだ・・・・・・・・・

そこで、単純に、レジスタ名を変更

    .text
    .global  _start
    .type    _start,@function
_start:

# スタックの設定(SP:__stack、USP:__stack - 128)
    mov.l       #__stack, r5
    mvtc        r5, isp
    sub         #128,r5
    mvtc        r5, usp

この修正後、今までのおかしな挙動が直った。

今まで、結構大きなプログラムを動かしていたけど、よく動いてたなぁ・・・

経験的に、レジスターセットの後ろ(R15とか)にSPを置いてあるのが普通と
思っていたから、何も考えずに、R0を使ったのが間違いだった・・・
※ソフトウェアーマニュアルを良く読まなかったのが悪いのだけど・・・

-----
RXマイコンでは、スーパーバイザーモードとユーザーモードのRUNレベルがあり、
通常はユーザーモードで動作させる。

ユーザーモードで特権命令を実行すると、「特権違反例外」が発生する。

ユーザーモードに移行するには、「rte」命令などを実行した場合に、退避してあった
ステータスレジスターを復帰するが、その際、ユーザーモードフラグが有効になって
いれば、ユーザーモードに移行する為、以下のような、少しキワドイプログラムで移
行する。

# PMレジスタを設定し、ユーザモードに移行する、ユーザースタックに切り替わる
    mvfc    psw,r1
    or      #0x00100000, r1
    push.l  r1

# UレジスタをセットするためにRTE命令を実行する
    mvfc    pc,r1
    add	    #10,r1
    push.l  r1
    rte
    nop

※PCにオフセットを加える事で、RTE命令の下に復帰する。

RX64MにSDRAMを接続する

ようやく、SDRAMのテストを開始、結線は多いが、高速な大容量外部
メモリを得られる。
デバイスだけでも512Kバイトのメモリーを持っているので、通常は十
分ではあるけど、このようなデバイスじゃないと、SDRAMを制御する
為のハードウェアーを内臓していない、又、169ピンのデバイスじゃな
いと、32ビットの外部バスをサポートしていない。
※最大のパフォーマンスを得たいので32ビットバスで動かしてみたい。

普通は、基板を起こすべきなのだろうけど、実験ではそうもいかない。
と、言っても最近では、海外のメーカーに発注すれば、基板を新規に作成
するコストは尋常じゃ無く安いので、いきなり基板を起こしてみるのも悪
くないかもしれない。

クロックが高いので、手配線では動作が難しいかもしれないが、バスに接
続するSDRAMは、CPUの動作速度の半分でしかないので、(およそ
60MHz)このくらいなら、手配線でも何とか動作すると思う。
「反射」が起こって動作が不安定になった場合は、ダンピング抵抗を調整
してインピーダンスの整合を行えば、何とかなるのでは無いかと考えてい
る。
※変換基板では、電源ラインが相対的に弱くなるのが多少気になる。

デバイスは300円(128メガビット)なのに、変換基板(Aitendo 産)
が250円するけど、他に、収まりが良く、スペースが少ない変換基板が
無かった。
img_0867s
※基板を起こす時には256メガビット品を使うと思うが、組み込み用途
のSDRAMを単体で入手(秋葉原などで)できるのは限られている。

最近は、0.5mmピッチのハンダ付けが多かったので、0.8mmピッ
チは、凄く楽だったーー
変換基板には、何故か余分な部分があるので、カットして、裏面にある謎
の端子パッドも、いつものようにポリイミドテープで絶縁、ベース基板と
直接コンタクトさせる。
img_0870s
※ピン番号のシルクが一部間違っている・・(28、29ではなく、27、
28ね・・)
※ポリイミドテープの存在を知らない時は、「紙」を貼っていた。www

まず、電源ラインを配線してから、十分なパスコンを接続、それから配線
を行った、データバスは、液晶を接続するのにも使うので、別途、コネク
ターに出す。
・電源の配線
img_0871s

参考回路(ルネサスのRX64Mボードの例)
rx64m_sdram

厄介なのは、SDRAMの場合、初期化処理を行わないと、使う事ができな
い点で、それなりのパラメーターがある、とりあえず、ベストな設定より、
必ず動作しそうな無難な設定を考えてみた。
後は、SDRAMのマニュアルと、RX64Mのマニュアルを見ながら、行
い、とりあえず、書いたデータを読み出せた~
※もっと苦労すると思っていたので、意外な感じはあるが、メモリー空間は
32メガバイトもあるので、詳細なテストを行わないと、分からない。

バス・インターフェースの初期化

    // SDRAM 初期化 128M/32bits bus
    device::MPC::PFAOE0 = 0xff;  // A8 to A15
    device::MPC::PFBCR0 = device::MPC::PFBCR0.ADRLE.b(1) |
                          device::MPC::PFBCR0.DHE.b(1) |
                          device::MPC::PFBCR0.DH32E.b(1);
    device::MPC::PFBCR1 = device::MPC::PFBCR1.MDSDE.b(1) |
                          device::MPC::PFBCR1.DQM1E.b(1) |
                          device::MPC::PFBCR1.SDCLKE.b(1);
    device::SYSTEM::SYSCR0 = device::SYSTEM::SYSCR0.KEY.b(0x5A) |
                             device::SYSTEM::SYSCR0.ROME.b(1) |
                             device::SYSTEM::SYSCR0.EXBE.b(1);
    while(device::SYSTEM::SYSCR0.EXBE() == 0) asm("nop");

SDRAM の初期化

    device::BUS::SDIR = device::BUS::SDIR.ARFI.b(0) |
                        device::BUS::SDIR.ARFC.b(1) |
                        device::BUS::SDIR.PRC.b(0);
    device::BUS::SDICR = device::BUS::SDICR.INIRQ.b(1);  // 初期化シーケンス開始
    while(device::BUS::SDSR() != 0) asm("nop");
    // 動作許可、32ビットアクセス
    device::BUS::SDCCR = device::BUS::SDCCR.BSIZE.b(1);
    // Burst read and burst write, CAS latency: 3, Burst type: Sequential, Burst length: 1
    device::BUS::SDMOD = 0b00000000110000;
    // CAS latency: 3, Write recovery: 1, ROW prechage: 4, RAS latency: 3, RAS active: 4
    device::BUS::SDTR = device::BUS::SDTR.CL.b(3) |
                        device::BUS::SDTR.RP.b(3) |
                        device::BUS::SDTR.RCD.b(2) |
                        device::BUS::SDTR.RAS.b(3);
    // 128M/16 カラム9ビット、ロウ12ビット
    device::BUS::SDADR = device::BUS::SDADR.MXC.b(1);
    // Refresh cycle
    device::BUS::SDRFCR = device::BUS::SDRFCR.RFC.b(2048) |
                          device::BUS::SDRFCR.REFW.b(7);
    device::BUS::SDRFEN = device::BUS::SDRFEN.RFEN.b(1);
    // SDRAM 動作開始
    device::BUS::SDCCR.EXENB = 1;

img_0872s

SDRAM サンプル

ADP2503/ADP2504 降圧、昇圧DC/DCコンバーター

充電池で動く機器を作るのに便利なDC/DCコンバーターの実験をした。

CPUの電源電圧が3.3Vだと、3.7Vのリチウムイオン電池から電源供給する
には、微妙だ。
シリーズレギュレーターだと、3.5V程度までしか使えない(電圧降下が0.2V)
かといって、降圧のDC/DCでは、3.3V以上の電圧がある場合には使えない。

そんな用途に使いやすい、降圧、昇圧を自動で切り替える事ができる、デュアルトポロ
ジーのDC/DCコンバーターがある。
adp2503

DC/DCの大手はリニアテクノロジーと思うけど、数量が少ない場合は、コストが高
く、気軽に使えない場合が多い。
そんな時、アナログデバイセズの製品が目に留まった。
※電圧固定(3.3V、5V)と、抵抗で任意(最大5.5V)の電圧を生成できるタ
イプがある。

単価は300円くらい(10個だと230円くらい)とまぁまぁで、パッケージがQF
Nなのが痛い(割高だがSOPもある)が、先日購入していた。
2503と2504の違いは取り出せる電流が違い、単価は数十円違う。
購入した時は、2504を5個と、2503のSOPバージョンを1個買ったつもりが、
両方共QFNを注文してしまい、長い間実験出来なかった。

昨日、QFNの変換基板を買ってきたので、ADP2503(600mA)を実験して
みた。
QFNのハンダ付けは、毎回、苦労する。

img_0864s
コテライザーの先端にブロワーを付けてQFNのハンダ付けに利用している。

img_0865s
今回は使わなかったが、1000mAを取り出せるADP2504、そのうち専用基板
を作る予定。

img_0860s
実験に使用したADP2503をユニバーサル基板に組んだ状態。
※スイッチング周波数が高い為、チョークコイルは1.5uHと小さい。
※VRefは0.5Vなので、3.3Vを得る為のネットワークは、168Kと30K
とした。(168Kは100Kと68Kを直列とした)
分圧抵抗の計算ツール
※マニュアルでは、合計が400K程度になるようにと書いてあったが、手持ちの都合
で、上記の組み合わせとした。(問題無いと思われる)
取り出す電流が小さい場合、間欠モードを選べるが、このモード中は、多少高い電圧と
なるようだ・・・

※18650のリチウムイオン電池は、プルタブ付の物をオークションで購入した。

img_0866s
リチウムイオン充電モジュール
※リチウム電池の電圧が3V程度になると、パワースイッチで切り離されるようになって
いて、電池の深い放電を防止する。
中華製で110円(激安)

RX24TでLCD表示と、各種LCD

部品の整理をしていたところ、色々なLCDが出てきた。
img_0858s
※安売りでバーゲンしてる時に買ったもの。

RX24Tには、まだ液晶を接続していなかったので、RX24Tで実験してみた。

赤い基板と横長の基板は、ST7565で、小さいのは、UC1701、白い枠は、
カラーTFT液晶。
横長は、モノ128×32、他はモノ128×64、カラーは128×160となって
いる。

どのLCDも、SPIで通信するものだけど、ピンアサインが、どれも微妙に異な
る・・・
また、基本的には、電源は3.3Vだけど、バックライト用電源が異なるモジュー
ルがある。(Aitendo さん何で同じにしないかなぁ・・・)

以前に買ったLCDで、LCDの不良(仕様違い)で、使わなくなっていたやつを
交換してきた、メールで問い合わせたら、返金すると言っていたが、同等品があった
ので、交換にした。
img_0862s
このLCDは大型でバックライトもあり、なかなか良い。

同じコントローラーでもLCDによりコントラストの設定が異なるのが、多少厄介。

img_0863s
※周囲が暗いけど、小さめの赤い基板のLCD、液晶の応答速度が若干速い気がする。

img_0859s
※さらに小型のLCD(バックライト付)で、コントローラーがUC1701

他にもあるが、どれも表示は問題無くできる。

    // SPI 定義(RSPI0)
    typedef device::rspi_io<device::RSPI0> SPI;
    SPI spi_;

    typedef device::PORT<device::PORT6, device::bitpos::B1> LCD_SEL;    ///< LCD 選択信号
    typedef device::PORT<device::PORT6, device::bitpos::B2> LCD_A0;     ///< LCD レジスター選択

#ifdef LCD_ST7565
    // ST7565 drive
    chip::ST7565<SPI, LCD_SEL, LCD_A0> lcd_(spi_);
#endif
#ifdef LCD_UC1701
    // UC1701 drive
    chip::UC1701<SPI, LCD_SEL, LCD_A0> lcd_(spi_);
#endif

「LCD_SEL」はLCDの選択信号
「LCD_A0」は、LCDの制御レジスター切り替え

LCDの切り替えは、インスタンスを代える事で行う。
「spi_」は、SPIを制御するクラスで、コンストラクター時、参照で受け取るよう
にしてある為、SPI の制御をシェア可能になっている。

LCDのコントラストは、LCDのスタート時に(初期化)設定する。

    lcd_.start(0x00);

※大きいタイプは0x10程度、他は、0x00くらいだった。(LCDにより調整
が必要なようだ)

RX24T、LCDサンプル

R8C関係、テンプレートライブラリのアップデート

R8C、RL78、RXマイコンと、実装を重ねた結果、色々と新しい試み(
判りやすさ、正確性、共有性、性能)が導入されて、昔に実装した、R8C関
係のテンプレートライブラリの完成度が相対的に低下している状況となってい
る。

ここらで、最新の実装方法を、R8Cにも反映するべく、アップデートを大々
的に行った。
この改修は、I2Cや、SPIデバイスの制御クラスを全てのプラットホーム
で共有する為の準備でもある。
また、デバイスのフラッシュ書き込み関係プログラムも改修を行った。

I2C、SPIインターフェースの完成度が低いので、その辺りも、RL78
やRXと同等な実装に切り替えた。

かなり大掛かりな手術となったが、一応完成した、これで、各プラットホーム
で、外部デバイスを共有する事が出来ると思う。

-----

以前にアマゾンで、LEDドライバー、マキシム社のMAX7219を買った。
MAX7219 7セグLED×8

部品単体で買っても1000円する(これは、高すぎるが・・)ので、とても
CPが高い。
一般的に、多数のLEDを接続するには、ポートや、電流容量の問題で、ドラ
イバーを入れなくてはならないので、それが簡単に接続できる。
ただし、電源は5Vなので、3.3Vのデバイスに接続するには、別途電源が
必要と思う。
そこで、電源電圧が自由に選べるR8C/M120ANで、5Vで駆動により、
接続実験を行った。

img_0857s

輝度をプログラム出来るとか、電流制限抵抗が少ない、デージーチェインできる
、ダイナミックスキャンが行われているなど、かなりユニークなデバイスで、取
り扱いが簡潔で良い。(少量でも安ければ良いのだけど・・・)

MAX7219サンプル

MAX7219制御クラス

BMP180/BMP280圧力センサー

最近、BMP280が、安く購入出来る事を知り、早速購入、実験してみた。
アマゾンで230円だった。
※湿度も計測できる、BME280は、まだ高価なようだ・・(@540)

BMP280は、BMP180の後継で、色々な部分が改善されているようだ、ただ、
温度や気圧を得る為のシーケンスは、BMP180とは異なる為、新規に実装する必要
がある。
今後は、BMP180はBMP280に置き換わるものと思われる。
※現状では、BMP280の方が安く入手できる。

BMP180とBMP280の主な違い:

Parameter:               BMP180                 BMP280
Footprint:               3.6 × 3.8 mm           2.0 × 2.5 mm
Minimum VDD:             1.80 V                 1.71 V
Minimum VDDIO:           1.62 V                 1.20 V
Current consumption:     12 μA                  2.7 μA
(@3Pa RMS noise)
RMS Noise:               3 Pa                   1.3 Pa
Pressure resolution:     1 Pa                   0.16Pa
Temperature resolution:  0.1°C                  0.01°C
Interfaces:              I²C                    I²C & SPI (3 and 4 wire, mode ‘00’ and ‘11’)
Measurement modes:       Only P or T, forced    P&T, forced or periodic
Measurement rate:        up to 120 Hz           up to 157 Hz
Filter options:          None                   Five bandwidths

早速、BMP280用にテンプレートクラスを実装して、動作実験を行った。
ここで、BMP180とインターフェースを合わせる為、BMP180の実装も見直した。
BMP180では、温度は0.1度単位で出力されるが、BMP280では、0.01度
までの分解能がある。
なるべく、小規模なマイコンなどで使う事を考えて、浮動小数点を使わないようにしたの
で、以前のインターフェースでは、10倍した整数で、温度を取得するようにしていたが
これを100倍とした。
圧力(ヘクトパスカル)は、元々100倍された値だったのでそのまま使った。
BMP280では、さらに小数点以下8ビットも有効のようだったが、センサの分解能か
ら考えて、必要ないと思ったので、捨てている。
圧力から、高度を求めるAPIは、std::pow を使うので、R8C版では、容量の関係で、
コンパイルは出来るものの、容量オーバーで、リンクに失敗する。
RL78でも問題無く機能するものの、バイナリーは64キロを超える。
※RXでは13キロ程度に収まる。

-----

補正などのソースコードはネットにあるソースを参考にしたけど、どうも、初期設定の
デバイスの動作モード設定に誤りがあるようで、データシートを読んで(観て)設定データ
としたが、それが正しいのか微妙ではある、データを1秒間隔で出力させると、それらしい
データを出力している。
※立川の高度は100mくらいのハズなので、かなり違うが、天気によりそれなりに変
化すると思うので、スルーしている。
※一応、圧力の補正ルーチンは確認しているが、特に間違いは無いと思える。

Bosh のデータシートには「filter」に関する説明が不十分なように思う・・・
※とりあえず、「Filter:16」の設定として、0b100としている。

BMP280 初期化コードの一部

    // Ex: Ultra high resolution
    // setting control
    // osrs_t(X2): 010, osrs_p(X16): 101, mode(Normal): 11
    uint8_t mode = 0b010'000'00 | 0b000'101'00 | 0b000'000'11;
    write8_(REG::CONTROL, mode);

    // setting config
    // t_sb(0.5ms): 000, filter(16): 100, xxx(0): 0, spi3w_en(0): 0
    uint8_t conf = 0b000'000'0'0 | 0b000'100'0'0 | 0b000'000'0'0 | 0b000'000'0'0;
    write8_(REG::CONFIG, conf);

img_0856s

Temperature: 19.51 C
Pressure: 1005.85 hPa
Altitude:   61.79 m
Temperature: 19.51 C
Pressure: 1005.86 hPa
Altitude:   61.71 m
Temperature: 19.51 C
Pressure: 1005.87 hPa
Altitude:   61.63 m
Temperature: 19.51 C
Pressure: 1005.87 hPa
Altitude:   61.63 m

BMP180/BMP280 サンプル

RX24TでA/D変換テスト

RX24Tは、モーター制御がターゲットだからか、A/D変換関係が、もの
凄く充実した(細かい)造りになっている。
変換時間は1マイクロ秒で、12ビットの精度があり、5チャンネルが2ユニ
ット、12チャネルが1ユニット、計22チャンネルと豪華で、付随する機能
も豊富で複雑だ。

流石、インバーター制御用なので、サンプルホールド回路が複数あったり、
ゲインを制御する機構があったり、モーター制御に必要な機構を網羅している
ようではある。
変換結果を受け取るレジスターも、個別になっているので、変換したいチャネ
ルを選んで、変換を開始するだけで、マネージメントも簡単で、処理負荷も少
なくてすむ。

とりあえず、単に変換するだけの機能を実装してテストしてみた。
他の変換モードは、必要になったら、適宜追加していくようにしたい。
ただ、テンプレートの定義は、複雑だったので、それなりに苦労した。
なるべく、3つのモジュールを同じように扱う事が出来るように工夫した。

チャネルの扱いをどのように扱うか、色々悩んだが、結局、各モジュールの定
義内に、「enum class」を使って、チャネル定義を行った。

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
    @brief  S12AD1 定義
    @param[in]	base	ベース・アドレス
    @param[in]	t		ペリフェラル型
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
template <uint32_t base, peripheral t>
struct s12ad1_t : public s12ad_t {

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    /*!
        @brief  アナログ入力型
    */
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    enum class analog : uint8_t {
        AIN100,
        AIN101,
        AIN102,
        AIN103,
        AIN116 = 0x10,
    };
.
.
.
};
typedef s12ad1_t<0x00089200, peripheral::S12AD1> S12AD1;

ユニット0、1は、チャネル5本で、5番目は、16番から開始する為、定数を16
としている、この値を使ってレジスターアクセスのオフセットとしている。
※ただ、こうすると、ループを回して、設定するような事が出来なくなるのが、痛い
が、アナログチャネルは、通常全て同一に使う事は少ないので、「良し」とする。

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
    @brief  S12AD2 定義
    @param[in]	base	ベース・アドレス
    @param[in]	t		ペリフェラル型
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
template <uint32_t base, peripheral t>
struct s12ad2_t : public s12ad_t {

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    /*!
        @brief  アナログ入力型
    */
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    enum class analog : uint8_t {
        AIN200,
        AIN201,
        AIN202,
        AIN203,
        AIN204,
        AIN205,
        AIN206,
        AIN207,
        AIN208,
        AIN209,
        AIN210,
        AIN211,
    };
.
.
.
};
typedef s12ad2_t<0x00089400, peripheral::S12AD2> S12AD2;

変換時間は1マイクロ秒と短い時間ではあるけど、80MHzのCPUの場合
では、変換開始から変換終了を待つのでは、十分な実装とは言えないので、割
り込み処理は実装してあり、変換終了時に、何かタスクを実行できるような仕
様としてあるが、どこまで実用的かは多少疑問が残る。
結局、リアルタイムカーネルのようなマルチタスクシステムにしないと真価を
発揮出来ないかもしれない。

RX24TのA/Dユニットの構成は、他のRXマイコンと比較して、汎用的
では無いため、変換操作を行う具体的なクラス「adc_io」は個別に定義した。
RX64Mや、RX63Tでは、別に定義する必要がある。

A/D 変換サンプル

RX24TでSDカードの読み書き

RX24TにもSDカードを接続してみた。

ほとんどは、RL78のリソースを使ったものの、FatFS を ff12b と最新の
実装を使った。
また、なるべく、固有のハードウェアー設定を追い出して、ハードの依存を
少なくする仕組みを整えた。

RX24Tには、専用のSPIチャネル(RSPI0)が1つだけあるので、
SDカードに割り当てた。
SDカードを扱うと、このチャネルはほぼ占有されてしまうと思うので、他
とのシェアをあまり考えなくてもも良いと思うが、一応、それも可能に出来る
ようにはしてある。

img_0855s

新規に作成したUSBシリアルコンバーターから、電源を取っているのだけど、
SDカードをマウントすると、USBシリアルデバイスが不安定になる現象が
起こった、これは、SDカードマウント時に大きな電流が流れ、電圧効果が大
きいのだろう、そこで、解消の為、USBシリアルモジュール側に47uFの
コンデンサを追加した、(22uFくらいで十分だと思うが、手持ちが無かっ
た)これで、安定的に動作するようになった。
念のため、RX24T側にも10uFのコンデンサを足した。

簡単なベンチマークを行った。
※サンプルのSDカードは、Transcend の8GB
※RX24Tでは、SPIの最大クロックは20MHzとなっている。

RX24T:
SD Speed test start...
SD Write test...
Write frame: 460
Write: 136770 Bytes/Sec
Write: 133 KBytes/Sec
SD Read test...
Read frame: 133
Read: 473041 Bytes/Sec
Read: 461 KBytes/Sec

RL78/G13:
SD Write test...
Write frame: 541
Write: 116293 Bytes/Sec
Write: 113 KBytes/Sec
SD Speed test start...
SD Read test...
Read frame: 180
Read: 349525 Bytes/Sec
Read: 341 KBytes/Sec

※書き込み速度は、あまり変化は無いが、読み込み速度はかなり改善している。
※RL78では、SPIのクロックは16MHzだったので、その分と、CPU
の処理能力の違いと思える。

-----

ポートを1ビット単位で定義できるようなクラスを実装した、これはRL78
でも同じようなクラスを実装したけど、より汎用的な仕様にした。

定義の仕方は、RL78とほぼ同じだが、ポートの指定は、テンプレートクラス名とした。

    typedef device::PORT<device::PORT6, device::bitpos::B5> sdc_select;    ///< カード選択信号
    typedef device::PORT<device::PORT6, device::bitpos::B4> sdc_power;    ///< カード電源制御
    typedef device::PORT<device::PORT6, device::bitpos::B3> sdc_detect;    ///< カード検出

RXマイコンでは、ポートの出力と、入力は、異なったレジスターを利用する
為、テンプレートクラスは、この対応が非常にやりやすい。
以下は、ポートクラスの一部:

struct port_t {
    static bit_rw_t<rw8_t<PORTx::base_address_ + 0x20>, bpos> PO;  // ポート出力用
    static bit_ro_t<ro8_t<PORTx::base_address_ + 0x40>, bpos> PI;  // ポート入力用

        void operator = (bool val) { PO = val; }
        bool operator () () { return PI(); }
    };
    static port_t P;

operator をオーバーロードする事で、「P」に対して、「=」で、値を設定、
「()」で読み出す事が出来る。

RX24T SD カードアクセスサンプル

RX64Mフラッシュ書き込みプログラム

RX24Tに続き、RX64Mでも、フラッシュへの書き込みが出来るようになった。

RX64Mは、RX24Tとは、全く違うプロトコルで、機能も増えている為、かなり
の部分が作り直しとなった。

RX63T、RX24Tでは、接続が確立され、コマンドを受け付けるようになった時
には、フラッシュは自動で消去されている為、「--erase」動作は必要無いのだが、
RX64Mでは、消去は、個別に対応する必要がある。

また、デバイスを自動で認識する訳では無い為、書き込み時、デバイス種別を選択する
必要がある。

./rx_prog -d RX64M -P COM11 --verbose --progress --erase --write --verify uart_sample.mot
# Platform: 'Cygwin'
# Configuration file path: 'rx_prog.conf'
# Device: 'RX64M'
# Serial port path: 'COM11'
# Serial port speed: 115200
# Input file path: 'uart_sample.mot'
# Motolola Sx format load map: (exec: 0x00000000)
#   0xFFE00000 to 0xFFE00FCB (4044 bytes)
#   0xFFFFFFD0 to 0xFFFFFFFF (48 bytes)
#   Total (4092 bytes)
# Serial port alias: COM11 ---> /dev/ttyS10
# Serial port path: '/dev/ttyS10'
# Connection OK.
#01/01: Device Type OSA: 16000000
#01/01: Device Type OSI: 16000000
#01/01: Device Type CPA: 120000000
#01/01: Device Type CPI: 120000000
#01/01: Endian is little.
#01/01: System clock: 120000000
#01/01: Device clock: 60000000
#01/01: Change baud rate: 115200
#01/01: ID: Disable
Erase:  ###############################################
Write:  ###############################################
Verify: ###############################################

RX Flash Programmer