STM32F769 Discovery Kit > LCDを白色発光させる (LCD駆動の初歩) > HAL + BSPの使用

```動作環境
Ubuntu 18.04 LTS
STM32CubeMX v5.2.1
STM32CubeIDE v1.0.1
基板: STM32F769 Discovery Kit
```

### STM32F769 Discovery Kit

- https://www.digikey.jp/product-detail/ja/stmicroelectronics/STM32F769I-DISCO/497-16524-ND/6004739
    - STM32F769NIH6 MCU with 216MHz/462 DMIPS
    - WVGA (800x480)の液晶
    - B-LCD40-DSI1
        - MIPI-DSI対応

## 概要

- STM32F769 Discovery搭載のLCD（WVGA)を駆動して、白色発光させる
- BSP (Board Support Package)を使う
- ローレベルの駆動にはHALを使用

## 備考（ご注意）

<font color=red>Note: この記事は学習途中での記事としているため、いくつかの「勘違い」が含まれるでしょう。
この記事の通りに実施した結果、基板破損などを生じるかもしれません。
ご注意ください。</font>

## 前準備

- STM32CubeIDEの環境を構築
- STM32CubeF7のBSPを取得
    - [ここ](https://www.st.com/ja/embedded-software/stm32cubef7.html)から取得しておく (登録が必要)
        - v1.15.0を取得した
    - ~/STM32Cube/Repository以下に取得した`stm32cube_fw_f7_v1150.zip`を解凍しておく
        - `STM32Cube_FW_F7_V1.15.0`ディレクトリが生成される

## 手順

- `1. STM32 Projectプロジェクトを作る
    - Part Number Searchにて「769NI」
    - Reference: STM32F769NIHxを選択
    - プロジェクト名(任意): F769NI_LCD_BSP_190714_2018
- `2. LTDCを設定する
    - Display Type: `RGB565(16bits) - DSI mode`
    - Parameter Settingsを設定する (図2-1)
    - Layer Settingsを設定する (図2-2)

図2-1 LTDC > Parameter Settings
![Screenshot from 2019-07-15 08-03-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/42654da5-10fe-d7ec-fb53-49392184b82c.png)

図2-2 LTDC > Layer Settings
![Screenshot from 2019-07-15 08-03-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/3adfea99-2149-a992-2c1c-cbb8c3dd3039.png)

- `3. DMA2DをActivatedにする
    - 設定はそのまま (図3-1)

図 3-1 DMA2D > Parameter Settings
![Screenshot from 2019-07-15 08-07-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/95cd20f1-853b-8dfc-2808-021d138ab0e7.png)

- `4. FMCにてSDRAM1の設定をする
    - Clock and chip enable: SDCKE0+SDNE0
    - Internal bank number: 4 banks
    - Address: 12bits
    - Data: 16bits
    - Byte enable: 16-bit byte enable
    - Configurationは図4-1の通りにした
        - デフォルトから変更してない?

図4-1 FMC > SDRAM1設定
![Screenshot from 2019-07-15 08-09-41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/271e172c-7c73-b6c2-34fa-6c99bbd488ea.png)

- `5. RCCにてHSE(High Speed Clock)を有効にする
    - HSEを使わないとLCDとの通信がおそすぎてLCD駆動を失敗する
    - High Speed Clock (HSE): BYPASS Clock Source (図5-1)
    - ここで「DSIHOST」が選択できるようになる (後で使用)

図5-1 RCC > HSE設定
![Screenshot from 2019-07-15 08-11-59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/407796a2-5276-f84e-c589-232f3dddfa8b.png)

- `6. Clock Configurationにてクロックの設定をする (図6-1)
    - 注意: この設定についてはまだ理解が浅い。あくまで「動いた」だけのもの

図6-1 Clock Configuration
![Screenshot from 2019-07-15 08-20-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/f437f588-3e9a-02aa-905c-05dd40fbe667.png)

- `7. DSIHOSTにてVideo Modeにする
    - 設定は図7-1 (デフォルト)

![Screenshot from 2019-07-15 10-18-40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/d8a2a0e4-b7aa-6106-eaf8-92f1c36062f7.png)


- `8. 保存してコードを生成する
    - > Do you want generate Code? 
    - [Yes]
- `9. BSPのコードのUtilitiesをプロジェクトに追加する
    - 「前準備」で解凍しておいたディレクトリと関連付ける
    - 対象: `~/STM32Cube/Repository/STM32Cube_FW_F7_V1.15.0/Utilities`
        - プロジェクトのツリーにて右クリック
        - Import...
        - File System
        - From directoryにて上記のUtilitiesを指定
        - 左側でUtilitiesフォルダを選択
        - Into folderはプロジェクトフォルダ/Utilities
            - F769NI_LCD_BSP_190714_2018/Utilities
        - Finish (結果は図9-1)

図9-1 BSPのコードのUtilitiesをプロジェクトに追加後
![Screenshot from 2019-07-15 09-06-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/8f9c36ca-29c9-3b8d-2d85-400210b48d62.png)

- `10. BSPのコードのComponentsとSTM32F769I-Discoveryをプロジェクトに追加する
    - 対象: `~/STM32Cube/Repository/STM32Cube_FW_F7_V1.15.0/Drivers/BSP/Components`
        - 手順は9と同じ
            - Into folderはプロジェクトフォルダ/Drivers/BSP/Components
                - `F769NI_LCD_BSP_190714_2018/Drivers/BSP/Components`
    
図10-1 BSPのコードのComponentsをプロジェクトに追加後
![Screenshot from 2019-07-15 08-31-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/13d849f3-077f-6103-1a09-14ec5d48df9f.png)

- `11. BSPのコードのSDRAMとLCD関連ファイル、共通ファイルをプロジェクトに追加
    - 対象: `~STM32Cube/Repository/STM32Cube_FW_F7_V1.15.0/Drivers/BSP/STM32F769I-Discovery`以下の
        - stm32f769i_discovery.c
        - stm32f769i_discovery.h
        - stm32f769i_discovery_lcd.c
        - stm32f769i_discovery_lcd.h
        - stm32f769i_discovery_sdram.c
        - stm32f769i_discovery_sdram.h
    - Into folderはプロジェクトフォルダ/Drivers/BSP
        - `F769NI_LCD_BSP_190714_2018/Drivers/BSP`
    - ファイルを選択して追加する (図11-1)

図11-1 Driver追加時のファイル選択
![Screenshot from 2019-07-15 09-13-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/d26d7738-b489-b6cb-f182-3bbb834b2fe1.png)


- `12. インクルードパスを設定する
    - C/C++Projectsペインにてプロジェク上で右クリック
    - Properties
    - C/C++ General
    - Paths and Symbols
    - [Add] 
    - [Workspace]
    - `/F769NI_LCD_BSP_190714_2018/Drivers/BSP/STM32F769I-Discovery`

- `13. Src/main.cにLCDとSDRAMのヘッダーを追加

```c
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stm32f769i_discovery_lcd.h"
#include "stm32f769i_discovery_sdram.h"
/* USER CODE END Includes */
```
- `14. 未定義のマクロを定義
    - 場所は任意. 今回はint main(void)の上に追加した

```c
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#define LCD_FOREGROUND_LAYER (1)
#define LCD_BACKGROUND_LAYER (0)
#define LCD_FRAME_BUFFER (0xC0000000)
/* USER CODE END 0 */
```


- `15. Src/main.cのint main(void)にBSP_LCD関連コードを実装 (下記のBSP_LCD_XXX)

```c
int main(void) {
   ...
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA2D_Init();
  MX_FMC_Init();
  MX_LTDC_Init();
  /* USER CODE BEGIN 2 */
  BSP_LCD_Init();
  BSP_LCD_LayerDefaultInit(LCD_BACKGROUND_LAYER, LCD_FRAME_BUFFER);
  BSP_LCD_LayerDefaultInit(LCD_FOREGROUND_LAYER, LCD_FRAME_BUFFER);
  BSP_LCD_SelectLayer(LCD_FOREGROUND_LAYER);
  BSP_LCD_DisplayOn();
  BSP_LCD_Clear(LCD_COLOR_WHITE);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
   ...
```
      
- `16. ビルドして実行するとLCDが白色発光する

  ![IMG_0917.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/108bb278-37eb-5cef-8f21-3e8febf910db.jpeg)

### 参考になった情報

- [LCDへの表示](http://metaloxide.cocolog-nifty.com/blog/2016/09/lcd-ac1f.html) by めたるのBlogさん
- [クロックの設定をしてみる](https://nucleo87.webnode.jp/nucleo%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0/%E3%82%AF%E3%83%AD%E3%83%83%E3%82%AF%E3%81%AE%E8%A8%AD%E5%AE%9A/) @ Nucleo入門 
- https://github.com/fboris/STM32Cube_FW_F4/blob/master/Projects/STM32F429I-Discovery/Examples/LTDC/LTDC_Display_2Layers/Src/main.c
- [STM32F746 Discovery - LTDC](https://m.blog.naver.com/kiatwins/220996596221) by 제플린さん
- [BSP library failed to link with HAL library](https://community.st.com/s/question/0D50X00009XkXcFSAV/bsp-library-failed-to-link-with-hal-library)
    - HAL_DSI_MODULE_ENABLEDを定義するように、と記載
- [[STM32CubeMX] STM32F429-DISC0 LCD 출력하기](https://naudhizb.tistory.com/827)
    - ここでBSP/Components, BSP/STM32F429I-Discovery, Utilitiesをプロジェクト記載することが書かれている
    - 他、写真入りでわかりやすい
- STM32F769の資料 (DocID029041 Rev 6)
    - p103 Table 4
    - Boundary address
    - 0xC000 0000 - 0xCFFF FFFF: FMC bank5
        - ここでFMCの設定が必要だと気づいた
- [What is FB_Address in BSP_LCD_LayerDefaultInit ?](https://community.st.com/s/question/0D50X00009XkXlYSAV/what-is-fbaddress-in-bsplcdlayerdefaultinit-)
    - SDRAMだと0xC0000000を指定するように、と記載あり
- https://os.mbed.com/teams/ST/code/BSP_DISCO_F769NI/file/3e58f8a39705/Drivers/BSP/STM32F769I-Discovery/stm32f769i_discovery_lcd.c/
    - BSP_LCD_XXX()の実装
    - HAL_XXX()を使用していることが分かる
- `~/STM32Cube/Repository/STM32Cube_FW_F7_V1.15.0/Projects/STM32F769I-Discovery/Examples/LCD_DSI/LCD_DSI_CmdMode_DoubleBuffer`
    - 取得したファイルにBSP使用のコードがあり、これがこの試行錯誤の出発点となった
- [STM32F746 Discovery - LTDC](https://m.blog.naver.com/kiatwins/220996596221) by 제플린さん
    - BSPを使わずHALだけで駆動する例
    - これはうまく動作しなかった
- [STM32F746 Discovery - LTDC (비트맵 출력)](https://m.blog.naver.com/PostView.nhn?blogId=kiatwins&logNo=220997280112&proxyReferer=https%3A%2F%2Fwww.google.com%2F) by 제플린さん
    - BSPを使わずHALだけで駆動する例
    - BMP画像を表示

## Clock Configuration 

### System Clock MuxにPLLCLKを設定した例

下記の設定でも表示は正常に実施された

![Screenshot from 2019-07-15 10-05-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/93e01a1c-3a13-9b2c-70d0-282142998307.png)


### 備考 > Error
(追記: 2019-07-16) 

上記の作業を一気にした時にエラーとなった。
DSIをオフにしてビルドした後、再度DSIを有効にしてビルドをするとエラーは出なくなった。

ビルドのタイミングによって失敗するのだろうか。