Nathan Leprevier / Mbed OS Grecordeur

Dependencies:   LCD_DISCO_F746NG GRecorder BSP_DISCO_F746NG

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tft.c Source File

tft.c

Go to the documentation of this file.
00001 /**
00002  * @file tft.c
00003  *
00004  */
00005  
00006 /*********************
00007  *      INCLUDES
00008  *********************/
00009 #include "lv_conf.h"
00010 #include "lvgl/lvgl.h"
00011 #include <string.h>
00012 #include <stdlib.h>
00013  
00014 #include "tft.h "
00015 #include "stm32f7xx.h"
00016 #include "stm32746g_discovery.h"
00017 #include "stm32746g_discovery_sdram.h"
00018 #include "stm32746g_discovery_ts.h"
00019 #include "../Components/rk043fn48h/rk043fn48h.h"
00020  
00021 /*********************
00022  *      DEFINES
00023  *********************/
00024  
00025 #if LV_COLOR_DEPTH != 16 && LV_COLOR_DEPTH != 24 && LV_COLOR_DEPTH != 32
00026 #error LV_COLOR_DEPTH must be 16, 24, or 32
00027 #endif
00028 
00029 #define LV_USE_GPU 0
00030  
00031 /**
00032   * @brief  LCD status structure definition
00033   */
00034 #define LCD_OK                          ((uint8_t)0x00)
00035 #define LCD_ERROR                       ((uint8_t)0x01)
00036 #define LCD_TIMEOUT                     ((uint8_t)0x02)
00037  
00038 /**
00039   * @brief LCD special pins
00040   */
00041 /* Display enable pin */
00042 #define LCD_DISP_PIN                    GPIO_PIN_12
00043 #define LCD_DISP_GPIO_PORT              GPIOI
00044 #define LCD_DISP_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOI_CLK_ENABLE()
00045 #define LCD_DISP_GPIO_CLK_DISABLE()     __HAL_RCC_GPIOI_CLK_DISABLE()
00046  
00047 /* Backlight control pin */
00048 #define LCD_BL_CTRL_PIN                  GPIO_PIN_3
00049 #define LCD_BL_CTRL_GPIO_PORT            GPIOK
00050 #define LCD_BL_CTRL_GPIO_CLK_ENABLE()    __HAL_RCC_GPIOK_CLK_ENABLE()
00051 #define LCD_BL_CTRL_GPIO_CLK_DISABLE()   __HAL_RCC_GPIOK_CLK_DISABLE()
00052  
00053 #define CPY_BUF_DMA_STREAM               DMA2_Stream0
00054 #define CPY_BUF_DMA_CHANNEL              DMA_CHANNEL_0
00055 #define CPY_BUF_DMA_STREAM_IRQ           DMA2_Stream0_IRQn
00056 #define CPY_BUF_DMA_STREAM_IRQHANDLER    DMA2_Stream0_IRQHandler
00057  
00058 /**********************
00059  *      TYPEDEFS
00060  **********************/
00061  
00062 /**********************
00063  *  STATIC PROTOTYPES
00064  **********************/
00065  
00066 /*These 3 functions are needed by LittlevGL*/
00067 static void ex_disp_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t * color_p);
00068 #if LV_USE_GPU
00069 static void gpu_mem_blend(lv_disp_drv_t *disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa);
00070 static void gpu_mem_fill(lv_disp_drv_t *disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width, const lv_area_t * fill_area, lv_color_t color);
00071 #endif
00072  
00073 static uint8_t LCD_Init(void);
00074 static void LCD_LayerRgb565Init(uint32_t FB_Address);
00075 static void LCD_DisplayOn(void);
00076  
00077 static void DMA_Config(void);
00078 static void DMA_TransferComplete(DMA_HandleTypeDef *han);
00079 static void DMA_TransferError(DMA_HandleTypeDef *han);
00080  
00081 #if LV_USE_GPU
00082 static void DMA2D_Config(void);
00083 #endif
00084  
00085 /**********************
00086  *  STATIC VARIABLES
00087  **********************/
00088 #if LV_USE_GPU
00089 static DMA2D_HandleTypeDef Dma2dHandle;
00090 #endif
00091 static LTDC_HandleTypeDef  hLtdcHandler;
00092  
00093 #if LV_COLOR_DEPTH == 16
00094 typedef uint16_t uintpixel_t;
00095 #elif LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32
00096 typedef uint32_t uintpixel_t;
00097 #endif
00098  
00099 /* You can try to change buffer to internal ram by uncommenting line below and commenting
00100  * SDRAM one. */
00101 //static uintpixel_t my_fb[TFT_HOR_RES * TFT_VER_RES];
00102  
00103 static __IO uintpixel_t * my_fb = (__IO uintpixel_t*) (SDRAM_DEVICE_ADDR);
00104  
00105 static DMA_HandleTypeDef  DmaHandle;
00106 static int32_t            x1_flush;
00107 static int32_t            y1_flush;
00108 static int32_t            x2_flush;
00109 static int32_t            y2_fill;
00110 static int32_t            y_fill_act;
00111 static const lv_color_t * buf_to_flush;
00112 static lv_disp_drv_t disp_drv;   
00113  
00114 static lv_disp_t *our_disp = NULL;
00115 /**********************
00116  *      MACROS
00117  **********************/
00118  
00119 /**
00120  * Initialize your display here
00121  */
00122  
00123 void tft_init(void)
00124 {
00125     /* There is only one display on STM32 */
00126     if(our_disp != NULL)
00127         abort();
00128     /* LCD Initialization */
00129     LCD_Init();
00130  
00131     /* LCD Initialization */
00132     LCD_LayerRgb565Init((uint32_t)my_fb);
00133  
00134     /* Enable the LCD */
00135     LCD_DisplayOn();
00136  
00137     DMA_Config();
00138  
00139 #if LV_USE_GPU != 0
00140     DMA2D_Config();
00141 #endif
00142    /*-----------------------------
00143     * Create a buffer for drawing
00144     *----------------------------*/
00145  
00146    /* LittlevGL requires a buffer where it draws the objects. The buffer's has to be greater than 1 display row*/
00147  
00148     static lv_disp_draw_buf_t buf;
00149     static lv_color_t buf1_1[TFT_HOR_RES * 68];
00150     static lv_color_t buf1_2[TFT_HOR_RES * 68];
00151     lv_disp_draw_buf_init(&buf, buf1_1, buf1_2, TFT_HOR_RES * 68);   /*Initialize the display buffer*/
00152  
00153  
00154     /*-----------------------------------
00155     * Register the display in LittlevGL
00156     *----------------------------------*/
00157  
00158                           /*Descriptor of a display driver*/
00159     lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/
00160  
00161     /*Set up the functions to access to your display*/
00162  
00163     /*Set the resolution of the display*/
00164     disp_drv.hor_res = TFT_HOR_RES;
00165     disp_drv.ver_res = TFT_VER_RES;
00166  
00167     /*Used to copy the buffer's content to the display*/
00168     disp_drv.flush_cb = ex_disp_flush;
00169  
00170     /*Set a display buffer*/
00171     disp_drv.draw_buf = &buf;
00172  
00173  
00174     /*Finally register the driver*/
00175     our_disp = lv_disp_drv_register(&disp_drv);
00176 }
00177  
00178 /**********************
00179  *   STATIC FUNCTIONS
00180  **********************/
00181  
00182 /* Flush the content of the internal buffer the specific area on the display
00183  * You can use DMA or any hardware acceleration to do this operation in the background but
00184  * 'lv_flush_ready()' has to be called when finished
00185  * This function is required only when LV_VDB_SIZE != 0 in lv_conf.h*/
00186 static void ex_disp_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t * color_p)
00187 {
00188     int32_t x1 = area->x1;
00189     int32_t x2 = area->x2;
00190     int32_t y1 = area->y1;
00191     int32_t y2 = area->y2;
00192     /*Return if the area is out the screen*/
00193  
00194     if(x2 < 0) return;
00195     if(y2 < 0) return;
00196     if(x1 > TFT_HOR_RES - 1) return;
00197     if(y1 > TFT_VER_RES - 1) return;
00198  
00199     /*Truncate the area to the screen*/
00200     int32_t act_x1 = x1 < 0 ? 0 : x1;
00201     int32_t act_y1 = y1 < 0 ? 0 : y1;
00202     int32_t act_x2 = x2 > TFT_HOR_RES - 1 ? TFT_HOR_RES - 1 : x2;
00203     int32_t act_y2 = y2 > TFT_VER_RES - 1 ? TFT_VER_RES - 1 : y2;
00204  
00205     x1_flush = act_x1;
00206     y1_flush = act_y1;
00207     x2_flush = act_x2;
00208     y2_fill = act_y2;
00209     y_fill_act = act_y1;
00210     buf_to_flush = color_p;
00211  
00212     SCB_CleanInvalidateDCache();
00213     SCB_InvalidateICache();
00214     /*##-7- Start the DMA transfer using the interrupt mode #*/
00215     /* Configure the source, destination and buffer size DMA fields and Start DMA Stream transfer */
00216     /* Enable All the DMA interrupts */
00217     HAL_StatusTypeDef err;
00218     uint32_t length = (x2_flush - x1_flush + 1);
00219 #if LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32
00220     length *= 2; /* STM32 DMA uses 16-bit chunks so multiply by 2 for 32-bit color */
00221 #endif
00222     err = HAL_DMA_Start_IT(&DmaHandle,(uint32_t)buf_to_flush, (uint32_t)&my_fb[y_fill_act * TFT_HOR_RES + x1_flush],
00223              length);
00224     if(err != HAL_OK)
00225     {
00226         while(1);   /*Halt on error*/
00227     }
00228 }
00229  
00230  
00231 /**
00232  * @brief Configure LCD pins, and peripheral clocks.
00233  */
00234 static void LCD_MspInit(void)
00235 {
00236     GPIO_InitTypeDef gpio_init_structure;
00237  
00238     /* Enable the LTDC and DMA2D clocks */
00239     __HAL_RCC_LTDC_CLK_ENABLE();
00240 #if LV_USE_GPU != 0
00241     __HAL_RCC_DMA2D_CLK_ENABLE();
00242 #endif
00243     /* Enable GPIOs clock */
00244     __HAL_RCC_GPIOE_CLK_ENABLE();
00245     __HAL_RCC_GPIOG_CLK_ENABLE();
00246     __HAL_RCC_GPIOI_CLK_ENABLE();
00247     __HAL_RCC_GPIOJ_CLK_ENABLE();
00248     __HAL_RCC_GPIOK_CLK_ENABLE();
00249     LCD_DISP_GPIO_CLK_ENABLE();
00250     LCD_BL_CTRL_GPIO_CLK_ENABLE();
00251  
00252     /*** LTDC Pins configuration ***/
00253     /* GPIOE configuration */
00254     gpio_init_structure.Pin       = GPIO_PIN_4;
00255     gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00256     gpio_init_structure.Pull      = GPIO_NOPULL;
00257     gpio_init_structure.Speed     = GPIO_SPEED_FAST;
00258     gpio_init_structure.Alternate = GPIO_AF14_LTDC;
00259     HAL_GPIO_Init(GPIOE, &gpio_init_structure);
00260  
00261     /* GPIOG configuration */
00262     gpio_init_structure.Pin       = GPIO_PIN_12;
00263     gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00264     gpio_init_structure.Alternate = GPIO_AF9_LTDC;
00265     HAL_GPIO_Init(GPIOG, &gpio_init_structure);
00266  
00267     /* GPIOI LTDC alternate configuration */
00268     gpio_init_structure.Pin       = GPIO_PIN_9 | GPIO_PIN_10 | \
00269             GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
00270     gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00271     gpio_init_structure.Alternate = GPIO_AF14_LTDC;
00272     HAL_GPIO_Init(GPIOI, &gpio_init_structure);
00273  
00274     /* GPIOJ configuration */
00275     gpio_init_structure.Pin       = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | \
00276             GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | \
00277             GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | \
00278             GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
00279     gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00280     gpio_init_structure.Alternate = GPIO_AF14_LTDC;
00281     HAL_GPIO_Init(GPIOJ, &gpio_init_structure);
00282  
00283     /* GPIOK configuration */
00284     gpio_init_structure.Pin       = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 | \
00285             GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
00286     gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00287     gpio_init_structure.Alternate = GPIO_AF14_LTDC;
00288     HAL_GPIO_Init(GPIOK, &gpio_init_structure);
00289  
00290     /* LCD_DISP GPIO configuration */
00291     gpio_init_structure.Pin       = LCD_DISP_PIN;     /* LCD_DISP pin has to be manually controlled */
00292     gpio_init_structure.Mode      = GPIO_MODE_OUTPUT_PP;
00293     HAL_GPIO_Init(LCD_DISP_GPIO_PORT, &gpio_init_structure);
00294  
00295     /* LCD_BL_CTRL GPIO configuration */
00296     gpio_init_structure.Pin       = LCD_BL_CTRL_PIN;  /* LCD_BL_CTRL pin has to be manually controlled */
00297     gpio_init_structure.Mode      = GPIO_MODE_OUTPUT_PP;
00298     HAL_GPIO_Init(LCD_BL_CTRL_GPIO_PORT, &gpio_init_structure);
00299 }
00300  
00301 /**
00302  * @brief Configure LTDC PLL.
00303  */
00304 static void LCD_ClockConfig(void)
00305 {
00306     static RCC_PeriphCLKInitTypeDef  periph_clk_init_struct;
00307  
00308     /* RK043FN48H LCD clock configuration */
00309     /* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */
00310     /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 192 Mhz */
00311     /* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 192/5 = 38.4 Mhz */
00312     /* LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_4 = 38.4/4 = 9.6Mhz */
00313     periph_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
00314     periph_clk_init_struct.PLLSAI.PLLSAIN = 192;
00315     periph_clk_init_struct.PLLSAI.PLLSAIR = RK043FN48H_FREQUENCY_DIVIDER;
00316     periph_clk_init_struct.PLLSAIDivR = RCC_PLLSAIDIVR_4;
00317     HAL_RCCEx_PeriphCLKConfig(&periph_clk_init_struct);
00318 }
00319  
00320 /**
00321   * @brief  Initializes the LCD.
00322   * @retval LCD state
00323   */
00324 static uint8_t LCD_Init(void)
00325 {
00326     /* Select the used LCD */
00327  
00328     /* The RK043FN48H LCD 480x272 is selected */
00329     /* Timing Configuration */
00330     hLtdcHandler.Init.HorizontalSync = (RK043FN48H_HSYNC - 1);
00331     hLtdcHandler.Init.VerticalSync = (RK043FN48H_VSYNC - 1);
00332     hLtdcHandler.Init.AccumulatedHBP = (RK043FN48H_HSYNC + RK043FN48H_HBP - 1);
00333     hLtdcHandler.Init.AccumulatedVBP = (RK043FN48H_VSYNC + RK043FN48H_VBP - 1);
00334     hLtdcHandler.Init.AccumulatedActiveH = (RK043FN48H_HEIGHT + RK043FN48H_VSYNC + RK043FN48H_VBP - 1);
00335     hLtdcHandler.Init.AccumulatedActiveW = (RK043FN48H_WIDTH + RK043FN48H_HSYNC + RK043FN48H_HBP - 1);
00336     hLtdcHandler.Init.TotalHeigh = (RK043FN48H_HEIGHT + RK043FN48H_VSYNC + RK043FN48H_VBP + RK043FN48H_VFP - 1);
00337     hLtdcHandler.Init.TotalWidth = (RK043FN48H_WIDTH + RK043FN48H_HSYNC + RK043FN48H_HBP + RK043FN48H_HFP - 1);
00338  
00339     /* LCD clock configuration */
00340     LCD_ClockConfig();
00341  
00342     /* Initialize the LCD pixel width and pixel height */
00343     hLtdcHandler.LayerCfg->ImageWidth  = RK043FN48H_WIDTH;
00344     hLtdcHandler.LayerCfg->ImageHeight = RK043FN48H_HEIGHT;
00345  
00346     /* Background value */
00347     hLtdcHandler.Init.Backcolor.Blue = 0;
00348     hLtdcHandler.Init.Backcolor.Green = 0;
00349     hLtdcHandler.Init.Backcolor.Red = 0;
00350  
00351     /* Polarity */
00352     hLtdcHandler.Init.HSPolarity = LTDC_HSPOLARITY_AL;
00353     hLtdcHandler.Init.VSPolarity = LTDC_VSPOLARITY_AL;
00354     hLtdcHandler.Init.DEPolarity = LTDC_DEPOLARITY_AL;
00355     hLtdcHandler.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
00356     hLtdcHandler.Instance = LTDC;
00357  
00358     if(HAL_LTDC_GetState(&hLtdcHandler) == HAL_LTDC_STATE_RESET)
00359     {
00360         /* Initialize the LCD Msp: this __weak function can be rewritten by the application */
00361         LCD_MspInit();
00362     }
00363     HAL_LTDC_Init(&hLtdcHandler);
00364  
00365     /* Assert display enable LCD_DISP pin */
00366     HAL_GPIO_WritePin(LCD_DISP_GPIO_PORT, LCD_DISP_PIN, GPIO_PIN_SET);
00367  
00368     /* Assert backlight LCD_BL_CTRL pin */
00369     HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_PORT, LCD_BL_CTRL_PIN, GPIO_PIN_SET);
00370  
00371     BSP_SDRAM_Init();
00372  
00373     uint32_t i;
00374     for(i = 0; i < (TFT_HOR_RES * TFT_VER_RES) ; i++)
00375     {
00376         my_fb[i] = 0;
00377     }
00378  
00379     return LCD_OK;
00380 }
00381  
00382 static void LCD_LayerRgb565Init(uint32_t FB_Address)
00383 {
00384     LTDC_LayerCfgTypeDef  layer_cfg;
00385  
00386     /* Layer Init */
00387     layer_cfg.WindowX0 = 0;
00388     layer_cfg.WindowX1 = TFT_HOR_RES;
00389     layer_cfg.WindowY0 = 0;
00390     layer_cfg.WindowY1 = TFT_VER_RES;
00391  
00392 #if LV_COLOR_DEPTH == 16
00393     layer_cfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
00394 #elif LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32
00395     layer_cfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB8888;
00396 #else
00397 #error Unsupported color depth (see tft.c)
00398 #endif
00399     layer_cfg.FBStartAdress = FB_Address;
00400     layer_cfg.Alpha = 255;
00401     layer_cfg.Alpha0 = 0;
00402     layer_cfg.Backcolor.Blue = 0;
00403     layer_cfg.Backcolor.Green = 0;
00404     layer_cfg.Backcolor.Red = 0;
00405     layer_cfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
00406     layer_cfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
00407     layer_cfg.ImageWidth = TFT_HOR_RES;
00408     layer_cfg.ImageHeight = TFT_VER_RES;
00409  
00410     HAL_LTDC_ConfigLayer(&hLtdcHandler, &layer_cfg, 0);
00411 }
00412  
00413 static void LCD_DisplayOn(void)
00414 {
00415     /* Display On */
00416     __HAL_LTDC_ENABLE(&hLtdcHandler);
00417     HAL_GPIO_WritePin(LCD_DISP_GPIO_PORT, LCD_DISP_PIN, GPIO_PIN_SET);        /* Assert LCD_DISP pin */
00418     HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_PORT, LCD_BL_CTRL_PIN, GPIO_PIN_SET);  /* Assert LCD_BL_CTRL pin */
00419 }
00420  
00421 static void DMA_Config(void)
00422 {
00423     /*## -1- Enable DMA2 clock #################################################*/
00424     __HAL_RCC_DMA2_CLK_ENABLE();
00425  
00426     /*##-2- Select the DMA functional Parameters ###############################*/
00427     DmaHandle.Init.Channel = CPY_BUF_DMA_CHANNEL;                   /* DMA_CHANNEL_0                    */
00428     DmaHandle.Init.Direction = DMA_MEMORY_TO_MEMORY;                /* M2M transfer mode                */
00429     DmaHandle.Init.PeriphInc = DMA_PINC_ENABLE;                     /* Peripheral increment mode Enable */
00430     DmaHandle.Init.MemInc = DMA_MINC_ENABLE;                        /* Memory increment mode Enable     */
00431     DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;   /* Peripheral data alignment : 16bit */
00432     DmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;      /* memory data alignment : 16bit     */
00433     DmaHandle.Init.Mode = DMA_NORMAL;                               /* Normal DMA mode                  */
00434     DmaHandle.Init.Priority = DMA_PRIORITY_HIGH;                    /* priority level : high            */
00435     DmaHandle.Init.FIFOMode = DMA_FIFOMODE_ENABLE;                  /* FIFO mode enabled                */
00436     DmaHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL; /* FIFO threshold: 1/4 full   */
00437     DmaHandle.Init.MemBurst = DMA_MBURST_SINGLE;                    /* Memory burst                     */
00438     DmaHandle.Init.PeriphBurst = DMA_PBURST_SINGLE;                 /* Peripheral burst                 */
00439  
00440     /*##-3- Select the DMA instance to be used for the transfer : DMA2_Stream0 #*/
00441     DmaHandle.Instance = CPY_BUF_DMA_STREAM;
00442  
00443     /*##-4- Initialize the DMA stream ##########################################*/
00444     if(HAL_DMA_Init(&DmaHandle) != HAL_OK)
00445     {
00446         while(1)
00447         {
00448         }
00449     }
00450  
00451     /*##-5- Select Callbacks functions called after Transfer complete and Transfer error */
00452     HAL_DMA_RegisterCallback(&DmaHandle, HAL_DMA_XFER_CPLT_CB_ID, DMA_TransferComplete);
00453     HAL_DMA_RegisterCallback(&DmaHandle, HAL_DMA_XFER_ERROR_CB_ID, DMA_TransferError);
00454  
00455     /*##-6- Configure NVIC for DMA transfer complete/error interrupts ##########*/
00456     HAL_NVIC_SetPriority(CPY_BUF_DMA_STREAM_IRQ, 0, 0);
00457     HAL_NVIC_EnableIRQ(CPY_BUF_DMA_STREAM_IRQ);
00458 }
00459  
00460 /**
00461   * @brief  DMA conversion complete callback
00462   * @note   This function is executed when the transfer complete interrupt
00463   *         is generated
00464   * @retval None
00465   */
00466 static void DMA_TransferComplete(DMA_HandleTypeDef *han)
00467 {
00468     y_fill_act ++;
00469  
00470     if(y_fill_act > y2_fill) {
00471         SCB_CleanInvalidateDCache();
00472         SCB_InvalidateICache();
00473         lv_disp_flush_ready(&disp_drv);
00474     } else {
00475         uint32_t length = (x2_flush - x1_flush + 1);
00476         buf_to_flush += x2_flush - x1_flush + 1;
00477         /*##-7- Start the DMA transfer using the interrupt mode ####################*/
00478         /* Configure the source, destination and buffer size DMA fields and Start DMA Stream transfer */
00479         /* Enable All the DMA interrupts */
00480 #if LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32
00481         length *= 2; /* STM32 DMA uses 16-bit chunks so multiply by 2 for 32-bit color */
00482 #endif
00483         if(HAL_DMA_Start_IT(han,(uint32_t)buf_to_flush, (uint32_t)&my_fb[y_fill_act * TFT_HOR_RES + x1_flush],
00484                             length) != HAL_OK)
00485         {
00486             while(1);   /*Halt on error*/
00487         }
00488     }
00489 }
00490  
00491 /**
00492   * @brief  DMA conversion error callback
00493   * @note   This function is executed when the transfer error interrupt
00494   *         is generated during DMA transfer
00495   * @retval None
00496   */
00497 static void DMA_TransferError(DMA_HandleTypeDef *han)
00498 {
00499  
00500 }
00501  
00502 /**
00503   * @brief  This function handles DMA Stream interrupt request.
00504   * @param  None
00505   * @retval None
00506   */
00507 void CPY_BUF_DMA_STREAM_IRQHANDLER(void)
00508 {
00509     /* Check the interrupt and clear flag */
00510     HAL_DMA_IRQHandler(&DmaHandle);
00511 }
00512  
00513  
00514 #if LV_USE_GPU != 0
00515  
00516 static void Error_Handler(void)
00517 {
00518     while(1)
00519     {
00520     }
00521 }
00522 /**
00523   * @brief  DMA2D Transfer completed callback
00524   * @param  hdma2d: DMA2D handle.
00525   * @note   This example shows a simple way to report end of DMA2D transfer, and
00526   *         you can add your own implementation.
00527   * @retval None
00528   */
00529 static void DMA2D_TransferComplete(DMA2D_HandleTypeDef *hdma2d)
00530 {
00531  
00532 }
00533  
00534 /**
00535   * @brief  DMA2D error callbacks
00536   * @param  hdma2d: DMA2D handle
00537   * @note   This example shows a simple way to report DMA2D transfer error, and you can
00538   *         add your own implementation.
00539   * @retval None
00540   */
00541 static void DMA2D_TransferError(DMA2D_HandleTypeDef *hdma2d)
00542 {
00543  
00544 }
00545  
00546 /**
00547   * @brief DMA2D configuration.
00548   * @note  This function Configure the DMA2D peripheral :
00549   *        1) Configure the Transfer mode as memory to memory with blending.
00550   *        2) Configure the output color mode as RGB565 pixel format.
00551   *        3) Configure the foreground
00552   *          - first image loaded from FLASH memory
00553   *          - constant alpha value (decreased to see the background)
00554   *          - color mode as RGB565 pixel format
00555   *        4) Configure the background
00556   *          - second image loaded from FLASH memory
00557   *          - color mode as RGB565 pixel format
00558   * @retval None
00559   */
00560 static void DMA2D_Config(void)
00561 {
00562     /* Configure the DMA2D Mode, Color Mode and output offset */
00563     Dma2dHandle.Init.Mode         = DMA2D_M2M_BLEND;
00564 #if LV_COLOR_DEPTH == 16
00565     Dma2dHandle.Init.ColorMode    = DMA2D_RGB565;
00566 #elif LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32
00567     Dma2dHandle.Init.ColorMode    = DMA2D_ARGB8888;
00568 #endif
00569     Dma2dHandle.Init.OutputOffset = 0x0;
00570  
00571     /* DMA2D Callbacks Configuration */
00572     Dma2dHandle.XferCpltCallback  = DMA2D_TransferComplete;
00573     Dma2dHandle.XferErrorCallback = DMA2D_TransferError;
00574  
00575     /* Foreground Configuration */
00576     Dma2dHandle.LayerCfg[1].AlphaMode = DMA2D_REPLACE_ALPHA;
00577     Dma2dHandle.LayerCfg[1].InputAlpha = 0xFF;
00578 #if LV_COLOR_DEPTH == 16
00579     Dma2dHandle.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
00580 #elif LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32
00581     Dma2dHandle.LayerCfg[1].InputColorMode = DMA2D_INPUT_ARGB8888;
00582 #endif
00583  
00584     Dma2dHandle.LayerCfg[1].InputOffset = 0x0;
00585  
00586     /* Background Configuration */
00587     Dma2dHandle.LayerCfg[0].AlphaMode = DMA2D_REPLACE_ALPHA;
00588     Dma2dHandle.LayerCfg[0].InputAlpha = 0xFF;
00589 #if LV_COLOR_DEPTH == 16
00590     Dma2dHandle.LayerCfg[0].InputColorMode = DMA2D_INPUT_RGB565;
00591 #elif LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32
00592     Dma2dHandle.LayerCfg[0].InputColorMode = DMA2D_INPUT_ARGB8888;
00593 #endif
00594     Dma2dHandle.LayerCfg[0].InputOffset = 0x0;
00595  
00596     Dma2dHandle.Instance   = DMA2D;
00597  
00598     /* DMA2D Initialization */
00599     if(HAL_DMA2D_Init(&Dma2dHandle) != HAL_OK)
00600     {
00601         /* Initialization Error */
00602         Error_Handler();
00603     }
00604  
00605     HAL_DMA2D_ConfigLayer(&Dma2dHandle, 0);
00606     HAL_DMA2D_ConfigLayer(&Dma2dHandle, 1);
00607 }
00608 #endif