FabGL
ESP32 Display Controller and Graphics Library
vgabasecontroller.h
Go to the documentation of this file.
1 /*
2  Created by Fabrizio Di Vittorio (fdivitto2013@gmail.com) - <http://www.fabgl.com>
3  Copyright (c) 2019-2021 Fabrizio Di Vittorio.
4  All rights reserved.
5 
6 
7 * Please contact fdivitto2013@gmail.com if you need a commercial license.
8 
9 
10 * This library and related software is available under GPL v3. Feel free to use FabGL in free software and hardware:
11 
12  FabGL is free software: you can redistribute it and/or modify
13  it under the terms of the GNU General Public License as published by
14  the Free Software Foundation, either version 3 of the License, or
15  (at your option) any later version.
16 
17  FabGL is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  GNU General Public License for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with FabGL. If not, see <http://www.gnu.org/licenses/>.
24  */
25 
26 
27 #pragma once
28 
29 
30 
38 #include <stdint.h>
39 #include <stddef.h>
40 #include <atomic>
41 
42 #include "driver/gpio.h"
43 
44 #include "freertos/FreeRTOS.h"
45 #include "freertos/queue.h"
46 
47 #include "fabglconf.h"
48 #include "fabutils.h"
49 #include "devdrivers/swgenerator.h"
50 #include "displaycontroller.h"
51 
52 
53 
54 
55 #define VGA_RED_BIT 0
56 #define VGA_GREEN_BIT 2
57 #define VGA_BLUE_BIT 4
58 #define VGA_HSYNC_BIT 6
59 #define VGA_VSYNC_BIT 7
60 
61 #define VGA_SYNC_MASK ((1 << VGA_HSYNC_BIT) | (1 << VGA_VSYNC_BIT))
62 
63 
64 // pixel 0 = byte 2, pixel 1 = byte 3, pixel 2 = byte 0, pixel 3 = byte 1 :
65 // pixel : 0 1 2 3 4 5 6 7 8 9 10 11 ...etc...
66 // byte : 2 3 0 1 6 7 4 5 10 11 8 9 ...etc...
67 // dword : 0 1 2 ...etc...
68 // Thanks to https://github.com/paulscottrobson for the new macro. Before was: (row[((X) & 0xFFFC) + ((2 + (X)) & 3)])
69 #define VGA_PIXELINROW(row, X) (row[(X) ^ 2])
70 
71 // requires variables: m_viewPort
72 #define VGA_PIXEL(X, Y) VGA_PIXELINROW(m_viewPort[(Y)], X)
73 #define VGA_INVERT_PIXEL(X, Y) { auto px = &VGA_PIXEL((X), (Y)); *px = ~(*px ^ VGA_SYNC_MASK); }
74 
75 
76 
77 namespace fabgl {
78 
79 
80 
81 #if FABGLIB_VGAXCONTROLLER_PERFORMANCE_CHECK
82  extern volatile uint64_t s_vgapalctrlcycles;
83 #endif
84 
85 
86 
92  Sync,
95 };
96 
97 
99 struct VGATimings {
100  char label[22];
101  int frequency;
102  int16_t HVisibleArea;
103  int16_t HFrontPorch;
104  int16_t HSyncPulse;
105  int16_t HBackPorch;
106  int16_t VVisibleArea;
107  int16_t VFrontPorch;
108  int16_t VSyncPulse;
109  int16_t VBackPorch;
110  char HSyncLogic;
111  char VSyncLogic;
112  uint8_t scanCount;
113  uint8_t multiScanBlack;
115 };
116 
117 
118 
119 class VGABaseController : public GenericBitmappedDisplayController {
120 
121 public:
122 
123  VGABaseController();
124 
125  // unwanted methods
126  VGABaseController(VGABaseController const&) = delete;
127  void operator=(VGABaseController const&) = delete;
128 
145  void begin(gpio_num_t redGPIO, gpio_num_t greenGPIO, gpio_num_t blueGPIO, gpio_num_t HSyncGPIO, gpio_num_t VSyncGPIO);
146 
166  void begin(gpio_num_t red1GPIO, gpio_num_t red0GPIO, gpio_num_t green1GPIO, gpio_num_t green0GPIO, gpio_num_t blue1GPIO, gpio_num_t blue0GPIO, gpio_num_t HSyncGPIO, gpio_num_t VSyncGPIO);
167 
178  void begin();
179 
180  virtual void end();
181 
182  static bool convertModelineToTimings(char const * modeline, VGATimings * timings);
183 
184  // abstract method of BitmappedDisplayController
185  virtual void suspendBackgroundPrimitiveExecution();
186 
187  // abstract method of BitmappedDisplayController
188  virtual void resumeBackgroundPrimitiveExecution();
189 
217  void setResolution(char const * modeline, int viewPortWidth = -1, int viewPortHeight = -1, bool doubleBuffered = false);
218 
219  virtual void setResolution(VGATimings const& timings, int viewPortWidth = -1, int viewPortHeight = -1, bool doubleBuffered = false);
220 
226  int getViewPortCol() { return m_viewPortCol; }
227 
233  int getViewPortRow() { return m_viewPortRow; }
234 
235  // abstract method of BitmappedDisplayController
236  int getViewPortWidth() { return m_viewPortWidth; }
237 
238  // abstract method of BitmappedDisplayController
239  int getViewPortHeight() { return m_viewPortHeight; }
240 
254  void moveScreen(int offsetX, int offsetY);
255 
270  void shrinkScreen(int shrinkX, int shrinkY);
271 
272  VGATimings * getResolutionTimings() { return &m_timings; }
273 
281  uint8_t getBitsPerChannel() { return m_bitsPerChannel; }
282 
296  uint8_t * getScanline(int y) { return (uint8_t*) m_viewPort[y]; }
297 
310  uint8_t createRawPixel(RGB222 rgb) { return preparePixel(rgb); }
311 
312  uint8_t createBlankRawPixel() { return m_HVSync; }
313 
314 
315 
316 protected:
317 
318  static void setupGPIO(gpio_num_t gpio, int bit, gpio_mode_t mode);
319 
320  void startGPIOStream();
321 
322  void freeBuffers();
323 
324  virtual void freeViewPort();
325 
326  virtual void init();
327 
328  bool setDMABuffersCount(int buffersCount);
329 
330  uint8_t packHVSync(bool HSync, bool VSync);
331 
332  uint8_t inline __attribute__((always_inline)) preparePixel(RGB222 rgb) { return m_HVSync | (rgb.B << VGA_BLUE_BIT) | (rgb.G << VGA_GREEN_BIT) | (rgb.R << VGA_RED_BIT); }
333 
334  uint8_t preparePixelWithSync(RGB222 rgb, bool HSync, bool VSync);
335 
336  void fillVertBuffers(int offsetY);
337 
338  void fillHorizBuffers(int offsetX);
339 
340  int fill(uint8_t volatile * buffer, int startPos, int length, uint8_t red, uint8_t green, uint8_t blue, bool hsync, bool vsync);
341 
342  int calcRequiredDMABuffersCount(int viewPortHeight);
343 
344  bool isMultiScanBlackLine(int scan);
345 
346  void setDMABufferBlank(int index, void volatile * address, int length, int scan, bool isStartOfVertFrontPorch);
347  void setDMABufferView(int index, int row, int scan, volatile uint8_t * * viewPort, bool onVisibleDMA);
348  void setDMABufferView(int index, int row, int scan, bool isStartOfVertFrontPorch);
349 
350  virtual void onSetupDMABuffer(lldesc_t volatile * buffer, bool isStartOfVertFrontPorch, int scan, bool isVisible, int visibleRow) = 0;
351 
352  void volatile * getDMABuffer(int index, int * length);
353 
354  void allocateViewPort(uint32_t allocCaps, int rowlen);
355  virtual void allocateViewPort() = 0;
356  virtual void checkViewPortSize() { };
357 
358  // abstract method of BitmappedDisplayController
359  virtual void swapBuffers();
360 
361 
362  // when double buffer is enabled the "drawing" view port is always m_viewPort, while the "visible" view port is always m_viewPortVisible
363  // when double buffer is not enabled then m_viewPort = m_viewPortVisible
364  volatile uint8_t * * m_viewPort;
365  volatile uint8_t * * m_viewPortVisible;
366 
367  // true: double buffering is implemented in DMA
368  bool m_doubleBufferOverDMA;
369 
370  volatile int m_primitiveProcessingSuspended; // 0 = enabled, >0 suspended
371 
372  volatile int16_t m_viewPortWidth;
373  volatile int16_t m_viewPortHeight;
374 
375  intr_handle_t m_isr_handle;
376 
377  VGATimings m_timings;
378  int16_t m_HLineSize;
379 
380  volatile int16_t m_viewPortCol;
381  volatile int16_t m_viewPortRow;
382 
383  // contains H and V signals for visible line
384  volatile uint8_t m_HVSync;
385 
386 
387 private:
388 
389 
390  // bits per channel on VGA output
391  // 1 = 8 colors, 2 = 64 colors, set by begin()
392  int m_bitsPerChannel;
393 
394  GPIOStream m_GPIOStream;
395 
396  lldesc_t volatile * m_DMABuffers;
397  int m_DMABuffersCount;
398 
399  // when double buffer is enabled at DMA level the running DMA buffer is always m_DMABuffersVisible
400  // when double buffer is not enabled then m_DMABuffers = m_DMABuffersVisible
401  lldesc_t volatile * m_DMABuffersHead;
402  lldesc_t volatile * m_DMABuffersVisible;
403 
404  // These buffers contains a full line, with FrontPorch, Sync, BackPorch and blank visible area, in the
405  // order specified by timings.HStartingBlock
406  volatile uint8_t * m_HBlankLine_withVSync;
407  volatile uint8_t * m_HBlankLine;
408 
409  uint8_t * m_viewPortMemoryPool[FABGLIB_VIEWPORT_MEMORY_POOL_COUNT + 1]; // last allocated pool is nullptr
410 
411  int16_t m_rawFrameHeight;
412 
413 };
414 
415 
416 
417 
418 
419 
420 
421 
422 } // end of namespace
This file contains fabgl::GPIOStream definition.
This file contains fabgl::BitmappedDisplayController definition.
VGAScanStart
Represents one of the four blocks of horizontal or vertical line.
Specifies the VGA timings. This is a modeline decoded.
This file contains some utility classes and functions.
#define FABGLIB_VIEWPORT_MEMORY_POOL_COUNT
Definition: fabglconf.h:126
Definition: canvas.cpp:36
This file contains FabGL library configuration settings, like number of supported colors...
VGAScanStart HStartingBlock