2008年7月28日月曜日

MicroSD 2GB 送料込み \698

 MicroSD 2GB を送料込み \698 で購入.


 MicroSD は機器との相性問題が結構きついということを身を持って体験済みなので,相性保証が無い MicroSD を買うのはちょっと気が引けたが,まぁ失敗しても \698 だし痛くないや.てか,去年の 2月に \5,000 出して買ったのがアホみたいや…

 今回買ったのは,Transcend の TSDN2GTF というやつで,SoftBank 810P・MicroSD→メモステ変換 + PSP でも何の問題もなく動いたヽ(´ー`)ノ
 結局 MicroSD は SunDisk,PQI,Transcend の 3枚手元にあるわけだが,PQI 以外は 810P でも MicroSD→メモステ変換 + PSP でも何の問題もない.もーぜってー PQI は買ってやんねーwww
# ちなみに,MicroSD→メモステ変換 は KingMax 製のやつと,PhotoFast CR-5200 どっちでも無問題.

 というわけで,MicroSD の数に余裕が出てきたので,1枚は MAPLUS2 専用にして,MAPLUS2 の ISO イメージを無圧縮で格納.MAPLUS2 がサクサク動くようになって快適ヽ(´ー`)ノ

2008年7月19日土曜日

簡易ラップタイム計測機能追加


「VSD for サーキットの友」に,簡易ラップタイム計測機能をつけてみた.

原理としては,動画でスタートラインを通過した瞬間に手動で目印をつけることで,目印~目印間の時間計測をして表示すると.なので原理的に動画の fps を超える精度の時間計測はできない (例えば動画が 30fps ならば,タイム計測の精度は 1/30 = 0.033秒) が,ラップタイマー持ってない人にとってはこれだけでも十分うれしいのではないかと.

ラップタイム表示のコード自体は,もともとの自作データロガー用 VSD が持っているので,問題は AviUtl の GUI でどうやってスタートラインの位置を入力するか.幸い,「マーク」という機能があって,任意のフレームにマークをつけることができるので,それでスタートライン通過フレームの指定をすることにした.

てなわけで,チャッチャと実装完了.

2008年7月13日日曜日

車載動画スーパーインポーズフィルタをサーキットの友に対応


自分はデータロガー環境を独自に構築しているが,これを他の人に広めようとしても,一番のネックになるのは車両からの情報を収集する方法.自分では H8 マイコンを用いているが,少なくともハンダ付けが必要なので他の人に展開するのはほぼ不可能だろう.

しかし世の中にはうまいことを考える人もいるようで,簡単なケーブルを自作するだけで,ノーパソが車両からの情報を収集できる機械になってしまうというものがあった↓
サーキットの友
原理としては,ライン (マイク) 入力に車両からの信号を突っ込んで,サウンドカードを AD 変換器代わりに使用して,CPU パワーでその波形をリアルタイムに解析すると.ステレオ入力だと最大 2ch (スピード・タコ) が解析できるから,簡易的なデータロガーになる.そういや同じような考えで,ライン入力をオシロスコープ代わりに使用するソフトもあったっけ.

もっと早くこれを知っていたら,自作データロガーとかわざわざ作らなかったかもw

で,サーキットの友 で車両のログを取ることはできるが,車載動画と合成する機能まではないので,自分の作った車載動画スーパーインポーズフィルタをサーキットの友対応にしてみた.

欲しい人はこちら

2008年6月22日日曜日

ゴミ SD カード活用

-------- initialize --------
CMD0:1 CMD1:7 CMD1:7 CMD1:3 CMD1:3 CMD1:3 CMD1:3 CMD1:3 CMD1:3 CMD1:3 CMD1:3
-------- CSD --------
CMD9:0,FE
0000:CSD structure
0000:System specification version
002D:Data read access-time 1
0000:Data read access-time 2 in CLK cycles
0032:Max. bus clock frequency
0135:Card command classes
0009:Max. read data block length
0001:Partial blocks for read allowed
0000:Write block misalignment
0000:Read block misalignment
0000:DSR implemented
019E:Device Size
0006:Max. read current @ VDD min
0006:Max. read current @ VDD max
0006:Max. write current @ VDD min
0006:Max. write current @ VDD max
0003:Device size multiplier
0013:Erase group size
001F:Erase group size multiplier
001F:Write protect group size
0000:Write protect group enable
0000:Manufacturer default ECC
0005:Write speed factor
0009:Max. write data block length
0000:Partial blocks for write allowed
0000:Content protection application
0000:File format group
0000:Copy flag (OTP)
0000:Permanent write protection
0000:Temporary write protection
0000:File Format
0000:ECC code
0074:CRC
f_mount:0
CMD17:0,FE CMD17:0,FE CMD17:0,FE
f_open:0
CMD17:0,FE
f_read:0: read=512
f_close:0
-------- dump --------
0000:00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0010:00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0020:00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
…
01F0:00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

