Select one of the symbols to view example projects that use it.
 
Outline
#include <touchgfx/hal/OSWrappers.hpp>
#include <touchgfx/lcd/LCD.hpp>
#include <touchgfx/hal/GPIO.hpp>
#include <STM32F4HAL_DSI.hpp>
#include <STM32F4DMA.hpp>
#include <FreeRTOS.h>
#include <task.h>
#include "stm32f4xx.h"
#include "stm32f4xx_hal_dsi.h"
#include "stm32f4xx_hal_ltdc.h"
#include "stm32f4xx_hal_gpio.h"
displayRefreshing
refreshRequested
updateRegion
doubleBufferingEnabled
currFbBase
bitDepth
STM32F4HAL_DSI::getTFTFrameBuffer() const
STM32F4HAL_DSI::setFrameBufferStartAddress(void *, uint16_t, bool, bool)
STM32F4HAL_DSI::setTFTFrameBuffer(uint16_t *)
STM32F4HAL_DSI::configureInterrupts()
STM32F4HAL_DSI::enableLCDControllerInterrupt()
STM32F4HAL_DSI::disableInterrupts()
STM32F4HAL_DSI::enableInterrupts()
STM32F4HAL_DSI::beginFrame()
STM32F4HAL_DSI::endFrame()
HAL_DSI_TearingEffectCallback(DSI_HandleTypeDef *)
HAL_DSI_EndOfRefreshCallback(DSI_HandleTypeDef *)
Files
loading...
CodeScopeSTM32 Libraries and SamplesTouchGFXGui/target/STM32F4HAL_DSI.cpp
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/** ****************************************************************************** * This file is part of the TouchGFX 4.10.0 distribution. * * @attention * * Copyright (c) 2018 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** *//* ... */ #include <touchgfx/hal/OSWrappers.hpp> #include <touchgfx/lcd/LCD.hpp> #include <touchgfx/hal/GPIO.hpp> #include <STM32F4HAL_DSI.hpp> #include <STM32F4DMA.hpp> #include <FreeRTOS.h> #include <task.h> 7 includes /** * About this implementation: * This class is for use ONLY with the DSI peripheral. If you have a regular RGB interface display, use the STM32F4HAL.cpp class instead. * * This implementation assumes that the DSI is configured to be in adapted command mode, with tearing effect set to external pin. * Display will only be updated when there has actually been changes to the frame buffer. *//* ... */ extern "C" { #include "stm32f4xx.h" #include "stm32f4xx_hal_dsi.h" #include "stm32f4xx_hal_ltdc.h" #include "stm32f4xx_hal_gpio.h" extern LTDC_HandleTypeDef hltdc; extern DSI_HandleTypeDef hdsi; /* Request tear interrupt at specific scanline. Implemented in BoardConfiguration.cpp */ void LCD_ReqTear(); /* Configures display to update indicated region of the screen (200pixel wide chunks) - 16bpp mode */ void LCD_SetUpdateRegion(int idx); /* Configures display to update left half of the screen. Implemented in BoardConfiguration.cpp - 24bpp mode*/ void LCD_SetUpdateRegionLeft(); /* Configures display to update right half of the screen. Implemented in BoardConfiguration.cpp - 24bpp mode*/ void LCD_SetUpdateRegionRight(); }extern "C" { ... } static volatile bool displayRefreshing = false; static volatile bool refreshRequested = false; static volatile int updateRegion = 0; static bool doubleBufferingEnabled = false; static uint16_t* currFbBase = 0; static uint16_t bitDepth = 0; uint16_t* STM32F4HAL_DSI::getTFTFrameBuffer() const { return currFbBase; ...} void STM32F4HAL_DSI::setFrameBufferStartAddress(void* adr, uint16_t depth, bool useDoubleBuffering, bool useAnimationStorage) { // Make note of whether we are using double buffering. doubleBufferingEnabled = useDoubleBuffering; currFbBase = (uint16_t*)adr; bitDepth = depth; HAL::setFrameBufferStartAddress(adr, depth, useDoubleBuffering, useAnimationStorage); }{ ... } void STM32F4HAL_DSI::setTFTFrameBuffer(uint16_t* adr) { if (doubleBufferingEnabled) { __HAL_DSI_WRAPPER_DISABLE(&hdsi); LTDC_LAYER(&hltdc, 0)->CFBAR = (uint32_t)adr; __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(&hltdc); currFbBase = adr; __HAL_DSI_WRAPPER_ENABLE(&hdsi); }if (doubleBufferingEnabled) { ... } }{ ... } void STM32F4HAL_DSI::configureInterrupts() { // These two priorities MUST be EQUAL, and MUST be functionally lower than RTOS scheduler interrupts. NVIC_SetPriority(DMA2D_IRQn, 7); NVIC_SetPriority(DSI_IRQn, 7); }{ ... } /* Enable LCD line interrupt, when entering video (active) area */ void STM32F4HAL_DSI::enableLCDControllerInterrupt() { LCD_ReqTear(); __HAL_DSI_CLEAR_FLAG(&hdsi, DSI_IT_ER); __HAL_DSI_CLEAR_FLAG(&hdsi, DSI_IT_TE); __HAL_DSI_ENABLE_IT(&hdsi, DSI_IT_TE); __HAL_DSI_ENABLE_IT(&hdsi, DSI_IT_ER); LTDC->IER = 3; /* Enable line and FIFO underrun interrupts */ }{ ... } void STM32F4HAL_DSI::disableInterrupts() { NVIC_DisableIRQ(DMA2D_IRQn); NVIC_DisableIRQ(DSI_IRQn); NVIC_DisableIRQ(LTDC_ER_IRQn); }{ ... } void STM32F4HAL_DSI::enableInterrupts() { NVIC_EnableIRQ(DMA2D_IRQn); NVIC_EnableIRQ(DSI_IRQn); NVIC_EnableIRQ(LTDC_ER_IRQn); }{ ... } bool STM32F4HAL_DSI::beginFrame() { refreshRequested = false; return HAL::beginFrame(); }{ ... } void STM32F4HAL_DSI::endFrame() { HAL::endFrame(); if (frameBufferUpdatedThisFrame) { refreshRequested = true; }if (frameBufferUpdatedThisFrame) { ... } }{ ... } extern "C" void HAL_DSI_TearingEffectCallback(DSI_HandleTypeDef *hdsi) { GPIO::set(GPIO::VSYNC_FREQ); if (HAL::getInstance()) { HAL::getInstance()->vSync(); if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { OSWrappers::signalVSync(); }if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { ... } }if (HAL::getInstance()) { ... } if (!doubleBufferingEnabled && HAL::getInstance()) { // In single buffering, only require that the system waits for display update to be finished if we // actually intend to update the display in this frame. HAL::getInstance()->lockDMAToFrontPorch(refreshRequested); }if (!doubleBufferingEnabled && HAL::getInstance()) { ... } if (refreshRequested && !displayRefreshing) { // We have an update pending. if (doubleBufferingEnabled && HAL::getInstance()) { // Swap frame buffers immediately instead of waiting for the task to be scheduled in. // Note: task will also swap when it wakes up, but that operation is guarded and will not have // any effect if already swapped. HAL::getInstance()->swapFrameBuffers(); }if (doubleBufferingEnabled && HAL::getInstance()) { ... } // Update region 0 = first area of display (First quarter for 16bpp, first half for 24bpp) updateRegion = 0; //Set update region based on bit depth of framebuffer. 16pp or 24bpp. if (bitDepth == 24) { LCD_SetUpdateRegionLeft(); }if (bitDepth == 24) { ... } //Default to 16 bpp else { LCD_SetUpdateRegion(updateRegion); }else { ... } // Transfer a quarter screen of pixel data. HAL_DSI_Refresh(hdsi); displayRefreshing = true; }if (refreshRequested && !displayRefreshing) { ... } else { GPIO::clear(GPIO::VSYNC_FREQ); }else { ... } }{ ... } extern "C" void HAL_DSI_EndOfRefreshCallback(DSI_HandleTypeDef *hdsi) { if (displayRefreshing) { if (bitDepth == 24) { if (updateRegion == 0) { // If we transferred the left half, also transfer right half. __HAL_DSI_WRAPPER_DISABLE(hdsi); LTDC_LAYER(&hltdc, 0)->CFBAR = ((uint32_t)currFbBase) + (HAL::FRAME_BUFFER_WIDTH / 2) * 3; __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(&hltdc); LCD_SetUpdateRegionRight(); //Set display column to 400-799 __HAL_DSI_WRAPPER_ENABLE(hdsi); updateRegion = 1; HAL_DSI_Refresh(hdsi); }if (updateRegion == 0) { ... } else { // Otherwise we are done refreshing. __HAL_DSI_WRAPPER_DISABLE(hdsi); LTDC_LAYER(&hltdc, 0)->CFBAR = (uint32_t)currFbBase; __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(&hltdc); LCD_SetUpdateRegionLeft(); //Set display column to 0-399 __HAL_DSI_WRAPPER_ENABLE(hdsi); GPIO::clear(GPIO::VSYNC_FREQ); displayRefreshing = false; if (HAL::getInstance()) { // Signal to the framework that display update has finished. HAL::getInstance()->frontPorchEntered(); }if (HAL::getInstance()) { ... } }else { ... } }if (bitDepth == 24) { ... } else //Default to 16bpp { updateRegion++; if (updateRegion < 4) { __HAL_DSI_WRAPPER_DISABLE(hdsi); LTDC_LAYER(&hltdc, 0)->CFBAR = (uint32_t)currFbBase + (updateRegion * HAL::FRAME_BUFFER_WIDTH) / 2; __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(&hltdc); LCD_SetUpdateRegion(updateRegion); __HAL_DSI_WRAPPER_ENABLE(hdsi); HAL_DSI_Refresh(hdsi); }if (updateRegion < 4) { ... } else { __HAL_DSI_WRAPPER_DISABLE(hdsi); LTDC_LAYER(&hltdc, 0)->CFBAR = (uint32_t)currFbBase; __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(&hltdc); LCD_SetUpdateRegion(0); __HAL_DSI_WRAPPER_ENABLE(hdsi); GPIO::clear(GPIO::VSYNC_FREQ); displayRefreshing = false; if (HAL::getInstance()) { // Signal to the framework that display update has finished. HAL::getInstance()->frontPorchEntered(); }if (HAL::getInstance()) { ... } }else { ... } }else { ... } }if (displayRefreshing) { ... } }{ ... }