STM32F769 Discovery Kit > Touch動作を検知する > HAL + BSPの使用

```txt:動作環境
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 Disocvery Kitに搭載のLCDにてTouch動作を検知する

## 関連情報

- [FAQ: Enable touch screen on the STM32F746G-Discovery](https://community.st.com/s/article/FAQ-Enable-touch-screen-on-the-STM32F746G-Discovery)
    - Touch動作の検知に関する実装 (STemWinを使用)
- [[メモ] タイマー割り込みでLチカ (STM32L1-TIM2使用)](https://qiita.com/mt08/items/636a76deb2661392b98e#comment-5255e819522e60371e5a) by @mt08 さん
    - タイマー処理の参考に

情報感謝です。


## 前準備

- [STM32F769 Discovery Kit > LCDを白色発光させる (LCD駆動の初歩) > HAL + BSPの使用](https://qiita.com/7of9/items/4aa1674939ea0af69fae)

上記の実装を済ませておく。
プロジェクト名は「F769NI_TouchLCD_190716_1958」とする (任意)。

クロックの設定は[こちら](https://qiita.com/7of9/items/4aa1674939ea0af69fae#system-clock-mux%E3%81%ABpllclk%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%97%E3%81%9F%E4%BE%8B)を使うとする。

## 手順

[FAQ: Enable touch screen on the STM32F746G-Discovery](https://community.st.com/s/article/FAQ-Enable-touch-screen-on-the-STM32F746G-Discovery)
に記載の手順に基づいている。

ただし、リンク先はSTemWinを使用するようになっているが、こちらの環境ではSTemWinを使わない。
対応する手順は変更した。

### STM32CubeMX

- `1. I2Cを有効にする (図1-1)

図1-1. I2C有効化後
![Screenshot from 2019-07-18 21-32-52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/92969372-c783-b11b-c770-533bc80db982.png)

- `2. TIM3を有効にして250msecごとに割込みが出る設定にする (図2-1)
    - クロック設定ではAPBは 100MHZとしている (Clock Configurationにて)
    - Prescaler = (50000-1)のため2000Hz
    - Counter Period = (500-1)のため1/4秒=250msecにタイマー割込が起きる

図2-1. TIM3の設定
![Screenshot from 2019-07-18 21-34-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/398ef187-ae59-0a37-01ca-8e8880201180.png)

- `3. TIM3のglobal interruptを有効にしておく (図3-1)

図3-1. TIM3のglobal interrupt設定 (Enabled後)

![Screenshot from 2019-07-18 21-39-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/96e8e7fd-ec0d-235b-8342-88e86eb8d20b.png)


### ソースコード側の操作

- `1. Drivers/BSP/Components/ft5336関連を取込む
    - 前準備で実施しているため、この手順は不要
- `2. Drivers/BSP/Components/Commmon/ft.hを取込む
    - 前準備で実施しているため、この手順は不要
- `3. Drivers/BSP/STM32769I-Discoveryにあるts関連を取込む
    - stm32f769i_discovery_ts.c/.h : 取り込む
    - stm32f769i_discovery.c/.h : 前準備で取込み済

図3-1. 手順３までのDrivers配下の状況 (Drivers/BSP/Components/Common: ts.hがある)
![Screenshot from 2019-07-18 21-22-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/fc55e60f-37e4-997d-298a-a31dacd3da26.png)

図3-2. 手順３までのDrivers配下の状況 (Drivers/BSP/Components/ft5336がある)
![Screenshot from 2019-07-18 21-22-44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/04799675-ddeb-e993-094b-d8b15bbee213.png)

図3-3. 手順３までのDrivers配下の状況 (Drivers/BSP/STM32F769I-Discovery: stm32f769i_discovery_ts.c/.hがある)
![Screenshot from 2019-07-18 21-22-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/e217e4ca-9b26-96b8-57e3-1eb582e687ff.png)

- `4. インクルードパスを追加する
    - Drivers/BSP/Components/Common
    - Drivers/BSP/Components/ft5336
    - Drivers/BSP/STM32769I-Discovery
    - 追加方法 (Commonの場合)
        - C/C++Projectsペインにてプロジェク上で右クリック
        - Properties
        - C/C++ General
        - Paths and Symbols
        - [Add] 
        - [Workspace]
        - `/F769NI_LCD_BSP_190714_2018/Drivers/BSP/Common`


### ソースコードの追加 (main.c)

- `1. 関数プロトタイプ`void TouchTimer_Init(void);`を追加する。

```c
/* USER CODE BEGIN PFP */
void TouchTimer_Init(void);
/* USER CODE END PFP */
```

- `2. int main(void)の `/* USER CODE END 2*/`の前にTouchTimer_Init()を記載する

```c
  BSP_LCD_Clear(LCD_COLOR_WHITE);

  TouchTimer_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
```


- `3. `USER CODE BEGIN 4`以降に下記を実装する。

```c
void TouchTimer_Init()
{
	BSP_TS_Init(800, 480);

	if (HAL_TIM_Base_Init(&htim3) != HAL_OK) {while(1);}
	if (HAL_TIM_Base_Start_IT(&htim3) != HAL_OK) {while(1);}
}
void PollTouchScreen(void)
{
	//GUI_PID_STATE TS_State; // for STemWin
	static TS_StateTypeDef prev_state;
	TS_StateTypeDef ts;
	BSP_TS_GetState(&ts);
	//TS_State.Pressed = ts.touchDetected; // for STemWin
	static int mode = 0;

	if (prev_state.touchDetected != ts.touchDetected)
	{
		prev_state.touchDetected = ts.touchDetected;
		if (ts.touchX[0] != 0 && ts.touchY[0] != 0) {
			prev_state.touchX[0] = ts.touchX[0];
			prev_state.touchY[0] = ts.touchY[0];
		}
		//TS_State.Layer = 0; // for STemWin
		//TS_State.x = prev_state.touchX[0]; // for STemWin
		//TS_State.y = prev_steat.touchY[0]; // for STemWin

		if (ts.touchDetected) {
			if (mode == 0) {
				mode = 1;
				BSP_LCD_Clear(LCD_COLOR_WHITE);
			} else {
				mode = 0;
				BSP_LCD_Clear(LCD_COLOR_RED);
			}
		}
	}

}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if (htim->Instance == TIM6) {
		HAL_IncTick();
	}
	if (htim->Instance == TIM3) {
		PollTouchScreen();
	}
}
```

### 実行例

タッチの度に色が「赤ー＞白」「白ー＞赤」と変化する。

一回目のタッチ（白−＞赤）
![IMG_0931.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/a1cbb7db-ccd6-cf05-1a24-87f3fa5eb53a.jpeg)

二回目のタッチ（赤ー＞白）
![IMG_0930.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/41751857-903f-1a8a-cace-2554011dbb25.jpeg)