STM32L5を使ってみる3 -OCTO-SPIでQUAD-SPIROMを使おう-
●QUAD-SPI接続NORFLASH-ROMを使いこなせ!
FONTX2ファイルなどの大容量のデータはSTM32等の大規模マイコンと
いえどもフラッシュ容量を非常にひっ迫します。
以前からはそういったデータは外付けのQSPI-ROMに格納し、そこから
アクセスするといった手法が定番となっております。
STM32L5では信号線を最大8本持つクロックドシリアルインターフェース
いわゆる"OCTO-SPI"をもちさらに利便性が高まっております!
このOCTO-SPIを使ってQSPI-ROMと接続し内蔵フラッシュメモリのように
使えるMemoryMappedModeで読み出していこうと思います!
●もはや定番☆WinbondのW25Q128JVSIQ
前々回からの紹介の通り、ねむいさんは入手も容易で十分な容量(16MB)、
高速なクロック(133MHz)でデフォルトでQUAD-SPIモードになっていて
コマンドが省略出来て扱いやすいW25Q128JVSIQを使用しました。
W25Qのシリーズにはいろいろありますが末尾"IQ"のものは上でも
書いた通り最初っからQUAD-SPIモードになっており今から紹介する
メモリマップドモードで投げるコマンドがいくつか省略出来て楽です。
digikeyやmouserで購入の際はうっかり違うやつを買わないように
型番には注意してください。
●OCTO-SPIをMemoryMappedModeで使用するためのコード手順
STM32L5に搭載されているOCTO-SPIはSTM32F7などにあったQUAD-SPI
インターフェースからされに拡張され、読み出しのほかに書き込みも
サポートされています。基本的な設定の流れはQUAD-SPIの頃とほぼ
同じですが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_SYSCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
for(;;);
}
/* Peripheral clock enable */
__HAL_RCC_OSPI1_CLK_ENABLE();
/* Alternate GPIO enable */
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/* PE12 as OSPI_IO0 */
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OCTOSPI1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* PB0 as OSPI_IO1 */
GPIO_InitStruct.Pin = GPIO_PIN_0;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* PE14 as OSPI_IO2 */
GPIO_InitStruct.Pin = GPIO_PIN_14;
GPIO_InitStruct.Alternate = GPIO_AF10_OCTOSPI1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* PE15 as OSPI_IO3 */
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Alternate = GPIO_AF10_OCTOSPI1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* PB10 as OSPI_CLK */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Alternate = GPIO_AF10_OCTOSPI1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* PA2 as OSPI_NCS */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Alternate = GPIO_AF10_OCTOSPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
これはNUCLEO-L552ZE-Qから出たQUAD-SPIの足に対応したものです。
OCTO-SPIなのに8本全部使わぬぇのかと思いでしょうがこれはNUCLEO
が引き出してる足がそうなってるからそれに従ったわけなのでー
↓お次は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)
{
OSPI_RegularCmdTypeDef sCommand = {0};
OSPI_MemoryMappedTypeDef sMemMappedCfg = {0};
uint8_t reg_data =0;
/* Initialize OCTO-SPI I/O */
OSPI_IoInit_If();
/* Initialize OCTO-SPI */
hospi.Instance = OCTOSPI1;
hospi.Init.FifoThreshold = 1;
hospi.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
hospi.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON;
hospi.Init.DeviceSize = 24; /* 128Mbit=16MByte=2^24 W25Q128JVSIQ */
hospi.Init.ChipSelectHighTime = 2; /* 2ClockCycle(18nSec@110MHz) Need for W25Q128JVSIQ >10nSec@read */
hospi.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
hospi.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
hospi.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
hospi.Init.ClockPrescaler = 2; /* 110MHzMAX/2 = 55MHz(MAX OSPI-CLK:90MHz) */
hospi.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_HALFCYCLE;
hospi.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
hospi.Init.ChipSelectBoundary = 0;
hospi.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
hospi.Init.Refresh = 0;
if (HAL_OSPI_Init(&hospi) != HAL_OK)
{
for(;;);
}
/* Enable Reset --------------------------- */
/* Common Commands */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.AlternateBytes = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
/* Instruction */
sCommand.Instruction = 0x66; /* Reset Enable W25Q128JVSIQ */
/* Address */
sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;
sCommand.Address = 0;
/* Data */
sCommand.DataMode = HAL_OSPI_DATA_NONE;
sCommand.DummyCycles = 0;
sCommand.NbData = 0;
if (HAL_OSPI_Command(&hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
for(;;);
}
/* Reset Device --------------------------- */
/* Common Commands */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.AlternateBytes = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
/* Instruction */
sCommand.Instruction = 0x99; /* Reset W25Q128JVSIQ */
/* Address */
sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;
sCommand.Address = 0;
/* Data */
sCommand.DataMode = HAL_OSPI_DATA_NONE;
sCommand.DummyCycles = 0;
sCommand.NbData = 0;
if (HAL_OSPI_Command(&hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
for(;;);
}
/* Enter Quad-SPI Mode --------------------------- */
/* Common Commands */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.AlternateBytes = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
/* Instruction */
sCommand.Instruction = 0x31; /* Set Status2 W25Q128JVSIQ */
/* Address */
sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;
sCommand.Address = 0;
/* Data */
sCommand.DataMode = HAL_OSPI_INSTRUCTION_1_LINE;
sCommand.DummyCycles = 0;
sCommand.NbData = 1;
reg_data = 0x02; /* Enable QuadI/O Mode */
if (HAL_OSPI_Command(&hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
for(;;);
}
if (HAL_OSPI_Transmit(&hospi, ®_data, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
for(;;);
}
/* Enter MemoryMappedMode --------------------------- */
/* Read Commands */
sCommand.OperationType = HAL_OSPI_OPTYPE_READ_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_4_LINES;
sCommand.AlternateBytes = 0xFF; /* Need for Fast Read QUAD W25Q128JVSIQ */
sCommand.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_8_BITS;
sCommand.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
/* Instruction */
sCommand.Instruction = 0xEB; /* Fast Read QUAD W25Q128JVSIQ */
/* Address */
sCommand.AddressMode = HAL_OSPI_ADDRESS_4_LINES;
sCommand.Address = 0;
/* Data */
sCommand.DataMode = HAL_OSPI_DATA_4_LINES;
sCommand.DummyCycles = 4; /* DUMMY 4Cycle for Fast Read QUAD W25Q128JVSIQ */
sCommand.NbData = 0;
if(HAL_OSPI_Command(&hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
for(;;);
}
/* Write Commands */
sCommand.OperationType = HAL_OSPI_OPTYPE_WRITE_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.AlternateBytes = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
/* Instruction */
sCommand.Instruction = 0x32; /* Page Write QUAD W25Q128JVSIQ */
/* Address */
sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE;
sCommand.Address = 0;
/* Data */
sCommand.DataMode = HAL_OSPI_DATA_4_LINES;
sCommand.DummyCycles = 0;
sCommand.NbData = 0;
if(HAL_OSPI_Command(&hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
for(;;);
}
/* Set OCTO-SPI as MemoryMappedMode */
sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;
sMemMappedCfg.TimeOutPeriod = 0;
if(HAL_OSPI_MemoryMapped(&hospi, &sMemMappedCfg) != HAL_OK)
{
for(;;);
}
}
流れとしてはリセット有効->リセット->クアッドI/Oモード有効->
クアッド高速読み出しコマンド->クアッドセクタ書き込みコマンド
->HALのMemoryMappedMode移行関数呼び出し
となっております。
"クアッドI/Oモード有効"はW25Q128JVSIQ使うなら本来不要ですが
"念のため"突っ込んどきました…一応なくても動作します。
注意点ですがOCTO-SPIは書き込みもMemoryMappedModeが使用可能の為、
クアッド読み出しコマンドの次にセクタ書き込みコマンドの設定が
必須になります!!
なぜそうなっているかというとHALの関数内で書き込みコマンドの
設定まで要求してきやがるからです(別に今回書き込み要らんのに☠)
これも設定しないと先に進めません!
●動作してるところ
MemoryMappedModeで設定したアドレスはSTM32F7のでやった時と同じく
0x90000000からとなりますので過去のリソースが利用できます。
ねむいさんの使い方ではFONTX2ファイルのAnkの方を0x90000000、
Sjis-Kanjiフォントの方は0x90010000から参照しております。
Ankのファイルサイズはどんなにでかくとも65536byte以上にならない
だろうという打算でこのオフセット値を設定してます。
こんな感じでFONTX2(全角&半角)ファイルを仕込んだW25Q128JVSIQから
内蔵フラッシュと変わらない感覚でデータを読み出し表示ができました。
使用したフォントは小夏フォントを12ptのFONTX2に変換したものです。
STM32L5のOCTO-SPIは命令キャッシュだけでデータキャッシュは無い
ですが文字表示や操作感に特にもたついた感じはしてませんね。
デバッガで0x90000000番地を表示してみました。
MemoyMappedMode有効後は内蔵フラッシュと同じようにデバッガで
内部のデータを参照できてますね。
●ところでどうやってQSPI-ROMにデータ書くの?
…今回の記事はこれが最大の難関です…!
OpenOCDではDiscovery系のボードではI/Fの足もQSPI-ROMの品種も
決め打ちのためにQSPI-ROMの読み書きがサポートされていますが
NUCLEO系のやつは足は出ているもののその先に何がつながるかは
わからないのでサポートしているものは何にもありません。
したがってOpenOCDのmmwのコマンドでそれぞれのROMデバイス向けに
上で書いたコードを16進数並べてがむばって定義していくしかないの
ですがねむいさんはそんなことやる気力がないので…
Jtagkey2とSPI-ROM書き込みプログラム"Flashom"にてFONTX2データを
書き込むことにしました。
使用するフォントは12x12pxの小夏フォントです。
AnkはKONATHN12.FNTを、S-JisのKanjiはKONATZN12.FNTを使用します。
上記ファイルについて、私のL5プロジェクトの下記ディレクトリを
参照してください。
./lib/FONTX2/inc/fonts/KONATSU
※小夏フォントについてはTTFファイルで提供されております。
今回はあらかじめFONTX2コンバータでTTF->FONTX2形式に変換
して全角/半角とも使用しております。
まずはSPI-ROMの認識と読み出し。ちゃんと認識されているのを確認。
ついでに読み出したデータは後で使用するのでbin形式で保存します。
JtagKey2(で使用されているFT2232H)のSCKは最大30MHzのスピートなので
配線長はなるべく短くしましょう。5cm以下だとまず問題ないです。
残念ながらげたゲタ基板とNUCLEO基板を合体した状態ではまともに認識
出来なかったのでNUCLEOから5Vだけ拝借してW25Q128JVSIQと一対一で配線
する形になります。なお、CSはプルアップ必須なのですがねむいさんは
念のためCLK除くすべてのI/Oを22kohmでプルアップしてます。
一方CLKはSDMMCと同じく直列終端抵抗を忘れずに!!
ねむいさんはSDMMCと同じ33ohmを直列終端として使用してます。
お次は書き込み用バイナリの作成。
ねむいさんの知る限りではFlashromはアドレスをオフセット指定して
一部の領域だけを書き込むことができず、全領域一気に書き込みしないと
いけないので先に読み出したbinファイルを利用してそこにFONTX2ファイル
を上書きする形で配置しFONTX2を仕込んだROMファイルを作成します。
バイナリ編集プログラム"Stirling"を駆使して0x0000000にANKフォントを
0x00010000にKanjiフォントをそれぞれ上書きモードでコピペ配置します。
オフセットは1バイトでもずれないように注意してください。
Ankは配置されるとこんな感じ
Kanjiはこんなかんじになります。
Stirlingのビットマップ表示だとバイナリイメージはこんな感じです。
まだまだ一杯データ詰め込めますね。
そして書き込み。JtagKey2とFlashromを使用した際は通常のSPIで
書き込むことになりますがW25Q128JVSIQはセクタ書き込み対応なので
16MByteもある容量でも2分もかからず終わっちゃいます。
ねむいさんの公開しているプログラムでは一応作成済みのQSPI-ROM
イメージ(128QVFONT.bin)を添付して簡単な使用手順も書いてますので
酔狂な方はご参考に…。
まぁ私のぶろぐ普段から見られてる方は楽勝だと思います。
そんなわけでSTM32H5からやる予定だったOCTO-SPIでしたがL5でもうまく
使いこなすことができました!
L5でやりたいことは一通り全部やり切ったのでいい感じで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