hira のすべての投稿

ロジックアナライザー購入

仕事で、どうしてもロジックアナライザが必要になり、色々調べて購入した。

img_0891s

ヤフオクで買ったテクトロニクスのデジタルストレージはあるにはあるのだが、どうも
最近調子が悪く、チャネルも少ない。

購入したのは、「LA2016」で、200Mサンプル、16チャネル、1Gビットのメモリー
姉妹機として、100Mサンプル(LA1016)、500Mサンプル(LA5016)
がある、LA5016は$168、LA1016は$75、LA2016は$88となっ
ており、手頃な値段でありながら、高性能となっている。
※LA5016を買っといた方が良かったかもしれない。

急いでいたのでDHLを使った為、$100を超えたが、それでも安い!

このロジックアナライザは中国製のようだが、品質は悪くない。
アプリは、Windowsで動作する、多少、トリガー条件がチープではあるが、工夫
すれば問題無い範囲だろうと思う。
アプリは安定しており、USBドライバーも問題が起こらなかった、ノートでも安定し
て動作する。(Windows7、Windows10 で試した)
※アプリには、オートアップデート機能があるが、正しく動作しなかった為、本家の
サイト(中国)からアーカイブをダウンロードしてアップグレードした。

また、本家には、SDKもあり、自分でキャプチャーを行うアプリを自作できるようだ。

ロジックアナライザの導入を考えている人がいるのなら、是非選択枠に加えたら良いと
思う。

-----
購入後に気がついた、DSLogic Proも良さそうだ!
こちらは、オープンソースで、Windows、OS-X、Linuxで動作する。

整数計算でサインテーブルを生成する

これは、アセンブラ時代に、サインテーブルを生成する方法を色々試して、ある程度
成果のあった方法です。
※浮動小数点の sin で求めた値と微妙に違うところもありますが、実用性は十分あり
ます。

現在の C++11 以降では、constexpr でコンパイル時に計算して、定数としてソースコ
ードにテーブルを埋め込む事ができるので、必要性は薄いのですが、知っていれば、
応用範囲は広いでしょう。
ハードウェアーに実装して、周波数シンセサイザや音源の波形ベースに使う事も考え
られます。

x' = x・cos(s) - y・sin(s)
y' = x・sin(s) + y・cos(s)

s が十分小さい場合、以下のように近似できる。
cos(s) ≒ 1
sin(s) ≒ s

x' = x - y・s
y' = x'・s + y

テーブル生成に使っていますが、連続性がある場合は、リアルタイムに計算する事も
できます。(こちらの方が応用性があります)

非常に古いですが、1979年に発売された、ナムコのギャラクシアンで、編隊が、
実機の手前で、回転したり、サインカーブ的な軌跡で攻撃してくる場面がありますが、
この原理が使われていました。
※この当時、安易にテーブルにする人が多い中で、真のエンジニアでした。

また、単振動を使って、サインテーブルを計算する方法もあるかと思いますが、周期
を決定する定数を求めるのは、整数計算だけでは、簡単では無いと思えます。

テーブル生成では、テーブルのサイズは、2のN乗の方が、扱いやすいので、sの定
数を求める場合は、全円周(2・π)を、テーブル長で割る必要があります。

template <uint16_t shi, uint16_t len>
class sin_cos {

    static const uint32_t pai_ = 0xC90FDAA2;    ///< 円周率(3.141592654 * 2^30)
    static const uint32_t pai_shift_ = 30;      ///< 円周率、小数点位置

    uint16_t tbl_[(1 << shi) + 1];

    void build_()
    {
        int16_t gain = 16;  // 精度を確保する為の下駄
        int64_t x = len << gain;  // cos(0) の値
        int64_t y = 0;    // sin(0) の値
        for(uint16_t i = 0; i < ((1 << shi) + 1); ++i) {
            tbl_[i] = y >> gain;   // pai_ のビット位置補正
	    // 全周は、2・πなので+1
	    x -= (static_cast(pai_) * y) >> (pai_shift_ + shi + 1);
	    y += (static_cast(pai_) * x) >> (pai_shift_ + shi + 1);
        }
    }
    public:
        sin_cos() { build_(); }
};

整数演算で平方根

最近、整数演算だけで色々する話があったので、過去に作成したものを見直してみた。

・平方根
これは、ファミコン時代から使っていた方法をC++(C)で表現したもので。
※アルゴリズムは、コンピューターが出現する以前から知られていた数学的手法を元に
しているようで、初期のデジタルコンピューターが出現する、数十年前に既に知られて
いた方法のようである。

