STM32 DMA2D 테스트

STM32F4xx / STM32F7xx 계열을 그래픽 가속기인 DMA2D 모듈을 포함하고 있으며, ST는 이것을 사용하여 효율적인 그래픽 처리를 할 수 있다고 한다.

 

기존 LCDTest3Touch 예제에서 추가 핀설정은 없으며, DMA2D 모듈만 아래와 같은 설정으로 활성화 시키도록 한다. 참고로 외부 SDRAM을 사용하지 않기 때문에 Color Mode를 RGB565로 설정한다.

그리고, MCU 내부 메모리를 사용하기 때문에 Transfer Mode를 Register to Memory로 설정하도록 한다. 다음 포스트에서는 외부 SDRAM을 사용하는 방법을 알아볼 예정이다.

 

그래픽 처리는 노가성이 많고, LvGL이나 TouchGFX와 같은 라이브러리를 사용하여 개발하는 것이 효율적이기 때문에 이 포스트에서는 ST에서 제공하는 예제코드를 재사용하여 테스트하였다. stm32f429i_discovery_lcd.c 파일은 DMA2D를 사용하여 Line, Rantangle, Circle, Font 등을 그릴수 있는 API를 제공하고 있다.

 

프레임버퍼를 내부메모리를 사용하기 위해 아래와 같이 선언하였으며, 프레임버퍼 크기는 LCD 해상도과 컬러 모드로 결정되며 STM32F429I 데모보드의 LCD는 240x320이며 RGB565이므로 2바이트를 사용하므로 프레임버퍼는 153600 크기를 가진다.

CAN_HandleTypeDef hcan2;
DMA2D_HandleTypeDef hdma2d;
I2C_HandleTypeDef hi2c3;
LTDC_HandleTypeDef hltdc;
SPI_HandleTypeDef hspi5;
UART_HandleTypeDef huart5;

/* USER CODE BEGIN PV */
static uint8_t frame_buffer[153600/*240*320*2*/];
/* USER CODE END PV */

ST에서 제공하는 stm32f429i_discovery_lcd.c와 stm32f429i_discovery_ts.c 소스에서 Initialize 코드는 main.c에 작성되어 있기 때문에 위 파일에서 initialize 코드는 제거하고 handle을 파라미터로 전달하였다.

int main(void)
{
    ...

    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_CAN2_Init();
    MX_UART5_Init();
    MX_I2C3_Init();
    MX_SPI5_Init();
    MX_LTDC_Init();
    MX_DMA2D_Init();
    
    /* USER CODE BEGIN 2 */
    BSP_LCD_Init(hltdc, hdma2d);
    BSP_LCD_LayerDefaultInit(LCD_BACKGROUND_LAYER, (uint32_t)frame_buffer);
    BSP_LCD_SelectLayer(LCD_BACKGROUND_LAYER);
    BSP_LCD_DisplayOn();
    BSP_LCD_Clear(LCD_COLOR_WHITE);

    BSP_LCD_SetBackColor(RGB_LCD_COLOR_WHITE);
    BSP_LCD_SetTextColor(RGB_LCD_COLOR_BLACK);
    BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
    BSP_LCD_DisplayStringAt(0, 150, (uint8_t *)"LCD Test1", CENTER_MODE);
    BSP_LCD_DisplayStringAt(0, 180, (uint8_t *)"LCD Test2", CENTER_MODE);

    BSP_TS_Init(240, 320);
    BSP_TS_ITConfig();
    /* USER CODE END 2 */
    
    ...
}

터치패드에서 인터럽트로 받은 X, Y값을 화면에 출력하기 위해 기존 인터럽트 코드를 아래와 같이 변경하였다.

static uint16_t x, y;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if(GPIO_Pin  == LCD_TS_INT1_Pin)
    {
        TS_StateTypeDef tp_state;
        BSP_TS_GetState(&tp_state);
        if(x != tp_state.X || y != tp_state.Y)
        {
            char buf[32] = {0, };

            if(tp_state.X > 240) tp_state.X = 240;
            if(tp_state.Y > 320) tp_state.Y = 320;

            sprintf(buf, "x = %d, y = %d", tp_state.X, tp_state.Y);
            BSP_LCD_Clear(LCD_COLOR_WHITE);

            BSP_LCD_SetFont(&Font20);
            BSP_LCD_DisplayStringAt(0, 120, (uint8_t *)buf, CENTER_MODE);
            x = tp_state.X;
            y = tp_state.Y;
        }
        BSP_TS_ITClear();
    }
}

위 코드처럼 인터럽트에서 그래픽 처리하는 것은 지양해야 하며, 위 코드는 단순히 테스트를 위해 작성한 코드이며, 터치패드 움직임에 따라 LCD에 출력 값이 변하지 못하지만, 그래픽이 업데이트 되는 것은 확인할 수 있다.

이 포스트에서 사용한 예제는 아래 GitHub에서 전체 코드를 받을 수 있다. STM32F429 데모보드는 내장 SDRAM 크기가 256Kbyte이기 때문에 외부 SDRAM을 사용하면 보다 좋은 그래픽 라이브러리를 사용할 수 있다.

 

highgon2/STM32

STM32 TestCode. Contribute to highgon2/STM32 development by creating an account on GitHub.

github.com