STM32H5を使ってみる4 -STM32L5の時みたいにOCTO-SPIを使ってみる-
20240516追:
秋月さんよりNUCLEO-H563ZI販売開始です!!
20240516追:
つい最近、STM32H7シリーズにSTM32H7R/Sというかなり尖った品種が
追加されましたが思い出したようにSTM32H5を触っていこうと思います。
20240321追:
STM32U0シリーズなんてのも出現してました…!!
20240321追:
今回もSTM32H563ZI-NUCLEOを使用したFatFsの移植デモのソースコードを
使用して解説していきます。
●STM32L5から進化したSTM32H5のOCTO-SPI
STM32H5のOCTO-SPIはポピュラーなQUADSPI-ROMだけではなく、最大
16bitなクロックドシリアルROM/PSRAMなんかも接続可能で、もちろん
メモリマップドなアクセスが可能となっております。
シリアルなのに16bitもパラレルってなんなんだよと常に感じてますが
時代は常に進化していっているなと同じく感じております(混乱)。
sirius506さんはそんなOCTO-SPIを完全に使いこなしDOOMというゲームを
移植されており、ほんとに感心してしまいました…
ねむいさんは組み込み系界隈の中では雑魚キャラに過ぎないのでそんな
高度なことはできず、基本中の基本のQSPI-ROMを接続してメモリ
マップドモードで読み出し専用で動かすことからやってきます。
OCTO-SPIについてはST公式のAN5050もしっかり熟読してください。
●STM32H5のOCTO-SPIをメモリマップドモードで動かすコード
移植に当たってはSTM32L5のやつをそのままスライド移植…というわけには
簡単にいかず、L5のOCTO-SPIのコードから少し改変が必要でした。
その前に、STM32H563ZI-NUCLEOでOCTO-SPIを使う際はSB70をジャンパして
PE2(COTO-SPI IO2)を外部に引き出せられるようにするのを忘れないで
くださいね。
それではSTM32H5のOCTO-SPIのメモリマップドモードで使うためのコードを
紹介します。まずはI/O
/**************************************************************************/
/*!
@brief OCTO-SPI GPIO Configuration.
@param None.
@retval None.
*/
/**************************************************************************/
void OSPI_IoInit_If(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/* Initializes the peripherals clock */
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_OSPI;
PeriphClkInit.OspiClockSelection = RCC_OSPICLKSOURCE_HCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
for(;;);
}
/* Peripheral clock enable */
__HAL_RCC_OSPI1_CLK_ENABLE();
/* Alternate GPIO enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/* PD11 as OSPI_IO0 */
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_OCTOSPI1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* PD12 as OSPI_IO1 */
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Alternate = GPIO_AF9_OCTOSPI1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* PE2 as OSPI_IO2(Need SB70 SolderBridge) */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Alternate = GPIO_AF9_OCTOSPI1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* PD13 as OSPI_IO3 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Alternate = GPIO_AF9_OCTOSPI1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* PB2 as OSPI_CLK */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Alternate = GPIO_AF9_OCTOSPI1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* PG6 as OSPI_NCS */
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Alternate = GPIO_AF10_OCTOSPI1;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
}
お次はOCTO-SPIのメモリマップドモードの初期化です。
/**************************************************************************/
/*!
@brief Configure OCTO-SPI as Memory Mapped Mode.
Winbond W25Q128JVSIQ specific setting.
* Address size is 24bit(16MBytes).
* Initially sets QUAD-MODE(not need quadmode command).
* MAX 133MHz CLK.
* Support "XIP",thus suitable for MemoryMappedMode.
@param None.
@retval None.
*/
/**************************************************************************/
void Set_OSPI_MemoryMappedMode(void)
{
XSPI_RegularCmdTypeDef sCommand = {0};
XSPI_MemoryMappedTypeDef sMemMappedCfg = {0};
uint8_t reg_data =0;
/* Initialize OCTO-SPI I/O */
OSPI_IoInit_If();
/* Initialize OCTO-SPI */
hxspi.Instance = OCTOSPI1;
hxspi.Init.FifoThresholdByte = 1;
hxspi.Init.MemoryMode = HAL_XSPI_SINGLE_MEM;
hxspi.Init.MemoryType = HAL_XSPI_MEMTYPE_MICRON;
hxspi.Init.MemorySize = 23; /* 128Mbit=16MByte=2^(23+1) W25Q128JVSIQ */
hxspi.Init.ChipSelectHighTimeCycle = 4; /* 4ClockCycle(16nSec@250MHzMAX) Need for W25Q128JVSIQ >10nSec@read */
hxspi.Init.FreeRunningClock = HAL_XSPI_FREERUNCLK_DISABLE;
hxspi.Init.ClockMode = HAL_XSPI_CLOCK_MODE_0;
hxspi.Init.WrapSize = HAL_XSPI_WRAP_NOT_SUPPORTED;
hxspi.Init.ClockPrescaler = 1; /* 250MHzMAX/(1+1) = 125MHz (Allowed SDR Clock is 150MHz@3.3V) */
hxspi.Init.SampleShifting = HAL_XSPI_SAMPLE_SHIFT_HALFCYCLE;
hxspi.Init.DelayHoldQuarterCycle = HAL_XSPI_DHQC_DISABLE;
hxspi.Init.ChipSelectBoundary = 0;
hxspi.Init.DelayBlockBypass = HAL_XSPI_DELAY_BLOCK_BYPASS;
hxspi.Init.Refresh = 0;
if (HAL_XSPI_Init(&hxspi) != HAL_OK)
{
for(;;);
}
/* Enable Reset --------------------------- */
/* Common Commands */
sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
sCommand.AlternateBytes = HAL_XSPI_ALT_BYTES_NONE;
sCommand.AlternateBytesWidth = HAL_XSPI_ALT_BYTES_NONE;
sCommand.AlternateBytesDTRMode = HAL_XSPI_ALT_BYTES_DTR_DISABLE;
sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
/* Instruction */
sCommand.Instruction = 0x66; /* Reset Enable W25Q128JVSIQ */
/* Address */
sCommand.AddressMode = HAL_XSPI_ADDRESS_NONE;
sCommand.Address = 0;
/* Data */
sCommand.DataMode = HAL_XSPI_DATA_NONE;
sCommand.DataLength = 0;
sCommand.DummyCycles = 0;
if (HAL_XSPI_Command(&hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
for(;;);
}
/* Reset Device --------------------------- */
/* Common Commands */
sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
sCommand.AlternateBytes = HAL_XSPI_ALT_BYTES_NONE;
sCommand.AlternateBytesWidth = HAL_XSPI_ALT_BYTES_NONE;
sCommand.AlternateBytesDTRMode = HAL_XSPI_ALT_BYTES_DTR_DISABLE;
sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
/* Instruction */
sCommand.Instruction = 0x99; /* Reset W25Q128JVSIQ */
/* Address */
sCommand.AddressMode = HAL_XSPI_ADDRESS_NONE;
sCommand.Address = 0;
/* Data */
sCommand.DataMode = HAL_XSPI_DATA_NONE;
sCommand.DataLength = 0;
sCommand.DummyCycles = 0;
if (HAL_XSPI_Command(&hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
for(;;);
}
/* Enter Quad-SPI Mode --------------------------- */
/* Common Commands */
sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
sCommand.AlternateBytes = HAL_XSPI_ALT_BYTES_NONE;
sCommand.AlternateBytesWidth = HAL_XSPI_ALT_BYTES_NONE;
sCommand.AlternateBytesDTRMode = HAL_XSPI_ALT_BYTES_DTR_DISABLE;
sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
/* Instruction */
sCommand.Instruction = 0x31; /* Set Status2 W25Q128JVSIQ */
/* Address */
sCommand.AddressMode = HAL_XSPI_ADDRESS_NONE;
sCommand.Address = 0;
/* Data */
sCommand.DataMode = HAL_XSPI_INSTRUCTION_1_LINE;
sCommand.DataLength = 1;
sCommand.DummyCycles = 0;
reg_data = 0x02; /* Enable QuadI/O Mode */
if (HAL_XSPI_Command(&hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
for(;;);
}
if (HAL_XSPI_Transmit(&hxspi, ®_data, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
for(;;);
}
/* Enter MemoryMappedMode --------------------------- */
/* Read Commands */
sCommand.OperationType = HAL_XSPI_OPTYPE_READ_CFG;
sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_4_LINES;
sCommand.AlternateBytes = 0xFF; /* Need for Fast Read QUAD W25Q128JVSIQ */
sCommand.AlternateBytesWidth = HAL_XSPI_ALT_BYTES_8_BITS;
sCommand.AlternateBytesDTRMode = HAL_XSPI_ALT_BYTES_DTR_DISABLE;
sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
/* Instruction */
sCommand.Instruction = 0xEB; /* Fast Read QUAD W25Q128JVSIQ */
/* Address */
sCommand.AddressMode = HAL_XSPI_ADDRESS_4_LINES;
sCommand.Address = 0;
/* Data */
sCommand.DataMode = HAL_XSPI_DATA_4_LINES;
sCommand.DataLength = 0;
sCommand.DummyCycles = 4; /* DUMMY 4Cycle for Fast Read QUAD W25Q128JVSIQ */
if(HAL_XSPI_Command(&hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
for(;;);
}
/* Write Commands */
sCommand.OperationType = HAL_XSPI_OPTYPE_WRITE_CFG;
sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
sCommand.AlternateBytes = HAL_XSPI_ALT_BYTES_NONE;
sCommand.AlternateBytesWidth = HAL_XSPI_ALT_BYTES_NONE;
sCommand.AlternateBytesDTRMode = HAL_XSPI_ALT_BYTES_DTR_DISABLE;
sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
/* Instruction */
sCommand.Instruction = 0x32; /* Page Write QUAD W25Q128JVSIQ */
/* Address */
sCommand.AddressMode = HAL_XSPI_ADDRESS_1_LINE;
sCommand.Address = 0;
/* Data */
sCommand.DataMode = HAL_XSPI_DATA_4_LINES;
sCommand.DataLength = 0;
sCommand.DummyCycles = 0;
if(HAL_XSPI_Command(&hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
for(;;);
}
/* Set OCTO-SPI as MemoryMappedMode */
sMemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE;
sMemMappedCfg.TimeoutPeriodClock = 0;
if(HAL_XSPI_MemoryMapped(&hxspi, &sMemMappedCfg) != HAL_OK)
{
for(;;);
}
}
STM32H5のOCTO-SPIのHALはL5と微妙に違っており"HAL_OSPI"だったのが
"HAL_XSPI"に変わってたりして移植の際めっちゃ鬱陶しかったのですが
基本的な設定の流れはL5の時とそこまで変わっておりません。
特筆すべきはSTM32H5は250MHzで動作するのでW25Q128JVSIQ(最大133MHz)
に対して125MHzという過激なスピードのクロックが供給可能で非常に高速な
動作が可能です!しかもデータキャッシュもついてます!
ちなみにSTM32H5のOCTO-SPIの最大供給クロックは150MHz(3.3V時)まで
可能となっております。
●実際に動かしてみる
ていうかポリウレタン被覆銅線でQSPI-ROMへ配線引き伸ばしてほんとに
125MHzで動いてンのかと自分でも訝しんでいましたので実際にクロックの
波形を測定してみました。
使用したオシロはPicoscope5444D MSOです。そうだね宣伝だね。
Picoscope5444D MSOのアナログ帯域200MHzなのに125MHzの高速信号測るの
どうなのとお思いでしょうが測定限界を大幅に超えていますがETSモードで
測定した限りではきっちり125MHzのクロックが出ていることがわかります。
ねむいさんはQSPI-ROMをFONTX2を格納するのに使っていますがこんな感じで
文字崩れも起こさずきれいに表示できております!
手配線の限界に挑んだ感じですがまぁSCLKは一応33ohmで直列終端は
しているのでそれが効いて安定して動作しているのでしょう〜。
●おまけ・STM32L5とのパフォーマンス比較
せっかく下駄基板作ってハード的に同じ条件が揃えてるのでSTM32L5と
STM32H5のパフォーマンス比較とかやってみました。
同一のpngファイルでlibpngを使ったデコード時間を比較してみました。
☝STM32L5の場合(動作クロック:110MHz)
☝STM32H5の場合(動作クロック:250MHz)
う〜むやはり圧倒的に違いますね〜というかねむいさんがSTM32H5の
パワーを持て余しててまだまだ機能の一握りも使えてないので頑張って
使いこなしていこうと思います!これからも頑張るぞい!
-
免責・連絡先は↑のリンクを
↓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.
Comments
Post a Comment