Longan Nanoを使ってみる  ～謎の画像表示関数～

# 注意
このページは、quiita.com で公開されています。URLがqiita.com以外のサイト、例えばjpdebug.comなどのページでご覧になっている場合、悪質な無許可転載サイトで記事を見ています。正しい記事は、https://qiita.com/BUBUBB/items/7ce85ada67a3f6d1944d からリンクしています。

無許可転載サイトでの権利表記（CC BY SA 2.5、CC BY SA 3.0とCC BY SA 4.0など）は、不当な表示です。
正確な内容は、qiitaのページで参照してください。

# 謎の画像表示関数

longan-nanoのAPI、lcd.cはよくできているのだが、void LCD_ShowPicture(u16 x1,u16 y1,u16 x2,u16 y2)という関数がよくわからない。説明としては「显示40x40图片」となっているのだが、実際にはそうならない。
imageという配列に入れた、12800バイトのデータ（画面の半分）を所定の矩形（x1,y1-x2-y2)に書き込む。　この時、書き込むサイズは12800バイトで固定なのにもかかかわらず、矩形のサイズは矩形の横X縦X２バイトなので、12800バイトよりも小さくなることもある。そうなると、矩形の左上から再度書き込みが繰り返され、書かれた領域が上書きされてしまう。書き込むサイズを矩形のドット数ｘ２（16ビットカラーなので）にすればよいのだが…

事実上、この関数は、画面の半分をきっちりと埋めるときにしか使用できないことになってしまう。


今回のブロック崩しでは使用しないが、実際に、ゲームなどで画像を画面に表示するためには、LCD_ShowPictureではなく、次のようなプログラムを自分で作る必要があるだろう。この例では、bmpに用意したRGB565の画像情報を40x40ドットの絵として、0,0に表示している。

```
const u16 bmp[]={0xB186,0xC9C7,…
};
  :
LCD_Address_Set(x1,y1,x2,y2);
for (int i = 0; i < (x2-x1+1)*(y2-y1+1) ; i++) {
  LCD_WR_DATA(bmp[i]);
}
```
ただ、謎なのは、なぜ、この程度の簡単な処理で自由な大きさのデータが表示できるようになるのに、わざわざ使い道がほとんどないLCD_ShowPictureを用意したのか、ということだ。「显示40x40图片」という説明も関数の動作にマッチしておらず、意味が分からない。

さらに、LCD_ShowLogo(void)に至っては、単にSipeedのロゴ画像を表示するというもので、Sipeedの中の人以外は使い道がない。APIとして用意する必要もないし、何よりメモリーの無駄だ。



# ベタデータの作成
RGB565のベタデータも、表現としてはかなり古く、扱えるプログラムがほとんどない。昔は結構あったと思うのだが・・・
探すのも面倒なので、画像ファイルをベタデータやソースコードにするツールを作ることにした。屁みたいなプログラムなので一切の権利は放棄する。

[Githubからダウンロード](https://github.com/HisayukiNomura/BmpConverter/tree/0.1)

![bmp1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2096509/9992c033-ea04-f515-b4e7-3ea4a529cfdb.png)

①クリックして画像ファイルを指定。画像ファイルは、bmp/jpeg/png/gifなどが使用できる。

②サイズの変換が必要な場合、ここで指定する。このサイズは、画像ファイルを読み込むと自動的に読み込んだ画像に合わせて変更されるので、サイズ変換が必要ない場合は変更する必要はない。

③プリセットで、変換する形式を指定する。次のような種類が指定できる。ここで値を設定すると、ほかの項目（色の形式）などは自動的に指定されたものに合わせて変更される。
-  LCD_ShowPictureで使用できるバイト配列。これを選択した場合、画像ファイルのサイズは12800バイト（160x40など）になっている必要がある。
- 8ビット配列（LCD_WR_DATA8）。8bitの配列定義のソースコードとしてベタデータを作成する。作成したデータは、LCD_WR_DATA8で使用できる。
- 16ビット配列（LCD_WR_DATA)。16bitの配列定義のソースコードとしてベタデータを作成する。作成したデータは、LCD_WR_DATAで使用できる。
- ベタファイル。RGBのベタファイルとして、バイナリファイルを作成する。作成したデータは、microSDにコピーし、ファイルとして読み込んで使用する。

④色の形式。変換時の色の形式を指定する。ここでエンディアンも指定できる
- bytemap: 24bit-3Bytes 24ビットカラー
- Bytemap: RGB555-2bytes　RGB555形式。
- Bytemap: RGB565-2bytes　RGB565形式。
- Bitmap:　白黒ビットマップ

⑤ビットマップの方向。画像をデータにするとき、スキャンする方向を指定する。


変換を行うと、ベタファイル以外の形式（ソースコード形式）の場合、データと表示方法（コメント化されている）を含むファイルが生成される。

```
const u16 bmp[]={0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
   :
   :
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
};
// WORD:864  (0,0)-(26,31) 
//LCD_Address_Set(0,0,26,31);
//for (int i = 0; i < 864 ; i++) {
//    LCD_WR_DATA(bmp[i]);
//}
```

ベタファイルの場合、拡張子が.binのベタファイルと、拡張子が.cの使用方法が書かれたサンプルソースコードが生成される。生成されたソースコードはfatfsが含まれるプロジェクトにそのまま貼り付けて、ReadNShow()を呼び出すと画面に表示できる。

```
bool ReadNShow()
{
  FATFS fs;
FRESULT fr;
  unsigned char bmp[1728];
  fr = f_mount(&fs, "", 1);
  if (fr != FR_OK) {return FALSE;}  // Mount Error
  FIL fil;
  UINT br = 0;
  fr = f_open(&fil, "apple.bin" , FA_READ);
  if (fr != FR_OK) {return FALSE;}  // Open Error 
  f_lseek(&fil, 0);
  fr = f_read(&fil, bmp, sizeof(bmp), &br);
  if (br != sizeof(bmp)) {f_close(&fil);return FALSE;}  // Read Error
  LCD_Address_Set(0, 0,26,31);
  for (int i = 0; i < sizeof(bmp); i++) {
    LCD_WR_DATA8(bmp[i]);
  }
  f_close(&fil);
  return TRUE;
}

```