MassStrage.dfu で 8MB のゴミ SD カードのアクセスが失敗していたので,どこでコケているのか調べてみた.
最初は初期化シーケンスが正しくないのかと思ったが,SD の仕様書と見比べてもそんなにおかしなところはない.お次は AC タイミング的なエラーを疑ってみたが,こればっかりはオシロスコープ持ってないのでわかんね.ただほとんどのコマンド (CMD0 とか 9 とかはぜんぜん正常であることが分かってきた.てことは AC タイミング的な問題ではない?

唯一おかしいのは CMD1.こいつのレスポンスが 0x7 とか 0x3 とかしか返ってこないので,MassStrage.dfu では MSD_GoIdleState() で死んでいたようだ.でもレスポンスが 0x7 とか 0x3 とかって,ここ見る限りそもそもなんかおかしいんですが… (illegal command とかありえねー) もしかして SPI の 8bit アライメントがずれてんのか?
本来
11111111 00000001 11111111
と受け取りたいところを,2bit ずれて
11111100 00000111 111111?
と受け取ってしまってるとか.これならばレスポンスが 7→3 に変化してるのも筋が通るが,何でズレてんのかまではわかんね.ああ,こういうときオシロとかロジアナとかほしいなぁ…

で本来 CMD1 のレスポンスが 0 になるまで wait するのだが,レスポンスがおかしいまま次に進んでも CMD17 (セクタリード) とかは全然正常 (これのレスポンスとかリードデータが bit ズレ起こさないのも,上の仮定と違ってて謎).というわけでゴミ 8MB SD カードが無事活用できるようになった(?)

他の使えなかった SD カード (2GB) の解析はやってないけど,たぶんセクタサイズが 512B 以外になっててその設定 (CMD16) をやってないからじゃなかろうか?

-----
追記:
 CMD1 が Illegal Command になっていた件,どうやら SD カードの厳密な仕様的には CMD1 は受け付けなくて,CMD41 で初期化しなければならないらしい.CMD41 で初期化すると,ゴミ 8MB カードも無事使用できた.
 MMC と SD は SPI 通信を使う限り,完全互換性があるという思い込みをしてしまっていた.

2008年6月20日金曜日

FLASH 上のルーチンにリンク成功

デザインウェーブマガジン付録 ARM ボードをいぢくる続き.

FLASH に焼かれたルーチンを SRAM 実行プログラムから呼び出す方法を確立してみた.
SRAM は 20KB しかないので,printf 等の大き目のルーチンを SRAM 実行プログラムにリンクしてしまうと,当然残りの SRAM 容量が減ってしまうので開発に支障が出る.そこで FLASH 上にある printf ルーチンをリンクしてしまおうというのが今回の趣旨.

まず,FLASH 上の printf のアドレスを知るためには,
メニューの Project → Options...
Linker → List タブ → Generate linker map file
で FLASH 実行プログラムの .map ファイルを生成すればよい.たとえば printf のアドレスが 0x080063ed だったとすると,SRAM プログラムのソースで

#define printf (*( int (*)( const char *fmt, ... ))0x080063ed)

と書けば OK.

だが,これだと printf を使ってる全ファイルの修正が必要だし,いちいちプロトタイプ宣言を調べて #define を書き並べるのが面倒なので,別の方法を考えてみる.

rom_entry.s なるファイルを以下の内容

    RSEG ROM_CODE:CODE(2)
EXPORT printf
printf = 0x080063ed
END

で作成し SRAM プログラムのプロジェクトに追加してコンパイル・リンクすることで,FLASH 上の printf にリンクできた.この方法だと .c の修正はいらないし,.map ファイルから perl スクリプトなんかで機械的に rom_entry.s を生成できるので楽.

いろいろ FLASH 上のルーチンにリンクしたら,もともと 18KB のプログラムが 5.5KB になったよ(笑)

2008年6月18日水曜日

SD カード FAT アクセス成功

デザインウェーブマガジン付録 ARM ボードをいぢくる続き.


昨日と今日にかけて,フリーの FAT ファイルシステムドライバであるFatFsを組み込んで,SD カードのファイルを読み出せるようにしてみた.

具体的には,ff.c を組み込んで,diskio.c をインプリしていくのだが,disk_read/write() はほとんど SD カードセクタリード・ライトそのまんまだが,disk_ioctl() は何書いていいのか分からん… 幸いここにサンプルがあった.

デバッグ用にシリアル出力を大量にしているとなぜかリードデータが化ける問題があってちょっとハマッたが,最終的に無事ファイルリード完了ヽ(´ー`)ノ

あと,putchar() 関数を定義して,こいつでシリアル出力するようにしておくと,printf() で普通にシリアルにメッセージが出せるので便利ヽ(´ー`)ノ

以下,ToDo リスト
・FLASH のルーチンを SRAM プログラムからコールする仕組みを確立
・SRAM ルーチンを割込みハンドラに設定
・割り込みを使用したシリアル入出力
・ここら辺が FIX したら FLASH に焼いて,「SD カード上のファームを SRAM にロード」を運用開始

2008年6月16日月曜日

SD カードセクタダンプ成功(?)

データロガー 2号機計画を ゆっくり と進行中.


今回は,MassStrage を参考に,SD カードの 1セクタをリードしてシリアル (USB を介した仮想 com ポート) 出力にダンプさせてみた.まぁ MassStrage の msd.c あたりをそのまま組み込んだだけだが.コンパイル通すのに多少苦労しつつ,とりあえずダンプできるまでこぎつけた.

が,シリアル出力が明らかにおかしい.シリアル出力はカエルがぴょんのやつを参考にしていて,USB の送信データバッファ(?) に送信したい文字列を直接コピーしているのだが,おそらく前のやつが送信されきらないうちに次の文字列を上書きしているのだろう.

普通は,アプリ側でリングバッファを用意して,送信したいデータはリングバッファに書く→USB 送信データバッファに空きができたら割込み発生→割込みルーチンで,リングバッファから送信データバッファにコピー,なんて流れになると思うのだが…
もうちっと Cortex の割り込みを勉強せにゃならんね.とにかくシリアル出力をまともにしないと,まともなデバッグができねぇ.

とりあえず,断片的に見えているダンプデータを見る限り,SD カードセクタリードはできているようだ.

----
6/16追記:
とりあえず割り込みを使用しないでお茶を濁しモード.送信データをバッファにカキコ前に

while( GetEPTxStatus( ENDP1 ) == EP_TX_VALID );

で前回のデータが送信されきるまで待つことで,シリアル出力は正常になったヽ(´ー`)ノ

2008年6月9日月曜日

シリアル経由 FW ローダ完成

前回の記事どおり,SD カードの FW を SRAM にロードする仕組みを作っていくが,その前に,シリアル経由で FW を SRAM にロードする仕組みを作る.いくら既存のライブラリが充実しているからって,一発で SD カードアクセスプログラムが動くわけが無いのでw


というわけで,
1. 起動されたらデータを 0x4800 バイト分,シリアル (USB経由) から読み込んで 0x20000000~ へ書き込む
2. 0x20000004 に格納されているエントリポイントにジャンプ
という恐ろしく単純なプログラムを FLASH に焼きこんだ.これすらも,デザインウェーブマガジンに載っていたカエルがぴょんプログラムをちょこっと書き換えただけ.

ちなみに,マガジン付属 CD に入っていたサンプルプログラムの多くは,IAR Embedded Workbench でコンパイルしようとすると「__program_start」シンボルが無い,などと怒られてしまうが,その対処法はここに載っているようだ.

そしてマガジンに載っていた LED を点滅させるプログラムを SRAM 実行用に書き換え→.s19 を 0x20000000 からのバイナリイメージに変換するプログラムを作って変換→TeraTerm の send file で基盤に送信,で無事 LED が点滅したヽ(´ー`)ノ

これで内蔵 FLASH を書き換えることなく開発・デバッグができる.しかし,早いことベース基盤を作らないと,リセットボタンすらないのでやりにくぅ.

ちなみにメモリマップは前回からさらに変わっている↓

20000000ベクタテーブル
200000ECSRAM プログラム用 .text
・・・SRAM プログラム用 .data .bss 等
・・・空き
・・・スタック
(SRAM後端)FLASH プログラム用 .data .bss 等
20005000

SRAM 実行用プログラムのコード・ベクタテーブルを SRAM の前端で固定したかったので,FLASH 実行用 SRAM 領域を SRAM の最後尾にやって,そこからスタック領域とした.

2008年6月8日日曜日

データロガー2号計画発動

デザインウェーブの Cortex-M (AAM ARM) 基盤を使ったデータロガー 2号機作成をぼちぼち開始.

とりあえずの目標としては,SD カード上のファームウェアを SRAM 上にロードする仕組みを作る.で開発途上は SD カードにファームを書き込むことで Cortex 内部 FLASH の書き込み回数を減らす.これだとコード + データが 20KB 以内しか作れないが,デバッグの終わったルーチンをまとめて内部 FLASH に追い出して,SRAM 上のプログラムから FLASH 上のルーチンを呼び出す.なんてことを H8 の時はしてた.(H8 は SD カードアクセスはできなかったので,シリアル経由の .mot ロードだったが)

で,SD カードアクセスのライブラリは MassStrage デモのライブラリがそのまま使えそうだ.FAT アクセスライブラリも使われてるかと思ったら,FAT の管理をやってるのは Windows 側なのね.なのでフリーの FAT ライブラリを探してみたら,ここのが使えそうだ.

で,いろいろ make してると,メモリマップがちょとヘンなことが発覚.常識的には SP の初期値は RAM 領域最後尾の 0x20005000 だと思うのだが,標準だと 0x20000000 + プログラムで使う分 + 0x200 くらい.RAM あまりまくってるのにもったいない.

これは gcc でいうところのリンカスクリプトがおかしいのだろうと思っていろいろいじってみた.俺がインストしたのは「IAR Embedded Workbench」なので,リンカスクリプトに相当するのは「STM32F10x_FLASH.icf」になる.で以下のように書き換えた.

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08003000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x080030ec;
define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20004FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x0;
define symbol __ICFEDIT_size_heap__ = 0x200;
/**** End of ICF editor section. ###ICF###*/


define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];

