So-net無料ブログ作成
  • ブログをはじめる
  • ログイン
前の5件 | -

EFM8UB1のファクトリーブートローダー

前回からのつづき。

EFM8UB1のRev.CシリコンからはファクトリーブートローダーとしてCDCブートローダーが入っている(8kバイト品はUART、それ以上はUSB CDC)。
マニュアルとしてAN945 (pdf)に記載があるものの、いまいち要領を得ないのでまとめておく。
以下はEFM8UB10F16G-Cでの手順。

・書き込みツール
書き込みツール一式は下記のリンクからダウンロードできる。
www.silabs.com/documents/public/example-code/AN945SW.zip
Windowsクライアントでは、この中のTools→Windowsフォルダにある efm8load.exe と hex2boot.exe を使う。

・CDCブートローダへのエントリ
C2Dピンを'L'にした状態でリセット(C2CKピンをL)または電源投入すると、ブートローダーに入る。
なので、ユーザープログラム側でC2Dピンを使っている(特に入力)と、意図しないタイミングでブートローダーにブランチする場合がある。CDCブートローダー前提ならC2Dピンはユーザープログラムでは未使用にしておく。

この状態でUSBを接続すると、WindowsからはHIDクラスのデバイスとして認識される。VCPではないのでCOMポートとしては見えない。

・ブートコードへの変換
CDCブートローダーで書き込む場合、プログラムコードを.efm8ファイルという形式に変換する必要がある。
変換には hex2boot.exe を使う。
Simplicity IDEでプロジェクトをビルドしてできる.hexファイルを次のようにして.efm8ファイルに変換する。-oオプションは省略できないので注意。

> hex2boot hoge.hex -o hoge.efm8


・EFM8への書き込み
用意した.efm8ファイルを efm8load.exe でMCUへ書き込む。

> efm8load hoge.efm8

エラーがなければプログラムが書き込まれた後、実行される。
以降は、リセット時C2Dピンが解放または'H'レベルであれはユーザープログラムが優先して実行される。

もしCDCブートローダーエントリされていなければ

> efm8load foo.efm8
ERROR: Unable to open port!

というようなエラーがでる。


EFM8UB1のピン処理

Sililon LabsのEFM8 Universal Beeシリーズは、廉価・小型・必要十分の性能と三拍子揃ったUSB対応マイコン。
EFM8 USB 対応 Universal Bee 8 ビット・マイクロコントローラ

あまりメジャーではないものの、EFM8UB1はほぼ同クラスのPIC18F14K50よりも安価かつUSBシグナルでキャリブレーションするOSC内蔵で、外付け部品なしで動作できる優れもの。
また、工場出荷時にUSB CDC経由でファームを書き込めるブートローダが入っているため、専用ダウンロードケーブルなしでプログラムを書き込むことができる。

そんなEFM8UB1を使うための調査をしたのでメモ。

efm8ub1_qfn20.png

●電源まわり
VREGINとVDDにそれぞれパスコンを繋ぐ。仕様書の推奨は4.7uF以上+0.1uFの組み合わせ。
USBバスパワーの場合、USB電源をVREGINに接続する、VDDは内部LDOから3.3Vが出力されるのでパスコンのみ接続しておく。USB電源の入力はノイズフィルタ(フェライトビーズ)を入れることが推奨されている。
USBセルフパワーの場合、VREGINとVDDに外部LDOから3.3Vを接続する。USB電源は抵抗分圧を介してVUSB(P3.1)へ接続する。

●USB信号線
D+/D-をそのままUSB信号に接続する。ESD保護素子(TVSダイオード)を入れることが推奨されている。
ただしEFM8UB1デバイス側にも8kVのESD保護を内蔵しているので、あまり神経質にならんでもよさそう。

●I/Oピン
全てのI/OピンはVIO=3.3V時に5Vトレラント。
駆動能力はVIOの90%まで降下する(ドロップ0.3V)ポイントで±5mA、75%まで降下する(ドロップ0.8V)ポイントで±12.5mA。実用上は±8mAを上限として設計するのがベター。

●リセットとデバッグピン
C2CKピンは入力専用でC2デバッグピンとユーザーリセットピンを兼用している。内部プルアップ機能があるため、ユーザーで使わない場合は未接続のままでOK。
C2DピンはC2デバッグピンと、工場出荷時はCDCブートローダへのエントリピンを兼用している。ブート時にLになっているとCDCブートローダへジャンプする。ユーザーで使わない場合は未接続のままでOK。
詳細は下記pdf参照。
AN124 : Pin Sharing Techniques for the C2 Interface
AN945 : EFM8 Factory Bootloader User's Guide