過去には、色々なマイコン用(6502、6809、68000、Z80)アセンブラ
で書いた記憶がある。
Cなどの高級言語では、キャーリーの扱いが無い為、シフトや、ビット操作を行う場合
無駄が多い。
アセンブラで書けば、より一層の高速化ができるけど、互換性を考えて、Cで実装して
ある。
ハードウェアーにも実装しやすく、割り算よりリソースを使わないと思われる。
※整数計算なので、「余り」がある。

ゲームにおいて平方根は、必ず必要な「道具」で、シューティングゲームの誘導ミサイ
ル、正規化、ほぼありとあらゆる場面で使うと思われる。

template <typename T>
struct sqrt_t {
    typedef T value_type;

    T   val;    ///< 答え
    T   mod;	///< 余り

    sqrt_t(T v = 0, T m = 0) : val(v), mod(m) { }
};

static sqrt_t<uint16_t> sqrt16(uint16_t in)
{
    uint32_t a = in;
    uint32_t b = 0x4000;
    for(int i = 0; i < 8; ++i) {
        if(a >= b) {
            a -= b;
            b = ((b + b) & 0xfffe0000) + 0x10000 + (b & 0xffff);
        } else {
            b = ((b + b) & 0xfffe0000) + (b & 0xffff);
        }
        a <<= 2;
    }
    sqrt_t<uint16_t> ans(b >> 16, a >> 16);
    return ans;
}

・32ビット版

static sqrt_t<uint32_t> sqrt32(uint32_t al)
{
    uint32_t ah, bh, bl;

    ah = bh = 0;
    bl = 0x40000000;
    for(int i = 0; i < 16; ++i) {
        if(al >= bl) {
            if(ah >= bh) {
                ah -= bh;
                al -= bl;
                bh += bh + 1;
            } else {
                bh += bh;
            }
        } else {
            if(ah >= (bh + 1)) {
                ah -= bh + 1;
                al -= bl;
                bh += bh + 1;
            } else {
                bh += bh;
            }
        }
        ah <<= 2;
        ah += al >> 30;
        al <<= 2;
    }

    sqrt_t ans(bh, ah);
    return ans;
}

intmath.hpp

マイクロチップ用開発環境を構築

マイクロチップ用のソースを修正する作業が生じた為、Windows で、環境構築をしてみた。

遠い昔に、マイクロチップが出始めた時に、自分でアセンブラを実装して開発した覚えが
あるが、最近は、AVRやルネサスがメインとなり、使わなくなった。

開発環境が有料な事や、プログラマーが高いのも敬遠する理由ではある。
・プログラマーを自分で作る事もできそうだが、種類が多いので大変そうだ・・・
・60日を過ぎると、無料版は、最適化が「-O1」のみとなる。
※一応ソースコードが入手できるので、パッチを当てて、制限を回避する事も出来るよう
だが・・・
・現状で、C++14 のコードをコンパイル出来ないのは、まともなコンパイラとは思えない。

PICの良い面は、デバイスの入手性、バリエーションの多さ、「コスパ」なのだと思うが
自分はメリットを感じない。

今回使うチップは、「PIC24EP256GU810」で、「MPLAB C30」をインストールした。
※コンパイラは魔改造された gcc のようだ。

例によって、IDEを使わず、コマンドラインで開発したいので、Windows、MSYS2 で動作
させてみた。
以前から少しづつアップデートしている独自の「Makefile」を PIC30 用に修正しておこなった。
※この「Makefile」は、非常に柔軟性が高い!
従属規則の生成も全く問題無く、正常に生成された。
そして、暫く格闘したが、コンパイルしてリンクできるようになった。

・MPLAB C30 にパスを通す。(PATH=$PATH:/c/'Program Files (x86)'/Microchip/'MPLAB C30'/bin)
・デバイスを指定する。(-mpu=24EP256GU810)
・適切なコンパイルオプションを選ぶ。(-mlarge-code -mlarge-data -mlarge-scalar -mconst-in-data)
・適切なリンクオプションを選ぶ。(-T p24EP256GU810.gld --heap=1024 --stack=1024)

これだけ行って、コンパイル、リンクが通った。

#=======================================================#
#                                                       #
#    PIC C30 Makfile                                    #
#                                                       #
#=======================================================#
TARGET  =   farm

DEVICE  =   24EP256GU810