define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
place at address mem:( __ICFEDIT_region_RAM_end__ + 1 ) { block CSTACK };

define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };

initialize by copy { readwrite };
do not initialize { section .noinit };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

define block RAM_Block with fixed order { rw, block HEAP };

place in ROM_region { readonly };
place in RAM_region { block RAM_Block };

要は,もともとの .icf ではデータ・ヒープ・スタックを連続領域にとっていたのだが,STACK を独立させて 0x20005000 から サイズ 0 で(笑) 固定的に取っただけ.
てか,gcc のリンカスクリプトはドキュメントが充実してるし高機能だし楽なんだけど,ツール独自のリンカスクリプトはわけが分からん…

2008年5月31日土曜日

Gyao 動画を携帯で見る(2)

 810P で動画を見る事にこだわってみるテスト.PSP だとポケットに入れていくわけにはいかないし,重いし見るとき手が疲れるし.

 というわけで安直な方法で,.MP4 を 10分単位でファイル分割してみる事に.810P にはファイル連続再生機能があるので,これでもまぁ支障はないだろう.
 で,Yamb というフリーソフトを見つけてきて分割してみたが,分割された動画の再生が途中で終わってしまうので,うまく分割できていないようだ.それよりも驚愕の事実発覚.分割されたファイルには 001, 002, … という風に連番がつくのだが,810P の連続再生では,その番号の大きいほうから小さいほうへ再生する事しかできない.なんじゃこの仕様は.まともなプレーヤー実装する気あんのか佐江戸のやつらは (- -メ むか

 この事実を知った時点でファイル分割は萎え萎えになったので,別の案を探してみると,.MP4 にはチャプターを打てる仕様があることがわかり,しかも Yamb でチャプターを打てることが分かった.でも Yamb ではうまくいかなかったので,MP4Box のコマンドラインオプションで直接やってみた (Yamb は MP4Box の 単なる GUI ラッパーなので).が,PC のプレイヤーではチャプターを認識できたのだが,810P では認識できなかった_| ̄|○

 あー,残された手段は,ffmpeg の範囲指定エンコードで,細切れにエンコードしていくバッチファイルとか作るしかないか(゜ーÅ)ほろり