STM32F7を使ってみる11 -最新のeMMCを動かす-
前回までは古き世代の遺産であるマルチメディアカードをSTM32F7で再び動作せしめる
までになりましたが、今回は新しい世代へと進化したeMMCモジュールの動作に
ついに、ついに挑みます!
eMMCは最早カードの形状ではなく、ごく一般的なICの形となっていますがそれが
故に使い慣れたSDカードコネクタとかで使うには少々骨が折れます。
市販のギャングプログラマ用のSDカード変換付きソケットは100$以上するのであんまし
手を出したくはないです…
簡単かつ確実に使う良い方法ないかといろいろ探ってみるとODROIDと言うLinux系の
ARMボード向けのオプションパーツとしてeMMC実装済みのMicroSDの変換基板が販売
されているのを発見しました!
SouthKorea製なのがほんの少し心配でしたが値段も送料込みで38USD
(2016年3月下旬時点)だったので早速注文してみました!!
で、発注後4日くらいで親父の家に届きました。一週間以上かかるかと思いましたが
予想以上に早かったです。Androidを意識した質素の箱の作りで"Do it yourself"
なるコメントがあります。
一応ぷちぷちにくるまれていましたがこの色って静電対策してないやt
これって静電対策してないやt
まぁでもうごけばいいのですよぅ動けば!!
ボードとしてはコテコテの南朝鮮製ですが実装されているeMMCは東芝製で容量8GB,
そして規格はeMMCv5の最新版です!!!
一応コリアンボードのmicroSDへの変換パタンもやっけつではなく信号のIntegrity
を考慮した配線をしてくれているようです。
eMMCは古いタイプのカードリーダーでは認識すらしない場合があります。
ねむいさんが昨年購入したUSB3.0のTranscend製のカードリーダーでは無事に
認識できました♥
もともとこのeMMCはODROIDのオプションパーツとして販売されているので、
こんな風に最初から何らかのOSが仕込んであります。
ねむいさんはそんなもん関係なくeMMCを使用すること自体が目的なので速攻
FAT32でフォーマットして更地にてやりました!!!
前回の最後でちょろっと漏らしているように実は公開したF7のサンプルでは
既にeMMC(とMMCのブロックアドレッシング)に対応しております。
ビルド時間は結構長いので暇つぶしがてらF7からeMMCのルーチンを移植中の
STM32F4の板に差して反応見てみるかと思ったらなんと普通に認識してしまった…。
拍子抜けするくらいあっさり読めちゃって感動もへったくれもない…
ぇっ!?黒澤ダイヤちゃんのお口がイケナイことになってるって!?何のことやらハハ
虹裏メイドねむいさんは「ラブライブ!サンシャイン!!」を応援します。
さてビルドが終わってF7のプログラムの書き換えも終わったのでF4板から外すか
…と思ったら…
あ…あれ…???
・・・
案の定HELL朝鮮製ボードに罠がありました…微妙にサイズが大きいようで刺さる
には刺さるんですけど安易に抜けません(意味深)。
無理やり引き抜くと基板で擦れてMicroSDコネクタを壊してしまいます…
てわけで削ります。
いきなりF7-Discoveryで試さなくてよかった…
ゴリゴリ削ってこんな感じに…
うまいこと削れたのでF7-Discoveryのコネクタにスムーズに差さります。
F7でも無事に認識して画像や動画データも自由自在に読み出しできます♥
このeMMCは8GBの容量でSDHCと同じくブロックアドレッシングになります。
私の移植例ではMMCv4以降に新設されたブートパーティション等にアクセス
するための特別なコマンド群は使用しておらず、SDHC/SDXCと同じ感覚で読み
書きします。腕に自信がある人、私のコードを参考に拡張してください・・・(懇願)
そしていつも通りカード(?)の情報を読み出してみました。
>ds 0
rc=0
Drive size: 15269888 sectors
Erase block size: 1024 sectors
Default r/w block size: 512 bytes
Card type: MMC(Block)
CSD:
00000000 D0 5E 00 32 0F 59 03 FF FF FF FF EF 92 40 00 D3 .^.2.Y.......@..
CID:
00000000 11 01 00 30 30 38 47 45 30 00 5A DD 41 40 B2 0D ...008GE0.Z.A@..
Parsing MMC CID Register
Manufacturer ID :0x11
OEM/Application ID :<0>
Product Name :008GE0
Product Rev :0.0
Serial Number :0x5ADD4140
DateCode.Month :11
DateCode.Year :1999
Detected as MMCv5.0x Device!
OCR:
00000000 C0 FF 80 80 ....
前回述べたとおりMMCv4.xx以降はExtCSDレジスタを読み出すのは重要です。MMCv4以降のバージョン判定はExtCSDREVフィールドを参照し解釈する必要
性があります。ちなみにこの東芝のeMMCはv5とのことですがですが読み出すと
ExtCSDREVは”7”となりちゃんとv5のデバイスであることが分かります。
ちなみにdatecodeが1999とあるのはCIDレジスタの年数を示すフィールドが4bit分
しかないので2012年を境に年数が一巡してしまっているからです。最新のMMCAの
データシートではExtCSDREVから2012年以降を判別せよというようになっていますので
一方、SDカードでは年数を示すフィールドは6bit分あるのであと50年くらい安泰です。
FatFs module test terminal for STM32F746NGH6
LFN Enabled, Code page: 932
AppVersion : W.I.P
Build Date : Mar 31 2016
>fg piano
rc=0 FR_OK
>fo 1 ftbt.mp3
rc=0 FR_OK
>fr 132949600
132949600 bytes read with 22000 kB/sec.
>
シーケンシャルライトも見てみました。F7のサンプルではSDIO_CLKはMAX48MHzかつ4bitモードの設定がeMMCで可能ですがご覧のとおり理論値に近い読み出し
速度が出ました。やるじゃない!
FatFs module test terminal for STM32F746NGH6
LFN Enabled, Code page: 932
AppVersion : W.I.P
Build Date : Mar 31 2016
>fg piano
rc=0 FR_OK
>fo 1 ftbt.mp3
rc=0 FR_OK
>fr 132949600
132949600 bytes read with 20753 kB/sec.
>
因みに前回紹介したMMCPLusも結構速いです。と言うわけでユーザー領域のみですがeMMCでもSDHC/SDXCと同じく読み書きする
ことが出来るようになりました!今秋くらいに市場に出回るであろうSTM32F777等の
最強に強まったF7シリーズではSDMMCが二つに増えるので基板付け置きのeMMC
(とかMCP)が今後は発言力を増してくると思います!!
今回の成果はSTM32F4系やSTM32F1系、そしてLPC4088のMCIにも移植しています
のでどんどん試して下さい!ついでにバグもこっそり教えてもらえると助かります☆
STM32F7を使ってみる10 -いにしえのマルチメディアカードを動かす(うごかす編)-
ぇえええぇぇえええぇええ(どん引き)
↑イレギュラー化した部下に突如愛の告白されるシグマタイチョウ風に
いったいいつからIF誌はねむいさんのお株を奪うようなシモネタを炸裂させる
ようになったのでしょうか…???今回はちょっと笑えたので許しますが。
ああプロテインってそういう・・・
そんなどうでもいいことは置いといてさっさと本題に掛かります!!!!!前回は
microSD->SDの変換アダプタ作っただけで力尽きましたが今回は実際に動かします。
先ずはebayで購入した2GBのMMCPlusカードです!
MMCPlusの規格なので8bitバスで転送もできます…がソケットの互換性を考えると、
4bitバスモードで動かした方が無難でしょう。
因みに妙に汚いように見えますがUSEDでした。MMC自体最早新規生産なんかしてない
ので致し方なしです。カードとして正しく動作すればOKです。
で、その前に問題のソフトウエアの方ですが…こちらでも紛糾してるように
STM32CubeHALライブラリにMMCのサポートは全く有りません。それどころかなんと
過去のSPLには対応していたSDv1.xx系カードのサポートすらもHALライブラリでは
おもいくそぶっちされておりました!!!F**K!!
とりあえずSDv1.xx系のサポートは復活させて動作確認したのですがMMCネイティブ
モードにおけるイニシャライズはどうしたらいいのか全く分からなかったので
暫くの間ネットの海にダイブして情報を沢山漁ってきました。
幸いにもJEDECのMMCの規格は2016年現在は一般人でも公式のJEDECのサイトから
容易に入手することが出来るようにになっていてさらに中華圏のサイトでは
動作するかどうかは不明ですがSTM32向けのeMMCドライバも入手出来たので
それを参考にMMC向けのドライバをF7のHALライブラリ向けに組み込みました。
当然最初は思った通りに動かなかったのですがSTM32のSDIO/SDMMCのハード
ウエア自身にかなりクセがあることが分かり、クセを理解して全種類のカードを
イニシャライズせしめるよう克服していきました。
以下にMMCPlus/MMCv3なカードを使い認識していく過程をデバッガで実動作を
追いながら解説していきます。
STM32のSDカードドライバは基本的にSDv2->SDv1->MMCの順に認識しようとして
いきます。これは現在のSDカードの規格においても推奨される初期化手順と
されています。カードをリセットするCMD0を除くと最初に放たれるのはCMD8です。
MMCとSDv1系ではSDHC用初期化CMD8:SEND_IF_CONDはタイムアウトエラーとなります。
過去のSTM32のSPLに収録されているsdカードのサンプルではその状態から
なぜかCMD55を単品で投げてから改めてCMD55+ACMD41を投げていました。
CMD8が撥ねられた後いきなりCMD55+ACMD41を撃つとSDIOモジュールがエラーで
コケる対策にCMD55を空撃ちしていた感じです(SPLではあったけどHALライブラリ
はそれすらない!)。これはCMD55を受け付けるSDカード系は問題ないのですが
MMCv3以前だとCMD8が撥ねられた後のCMD55の空撃ちがILLEGAL_COMMANDとなり
またまた撥ねられてしまい、先に進めません(※MMCv4以降はこのCMD55が通ります)。
と言うわけでCMD55の代わりにCMD0でカードをリセット状態にしてから改めて
CMD55+ACMD41を送るようにするとうまく先に進めました!勿論SDv1系でも
CMD55の空撃ちではなくCMD0で問題有りませんでした。
MMCではCMD55+ACMD41は当たり前ですがタイムアウトエラーとなります。
先ほどと同じくCMD0を送りMMCをリセットしますが、eMMC対応を考えて引数を
0xF0F0F0F0にしたCMD0の後0x0000000な引数のCMD0を送るようにしてみました。
ここまで来てようやく本来のMMCの初期化ができます。
CMD1を送ってSDカードの「ACMD41」と同じように初期化します。
が、ブロックアドレッシング必須のSDHCと同じくCCSビット(0x40000000)を
ORして引数に渡さないとブロックアドレッシングを必要とするMMCv4.x以降の
規格では初期化が完了できませんのでしっかりとおっ立てた状態で引数として
わたしましょう。ちなみにv3以前のカードにおいてはCCSビットが立っていても
影響は受けずスルーされて初期化がそのまま通るので問題ないです。
上手く初期化が出来たらOCRレジスタの0x80FF8080が読みだされます。
MMCPlusでDualVoltage対応なので上記の値となっています。
因みにv3以前のカードでは0x80FF8000,ブロックアドレッシングな
v4系のデバイスでは0xC0FF8080が帰ってきます。
ここまで認識が通ったらだいぶ気が楽になります。
所でMMCv4.x系のカードでは新たに追加されたExtCSDレジスタから512バイト分の
追加情報を取得可能です。実はこのExtCSDは4GB以上のeMMCの総容量計算では
必須のビットが存在しています。
212〜215バイト目がそのSEC_COUNTフィールドなのですがここに総セクタ数が
記録されていて512を掛けると総バイト数が分かる仕組みになっています。
この2GBのMMCplusではSEC_COUNTフィールドからの算出方法でもCSDレジスタ
から算出する従来の容量計算方法(計算式はSDv1系と全く同じ)でも両方とも
可能です。
初期化を越えたらクロックを転送用の高速クロックに上げていきますが…
MMCv4系では最大52MHz,8bitバスモードまで動かせられます。当ぶろぐでは
4bitバスモードまでとします。MMC専用の呪文を投げる以外はSDカードの
4bit化やHighSpeedMode化と流れは同じです。そして…
無事ファイラーからディレクトリが読みだされました♥
サイズのでかい動画でもカクカクせずスムーズに動きます☆
(後でかなり早いカードなことが分かった)
お次はさらに古いMMCv3世代のカードです。容量はたったの128MB!
そしてもちろん中古品。
初期化を越えたらクロックを転送用の高速クロックに上げていきますが…
10年以上前のものですがちゃんと現在のPCカードリーダーからも認識できます。
MMCv3系のカードなので数が7ピンしかありません。MMCネイティブモードでも
当然バス数が1bitです。早速こちらも動きを追ってみましょう!
CMD1の初期化を終えるとOCRレジスタの0x80FF8000が読みだされました。
初期化を越えたらクロックを転送用の高速クロックに上げていきますが…
MMCv3系はクロック上限値が20MHzできっちり線引きされていてそれ以上はまず
動作しないので20MHz以下にクロックを落とす工夫が必要です。もちろんデータ
バス幅は1ビットのままです。
さすがに遅いですけど無事認識です♥
上記2つのカードの各レジスタをSDカードと同じようにパースしてみました。
CIDレジスタの扱いがSDカードと微妙に違うので注意です。
そんでもってMMCv4以上の細かいバージョン識別はExtCSDの"ExtCSDVER"
フィールドを読みだして解釈する必要があります。
eMMCの使用をにらんでこちらも正しく解釈できるようにしておきました。
●2GB MMCPlus
>ds 0
rc=0
Drive size: 3939328 sectors
Erase block size: 256 sectors
Default r/w block size: 1024 bytes
Card type: MMC(Byte)
CSD:
00000000 90 2F 00 2A 1F 5A 83 C1 B6 DB 9F FF 96 80 00 3F ./.*.Z.........?
CID:
00000000 37 FF FF 4D 4D 43 30 32 47 10 F3 02 67 50 2C F5 7..MMC02G...gP,.
Parsing MMC CID Register
Manufacturer ID :0x37
OEM/Application ID :
Product Name :MMC02G
Product Rev :1.0
Serial Number :0xF3026750
DateCode.Month :2
DateCode.Year :2009
Detected as MMCv4.0 Device!
OCR:
00000000 80 FF 80 80 ....
●128MB MMCv3
>ds 0
rc=0
Drive size: 250880 sectors
Erase block size: 32 sectors
Default r/w block size: 512 bytes
Card type: MMC(Byte)
CSD:
00000000 8C 26 01 2A 0F 59 81 E9 F6 DA 81 E3 9E 40 00 7D .&.*.Y.......@.}
CID:
00000000 11 00 00 30 31 32 38 4D 32 0A 05 80 FE CB 28 7D ...0128M2.....(}
Parsing MMC CID Register
Manufacturer ID :0x11
OEM/Application ID :<0><0>
Product Name :0128M2
Product Rev :0.10
Serial Number :0x0580FECB
DateCode.Month :2
DateCode.Year :2005
Detected as MMCv3.xx Device!
OCR:
00000000 80 FF 80 00 ....
>
いろいろありましたがMMCの動かし方も上手くモノにすることができるように
なりました!次はいよいよMMCから進化したeMMCの動作に挑みます!!
今回の更新はすでにおきぱに上げてあります。eMMCのSD変換アダプタを持ってるひとは
いいことあるかも・・・!?
●おまけ
前回言及したCubeF7のバグですが、「とりあえずuint64_tでキャストしときゃ
いいだろ」が祟って出てしまったカルマなのですが実際どうなるかをSTM32上で
確かめて見ました。
先ず使用する変数/定数は以下とします。
#define SECTOR_SIZE 512
uint64_t unk0;
uint32_t tnk = 8388612; /*512を掛けるとオーバーフロー*/
まずキャスト無しの場合…
unk0 = tnk * SECTOR_SIZE;
この場合は、普通にuint32_tの演算として扱われオーバーフローしたぶんは
そのまま頭が切られます。よって0x100000800ではなく0x800がunk0に代入
されました。
次に括弧でくくってuint64_tでキャストしてみます。今回フォーラムで指摘
されてたのがこのバグです。
unk0 = (uint64_t)(tnk * SECTOR_SIZE);
これもunk0に0x800が代入されてしまいました。*の演算を括弧でくくってしま
ったためにやっぱり0x800になっちゃいました。
正しいキャストの仕方がこちらです。
unk0 = (uint64_t)tnk * SECTOR_SIZE;
uint32_t変数のtnkをuint64_tにキャストしたうえでSECTOR_SIZEを掛けることで
0x100000800がunk0に正しく代入されます。
これ結構引っ掛かりやすいポイントなので私も気を付けるようにします。
フォーラムで指摘されるまで私も気づいて無くて同じミスしてましたがorz
因みにMMCv4.x系のSEC_COUNTの計算で
(代入先が64bit変数の場合)
(uint64_t)((uint64_t)(ext_csd.EXT_CSD.SEC_COUNT[3] << 24 | ¥
ext_csd.EXT_CSD.SEC_COUNT[2] << 16 | ¥
ext_csd.EXT_CSD.SEC_COUNT[1] << 8 | ¥
ext_csd.EXT_CSD.SEC_COUNT[0]));
もしくは
(uint64_t)((ext_csd.EXT_CSD.SEC_COUNT[3] << 24 | ¥
ext_csd.EXT_CSD.SEC_COUNT[2] << 16 | ¥
ext_csd.EXT_CSD.SEC_COUNT[1] << 8 | ¥
ext_csd.EXT_CSD.SEC_COUNT[0]));
もしくは
((ext_csd.EXT_CSD.SEC_COUNT[3] << 24 | ¥
ext_csd.EXT_CSD.SEC_COUNT[2] << 16 | ¥
ext_csd.EXT_CSD.SEC_COUNT[1] << 8 | ¥
ext_csd.EXT_CSD.SEC_COUNT[0]));
と誤った式にしてしまうとext_csd.EXT_CSD.SEC_COUNT[3]の最上位ビットに1が立つ
ような値がSDカード/eMMCから得られた場合、uint64だろうがint64だろうが負の値と
みなされた状態で整数拡張されて上位32bitが0xFFFFFFFFでパディングされた状態で
64bit変数にキャストされてしまい、結果として意図しない値がストアされてしまいます。
ですので、
(uint64_t)((uint32_t)(ext_csd.EXT_CSD.SEC_COUNT[3] << 24 | ?
ext_csd.EXT_CSD.SEC_COUNT[2] << 16 | ¥
ext_csd.EXT_CSD.SEC_COUNT[1] << 8 | ¥
ext_csd.EXT_CSD.SEC_COUNT[0]));
もしくは
(uint32_t)((ext_csd.EXT_CSD.SEC_COUNT[3] << 24 | ?
ext_csd.EXT_CSD.SEC_COUNT[2] << 16 | ¥
ext_csd.EXT_CSD.SEC_COUNT[1] << 8 | ¥
ext_csd.EXT_CSD.SEC_COUNT[0]));
として頭をきっちり削っておけば問題ありません。
ってわけで型の合わない変数に何も考えずキャストとか代入したらこうなります
なったorz
-
免責・連絡先は↑のリンクを
↓SNSもやってます↓
powered by まめわざ- ARM/STM32 (116)
- OpenOCD (27)
- ARM/NxP (34)
- ARM/Cypress (5)
- ARM/Others (3)
- ARM/Raspi (1)
- AVR (13)
- FPGA (4)
- GPS/GNSS (19)
- MISC (81)
- STM8 (2)
- Wirelessなアレ (16)
- おきぱ (1)
- ブラウザベンチマーク (28)
- 日本の自然歩道 (25)
- STM32U0はぢめました
⇒ ねむい (08/07) - STM32U0はぢめました
⇒ ひかわ (07/28) - STM32H5を使ってみる3 -待ち受ける初見殺しの罠たち-
⇒ ねむい (05/17) - STM32H5を使ってみる3 -待ち受ける初見殺しの罠たち-
⇒ どじょりん (05/16) - STM32H5を使ってみる3 -待ち受ける初見殺しの罠たち-
⇒ どじょりん (05/16) - いろいろ試す61(と今年の反省会)
⇒ ねむい (01/02) - いろいろ試す61(と今年の反省会)
⇒ ひかわ (01/02) - いろいろ試す61(と今年の反省会)
⇒ ひかわ (01/01) - STM32H5を使ってみる3 -待ち受ける初見殺しの罠たち-
⇒ ねむい (12/31) - STM32H5を使ってみる3 -待ち受ける初見殺しの罠たち-
⇒ ひかわ (12/31)
- October 2024 (1)
- September 2024 (1)
- August 2024 (1)
- July 2024 (1)
- June 2024 (1)
- May 2024 (1)
- April 2024 (1)
- March 2024 (1)
- February 2024 (2)
- January 2024 (1)
- December 2023 (4)
- November 2023 (2)
- October 2023 (2)
- September 2023 (1)
- August 2023 (2)
- July 2023 (1)
- June 2023 (2)
- May 2023 (3)
- April 2023 (1)
- March 2023 (1)
- February 2023 (1)
- January 2023 (1)
- December 2022 (2)
- November 2022 (1)
- October 2022 (1)
- September 2022 (1)
- August 2022 (1)
- July 2022 (1)
- June 2022 (1)
- May 2022 (1)
- April 2022 (1)
- March 2022 (1)
- February 2022 (1)
- January 2022 (1)
- December 2021 (2)
- November 2021 (2)
- October 2021 (1)
- September 2021 (1)
- August 2021 (1)
- July 2021 (1)
- June 2021 (1)
- May 2021 (1)
- April 2021 (1)
- March 2021 (1)
- February 2021 (1)
- January 2021 (1)
- December 2020 (3)
- November 2020 (1)
- October 2020 (1)
- September 2020 (1)
- August 2020 (1)
- July 2020 (1)
- June 2020 (2)
- May 2020 (1)
- April 2020 (1)
- March 2020 (1)
- February 2020 (1)
- January 2020 (1)
- December 2019 (3)
- November 2019 (1)
- October 2019 (1)
- September 2019 (2)
- August 2019 (1)
- July 2019 (1)
- June 2019 (1)
- May 2019 (1)
- April 2019 (1)
- March 2019 (1)
- February 2019 (1)
- January 2019 (1)
- December 2018 (3)
- November 2018 (2)
- October 2018 (1)
- September 2018 (1)
- August 2018 (1)
- July 2018 (1)
- June 2018 (1)
- May 2018 (1)
- April 2018 (2)
- March 2018 (1)
- February 2018 (1)
- January 2018 (1)
- December 2017 (2)
- November 2017 (2)
- October 2017 (1)
- September 2017 (1)
- August 2017 (1)
- July 2017 (1)
- June 2017 (1)
- May 2017 (1)
- April 2017 (1)
- March 2017 (2)
- February 2017 (2)
- January 2017 (2)
- December 2016 (7)
- November 2016 (2)
- October 2016 (2)
- September 2016 (1)
- August 2016 (1)
- July 2016 (1)
- June 2016 (1)
- May 2016 (2)
- April 2016 (1)
- March 2016 (2)
- February 2016 (1)
- January 2016 (1)
- December 2015 (3)
- November 2015 (1)
- October 2015 (3)
- September 2015 (2)
- August 2015 (2)
- July 2015 (3)
- June 2015 (3)
- May 2015 (4)
- April 2015 (2)
- March 2015 (4)
- February 2015 (1)
- January 2015 (3)
- December 2014 (3)
- November 2014 (2)
- October 2014 (1)
- September 2014 (2)
- August 2014 (2)
- July 2014 (3)
- June 2014 (2)
- May 2014 (1)
- April 2014 (1)
- March 2014 (4)
- February 2014 (4)
- January 2014 (3)
- December 2013 (5)
- November 2013 (4)
- October 2013 (3)
- September 2013 (2)
- August 2013 (2)
- July 2013 (2)
- June 2013 (3)
- May 2013 (2)
- April 2013 (2)
- March 2013 (2)
- February 2013 (2)
- January 2013 (3)
- December 2012 (4)
- November 2012 (2)
- October 2012 (2)
- September 2012 (4)
- August 2012 (1)
- July 2012 (3)
- June 2012 (2)
- May 2012 (3)
- April 2012 (3)
- March 2012 (2)
- February 2012 (3)
- January 2012 (3)
- December 2011 (5)
- November 2011 (3)
- October 2011 (2)
- September 2011 (2)
- August 2011 (2)
- July 2011 (2)
- June 2011 (2)
- May 2011 (2)
- April 2011 (2)
- March 2011 (2)
- February 2011 (2)
- January 2011 (3)
- December 2010 (7)
- November 2010 (1)
- October 2010 (1)
- September 2010 (1)
- August 2010 (3)
- July 2010 (4)
- May 2010 (1)
- April 2010 (2)
- March 2010 (2)
- February 2010 (2)
- January 2010 (3)
- December 2009 (3)
- November 2009 (8)
- October 2009 (7)
- September 2009 (5)
- August 2009 (4)
- July 2009 (6)
- June 2009 (6)
- May 2009 (14)
- January 1970 (1)
Copyright(C) B-Blog project All rights reserved.