FT_PROGが動かなくなってたので調べた

今さら説明する必要もなかろうと思いますが、FT_PROGというのはFTDIのUSBブリッジICのコンフィグレーションを書き換えるツールです。

ft_prog_window.png

先日ちょっとデバイスのコンフィグレーションを変えようと思って使ってみたら、いつの間にかデバイススキャンが動かなくなってました。
そこでログを見てみるとFT_ProgのログにFTD2XX.DLLのロードエラーが出てる。どうやらセキュリティ強化のためか、DLLの暗黙の検索パスからシステムパスが削られてるのが原因くさい。

・解決

DLLがロードできないだけなので、FT_Prog.exeと同じフォルダにCDM v2.12.28のi386フォルダからftd2xx.dllをコピーしてやればOK

dll_copy.png

記憶がたしかなら去年は使えていたハズなので、今年に入ってからのWindowsUpdateが何か影響をしたのか?と思いいろいろ調べてみたところ、どうも7月のWIndows UpdateがFT_Progのデバイススキャンできない原因みたい。10.0.17134.137だとちゃんと見えるけど、165と191では見えなかった。


NT京都 [雑談]

ニコニコ技術部の春の恒例行事となりましたNT京都が、今年も京都・西院春日神社で行われました。
DSC03084_small.jpg

今回はニコニコ技術部の有志イベント開催10周年ということで、昔懐かしの動画ネタを出展しました。
DSC02998_small.jpg

当日の雰囲気などはNT京都2018 当日まとめ(togetter)からどうぞ。

VHDLで飽和演算 [IPコア]

前にVHDLのリダクション演算を書いたので、それを使った飽和演算処理を紹介。
HDLで飽和演算をしたい場面はちょくちょくでてくるものの、完全にパラメタラブルに書くのは以外と面倒くさい。

ざっくりと処理条件を書くとこうなる。
入力データをd、出力データをyとし、それぞれのビット幅をn,m、n>mとする。

(1) 正の最大値への飽和
d[n-1](MSB:符号ビット)が'0'、かつd[n-2:m-1]の全てのビットが'0'でない場合。
y[m-1] <= '0', y[m-2:0] <= 全て'1'

(2) 負の最大値への飽和
d[n-1]が'1'、かつd[n-2:m-1]の全てのビットが1でない場合。
y[m-1] <= '1', y[m-2:0] <= 全て'0'

(3) 飽和なし
y <= d[m-1:0]

VHDLでは比較演算子でオーバーロードされるので、任意長ベクタ型がゼロかどうかの比較は簡単にできるものの、即値で任意長のビット集合を生成するのにかなり鬱陶しいことをやらないといけない。
故に比較するビット幅がパラメタラブルなものは鬼門なのだけど、ここでリダクション演算を使うとすっきり記述できる。
例えば

or_reduce(A) = '0'

とするとAの全てのビットが'0'かどうかを判別できる。同様に、

and_reduce(B) = '1'

とするとBの全てのビットが'1'かどうかを判別できる。
そうすると、まとめてこんな感じで書くことができる。

y <=
  (y'left=>'0',others=>'1') when(d(d'left) = '0' and or_reduce(d(d'left-1 downto y'left)) /= '0') else
  (y'left=>'1',others=>'0') when(d(d'left) = '1' and and_reduce(d(d'left-1 downto y'left)) /= '1') else
  d(y'range);

結構長ったらしい記述だけども、注目すべきはマジックナンバーが出てこない点。つまり、これはdとyのビット長を自動的に参照して飽和演算回路を生成してくれる。
こんな感じてVHDLのアトリビュート演算子はめっちゃ便利だから皆使おう。


ちなみに飽和演算のキモは出力部以外のビットが符号値のみで構成されているかをどう判断するかである。
なので飽和条件は以下のようにもうすこし詰めることができる。

(1) d[n-1:m-1]の全てのビットが同値の場合は飽和無し
y <= d[m-1:0]

(2) それ以外の場合は符号ビットから最大値を生成
y[m-1] <= d[n-1], y[m-2:0] <= not d[n-1]

任意長ベクタの全ビット値が同じかどうかは、リダクションORとリダクションANDの一致をとれば判別できるので

y <=
  d(y'range) when(or_reduce(d(d'left downto y'left)) = and_reduce(d(d'left downto y'left)) else
  (y'left=>d(d'left),others=>not d(d'left)); 

と書ける。こちらの方がソースリストはすっきりする反面、比較条件のパスが複雑になるので必ずしもロジックが減るわけではない、という点には注意。


前の5件 | -