BUILD   =   release

VPATH   =

ASOURCES =

CSOURCES =   ここにソースファイルを列挙する~

PSOURCES =   

USER_LIBS =

LDSCRIPT  =

USER_DEFS =

INC_SYS   =

INC_APP   =

OPTIMIZE  =   -O1 -mlarge-code -mlarge-data -mlarge-scalar -mconst-in-data

MCU_TARGET =   -mcpu=$(DEVICE)

CP_OPT   =   -Wall -Werror \
             -Wno-unused-variable \
             -Wno-unused-function \
             -fno-exceptions

#CC_OPT  =   -Wall -Werror \
#            -Wno-unused-variable \
#            -fno-exceptions
#CC_OPT  =   -x c
CC_OPT   =

SYSINCS  =   $(addprefix -I, $(INC_SYS))
APPINCS  =   $(addprefix -I, $(INC_APP))
AINCS    =   $(SYSINCS) $(APPINCS)
CINCS    =   $(SYSINCS) $(APPINCS)
PINCS    =   $(SYSINCS) $(APPINCS)
LIBINCS  =   $(addprefix -L, $(LIB_ROOT))
DEFS     =   $(addprefix -D, $(USER_DEFS))
LIBS     =   $(addprefix -l, $(USER_LIBS))

# You should not have to change anything below here.
AS       =   pic30-as
CC       =   pic30-gcc
CP       =
AR       =   pic30-ar
LD       =   pic30-ld
OBJCOPY  =
OBJDUMP  =   pic30-objdump
SIZE     =
HEX      =   pic30-bin2hex

# AFLAGS =   -Wa,-adhlns=$(<:.s=.lst),-gstabs
# AFLAGS =   -Wa,-adhlns=$(<:.s=.lst)
# ALL_ASFLAGS = -x assembler-with-cpp $(ASFLAGS) $(DEFS)
ALL_ASFLAGS  =   $(AFLAGS) $(MCU_TARGET) $(DEFS)

# Override is only needed by avr-lib build system.

CFLAGS  =   $(CC_OPT) $(OPTIMIZE) $(MCU_TARGET) $(DEFS)
PFLAGS  =   -std=c++14 $(CP_OPT) $(OPTIMIZE) $(MCU_TARGET) $(DEFS)

# override LDFLAGS = $(MCU_TARGET) -nostartfiles -Wl,-Map,$(TARGET).map -T $(LDSCRIPT)
# override LDFLAGS = $(MCU_TARGET) -T$(DEVICE).gld,--defsym=__MPLAB_BUILD=1,--defsym=__MPLAB_DEBUG=1,--heap=1024,--stack=1024,-Map="VTS-10a.map"
override LDFLAGS = $(MCU_TARGET) -T p$(DEVICE).gld --heap=1024 --stack=1024

OBJCOPY_OPT  =   --srec-forceS3 --srec-len 32

OBJECTS =   $(addprefix $(BUILD)/,$(patsubst %.s,%.o,$(ASOURCES))) \
            $(addprefix $(BUILD)/,$(patsubst %.c,%.o,$(CSOURCES))) \
            $(addprefix $(BUILD)/,$(patsubst %.cpp,%.o,$(PSOURCES)))

DOBJECTS =  $(addprefix $(BUILD)/,$(patsubst %.c,%.o,$(CSOURCES))) \
            $(addprefix $(BUILD)/,$(patsubst %.cpp,%.o,$(PSOURCES)))

DEPENDS =   $(patsubst %.o,%.d, $(DOBJECTS))

.PHONY: all clean
.SUFFIXES :
.SUFFIXES : .rc .hpp .s .h .c .cpp .d .o

all: $(BUILD) $(TARGET).elf

$(TARGET).elf: $(OBJECTS) Makefile
    $(CC) $(LDFLAGS) $(LIBINCS) -o $@ $(OBJECTS) $(LIBS)
    $(HEX) $@ $(TARGET).hex

$(BUILD)/%.o: %.s
    mkdir -p $(dir $@); \
    $(AS) -c $(AOPT) $(AFLAGS) $(AINCS) -o $@ $<

$(BUILD)/%.o : %.c
    mkdir -p $(dir $@); \
    $(CC) -c $(COPT) $(CFLAGS) $(CINCS) $(CCWARN) -o $@ $<

$(BUILD)/%.o : %.cpp
    mkdir -p $(dir $@); \
    $(CP) -c $(POPT) $(PFLAGS) $(PINCS) $(CPWARN) -o $@ $<

