보드를 구입한 본래의 목적이었던 TouchGFX를 사용하기 위해서 프로젝트 생성. 여러가지 유투브나 문서를 찾아봤지만, 한번에 매끄럽게 되는건 없는듯하다. ST에서 TouchGFX를 인수하였다곤 하지만 하나의 개발도구로 합치는데는 꽤 시간이 걸릴듯 한데… 뭐 그거야 나중 일이고.. 일단은 프로젝트를 생성하고 개발하기 위한 준비단계까지는 되어야 하니….
프로젝트 생성은 예전 데모와 마찬가지로 File > New > STM32 Project 로 시작한다. 보드도 역시 현재 보유한 32F746GDISCOVERY를 선택하고 다음으로 진행.
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-1.png?resize=525%2C358&ssl=1)
프로젝트 이름을 입력하고, 개발 언어는 C++로 선택. Finish를 선택하여 생성 시작. 이후 나오는 다이얼로그창에선 모두 Yes로 답하면 됨.
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-2.png?resize=481%2C535&ssl=1)
예전 데모와 같이 디바이스 설정을 위한 화면이 나타나면… 이제부터 설정 시작. (앞선 포스팅에선 편하다고 했었는데, 편하긴 개뿔… 좀더 한방에 되면 얼마나 좋아….)
(1) System Core > CORTEX_M7
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-20.png?resize=525%2C483&ssl=1)
(2) Connectivity > ETH
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-4.png?resize=525%2C63&ssl=1)
(3) Connectivity > QUADSPI
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-5.png?resize=525%2C630&ssl=1)
(4) Multimedia > LTDC
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-6.png?resize=525%2C752&ssl=1)
(5) TouchGFX 관련
이건 먼저, Additional Software를 클릭하고, 다음의 화면과 같이 TouchGFX를 선택.
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-7.png?resize=525%2C319&ssl=1)
그러면, 좌측에 Additional Software 탭과, TouchGFX 관련 설정 항목이 생성됨. Graphics Application를 체크하고 다음과 같이 설정.
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-8.png?resize=525%2C544&ssl=1)
(6) Middleware > FREERTOS
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-9.png?resize=525%2C347&ssl=1)
스택크기만 4096으로 변경.
이제 Project > Generate Code (Alt+K)를 실행하여 코드 생성. 생성이 완료되면, 프로젝트 창이 다음과 같이 되어야 함.
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-10.png?resize=340%2C276&ssl=1)
이제 TouchGFX의 ApplicationTemplate.touchgfx.part를 더블클릭하여 TouchGFX 디자이너를 실행한다. 만약 기존에 설치가 안되어있을 경우, 홈디렉토리 아래의 다음 주소를 가보면, 설치 파일이 존재한다.
C:\Users\bkahn\STM32Cube\Repository\Packs\STMicroelectronics\X-CUBE-TOUCHGFX\4.13.0\Utilities\PC_Software\TouchGFXDesigner
설치를 완료하고 다시 저 파일을 더블클릭하면…
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-11.png?resize=525%2C284&ssl=1)
와 같이 디자이너가 실행되고, UI를 디자인할 수 있음. 일단은 Blank UI를 선택한다. 다음과 같이 빈 UI 화면이 나오고 왼쪽의 위젯 화면에서 원하는 컴포넌트를 가져다 붙이면 됨.
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-12.png?resize=525%2C310&ssl=1)
테스트용도이니 대충 디자인하고… (이 툴 또한 익숙해져야 하는 것이기에….)
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-13.png?resize=525%2C310&ssl=1)
다 되었으면, 오른쪽 상단의 Generate Code를 클릭한다. 아래쪽 상태바에 Generate Done이 뜨면, 다시 CubeIDE로 이동한다. 프로젝트에서 오른쪽 버튼을 누르고 Refresh (F5)를 클릭하면, 파일이 추가됨을 볼 수 있다.
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-14.png?resize=350%2C402&ssl=1)
이제 몇가지 코드를 추가 및 수정 필요.
(2-1) STM32F746NGHX_FLASH.ld를 수정
그래픽 등 리소스가 제법 큰 크기를 차지하므로, FLASH 영역에는 다 들어가지 못함. 따라서 보드에 부착된 외장 플래시에 저장해야 하는데, 이를 위해 저 파일을 수정해야 함. 다른 부분만 표시하면…
...
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
QUADSPI (r) : ORIGIN = 0x90000000, LENGTH = 16M
}
...
.ARM.attributes 0 : { *(.ARM.attributes) }
ExtFlashSection :
{
*(ExtFlashSection ExtFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >QUADSPI
FontFlashSection :
{
*(FontFlashSection FontFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >QUADSPI
TextFlashSection :
{
*(TextFlashSection TextFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >QUADSPI
...
(2-2) Drivers에 BSP와 Components 추가.
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-15.png?resize=310%2C278&ssl=1)
해당 파일은 TouchGFX 디자이너에서 빈프로젝트를 생성하면 얻을 수 있음. 추가한 다음 C++ 빌드 옵션에 해당 디렉토리 추가.
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-16.png?resize=525%2C409&ssl=1)
총 4개의 디렉토리를 추가해야 함.
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-17.png?resize=525%2C331&ssl=1)
(2-3) main.c 파일 수정
Core > Src > main.c 를 열고 다음과 같이 추가.
...
/* USER CODE BEGIN Includes */
#include <stm32746g_discovery_qspi.h>
/* USER CODE END Includes */
...
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define REFRESH_COUNT 1835
#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
/* USER CODE END PD */
...
/* USER CODE BEGIN PV */
static FMC_SDRAM_CommandTypeDef Command;
/* USER CODE END PV */
static void MX_QUADSPI_Init(void)
{
...
/* USER CODE BEGIN QUADSPI_Init 2 */
BSP_QSPI_Init();
BSP_QSPI_MemoryMappedMode();
HAL_NVIC_DisableIRQ(QUADSPI_IRQn);
/* USER CODE END QUADSPI_Init 2 */
}
static void MX_FMC_Init(void)
{
...
/* USER CODE BEGIN FMC_Init 2 */
__IO uint32_t tmpmrd = 0;
/* Step 1: Configure a clock configuration enable command */
Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
/* Step 2: Insert 100 us minimum delay */
/* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
HAL_Delay(1);
/* Step 3: Configure a PALL (precharge all) command */
Command.CommandMode = FMC_SDRAM_CMD_PALL;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
/* Step 4: Configure an Auto Refresh command */
Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 8;
Command.ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
/* Step 5: Program the external memory mode register */
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 | \
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | \
SDRAM_MODEREG_CAS_LATENCY_3 | \
SDRAM_MODEREG_OPERATING_MODE_STANDARD | \
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = tmpmrd;
/* Send the command */
HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
/* Step 6: Set the refresh rate counter */
/* Set the device refresh rate */
HAL_SDRAM_ProgramRefreshRate(&hsdram1, REFRESH_COUNT);
//Deactivate speculative/cache access to first FMC Bank to save FMC bandwidth
FMC_Bank1->BTCR[0] = 0x000030D2;
/* USER CODE END FMC_Init 2 */
}
void StartDefaultTask(void const * argument)
{
...
/* USER CODE BEGIN 5 */
MX_TouchGFX_Process();
...
}
이제 저장하고 프로젝트 빌드 Project -> Build Project. 에러없이 빌드가 완료되면 다음과 같이 각 메모리 영역의 사용량 등이 나옴.
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-18.png?resize=525%2C82&ssl=1)
Run > Run을 눌러 보드에 다운로드하고 실행.
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/image-19.png?resize=525%2C364&ssl=1)
이때, Debugger 항목에서 External Loader를 체크하고, 현재보드에 연결된 외장 FLASH 모델을 선택. Apply하고 확인을 눌러 계속 진행.
다운로드가 완료되고 자동으로 보드가 리셋이 되면서 아까 디자인 했던 그대로 화면이 나오는 것을 확인할 수 있음.
![](https://i0.wp.com/ahnbk.com/wp-content/uploads/2020/05/img_6299.jpg?resize=525%2C394&ssl=1)
이렇게 일단은 셋업을 해놓고 하나씩 붙여나가면 될듯. 끝!