$(BUILD)/%.d: %.c
    mkdir -p $(dir $@); \
    $(CC) -MM -DDEPEND_ESCAPE $(COPT) $(CFLAGS) $(APPINCS) $< \
        | sed 's/$(notdir $*)\.o:/$(subst /,\/,$(patsubst %.d,%.o,$@) $@):/' > $@ ; \
        [ -s $@ ] || rm -f $@

$(BUILD)/%.d: %.cpp
    mkdir -p $(dir $@); \
    $(CP) -MM -DDEPEND_ESCAPE $(POPT) $(PFLAGS) $(APPINCS) $< \
        | sed 's/$(notdir $*)\.o:/$(subst /,\/,$(patsubst %.d,%.o,$@) $@):/' > $@ ; \
        [ -s $@ ] || rm -f $@

clean:
    rm -rf $(BUILD) $(TARGET).elf $(TARGET).mot $(TARGET).lst $(TARGET).map

clean_depend:
    rm -f $(DEPENDS)

後は、書き込んでテストとなるが、ライターは自作する時間も惜しいので、仕方なく
「PICkit3」を買う(5700円)事にする。(自分のお金じゃ無いけど・・)
IMG_0898s
※自分は、デバッグ機能(トレース、実行など)が必要になった事が少ないので、
フラッシュ書き込みさえ出来れば、満足なのだけど・・・

やはり、コンパイラが有償(無償版は60日過ぎると、最適化できなくなる)なのは、最
悪だと思う、自分的には、仕事以外では絶対に使わないデバイスだと思う。

追記:
Windows10 のノートにもPICの開発環境をインストールしたが、コンパイラを走らせる
と「ライセンスがどうの」と言ってきてエラーになる・・・
調べると、「mplabc30-v3_31-windows-installer.exe」のバージョンに起因する、
license-lm 関係のバグのようだ、そこで、「v3_30」を取ってきてインストールした。

-----
やっぱり、ルネサス系、R8C、RL78、RXマイコンが最高だと、再認識する。
※コストでは、PICに武がある事は認めるのだけど・・・

18650電池ボックスの製作

18650単セルの放電など行っていて、接触抵抗の少ない電池ボックスがあると
便利だ。

一般に売られている汎用電池ボックスは、スプリング式の電極なのだが、構造上の
問題で、接触抵抗が不安定で、使い物にならない場合が多いようだ。
充電、放電電流が小さい場合は、それでも良いが、1Aくらいだと、接触抵抗の増
大により、充電電圧、電流の制御が不安定になり、充電が正しく行われなかったり
する場合もある。

そこで、通販で売られている引きバネ式の充電器に習って、同じような構造で、電
池ボックスを自作してみる事にした。

まず、どうやって作るか?

色々考えた末、両面スルホールのユニバーサル基板を組み合わせて作る事にした。
※以前に、自動車の車内ランプをLED化した時に、電極と、基板のスルホールを
利用して半田付けする事で、製作性と強度を確保しつつ、自由に形状を作れる事が
あった、この方法を電池ボックスにも応用してみた。
スルホールのユニバーサル基板は、値段が高いので、少しもったいないけど、試み
としては面白いと思う。
2.54mmを「単位」として適当に考えた。
※作ってからタイトにしすぎた事に気づいた・・・
※毎度の事だが、構造が懲りすぎと思える、ただの電池ボックスなのに・・・
ただ、コストを出来るだけ抑える工夫はしている。

各部品:
img_0885s
コンターマシンがあるので、ガラスエポキシの基板を切り出すのは簡単だけど、切
断面はシャープでは無いので、ベルトグラインダーで整えて、リューター、ヤスリ
などで、曲面を切り出したり、整形する。
※電動リューターは、以前に友人から貰った物だが、細かい加工がやりやすい優れ
ものだ。

組み立てた状態:
img_0886s

銅線とスルホールを利用して、コーナーをハンダ付け:
img_0887s

スライド接点の作成:
img_0889s
内径3mmのジュラコンをスライドメタルに使って、3mmのステンレス棒をスラ
イドガイドにしたものの、「引きバネ」では意外とスムーズに動かない事が判明。

とりあえず、「引きバネ」じゃなくて、押しバネなら大丈夫そう・・

強力な「押しバネ」が手元に無いので、とりあえず、保留だな、残念・・・
まぁ、こんな事は良くあるwww

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サンプル