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-2020 Fabrizio Di Vittorio.
4  All rights reserved.
5 
6  This file is part of FabGL Library.
7 
8  FabGL is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  FabGL is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with FabGL. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 
23 #pragma once
24 
25 
26 
34 #include <stdint.h>
35 #include <stddef.h>
36 #include <atomic>
37 
38 #include "rom/lldesc.h"
39 #include "driver/gpio.h"
40 
41 #include "freertos/FreeRTOS.h"
42 #include "freertos/queue.h"
43 
44 #include "fabglconf.h"
45 #include "fabutils.h"
46 #include "devdrivers/swgenerator.h"
47 #include "displaycontroller.h"
48 
49 
50 
51 
52 #define VGA_RED_BIT 0
53 #define VGA_GREEN_BIT 2
54 #define VGA_BLUE_BIT 4
55 #define VGA_HSYNC_BIT 6
56 #define VGA_VSYNC_BIT 7
57 
58 #define VGA_SYNC_MASK ((1 << VGA_HSYNC_BIT) | (1 << VGA_VSYNC_BIT))
59 
60 
61 // pixel 0 = byte 2, pixel 1 = byte 3, pixel 2 = byte 0, pixel 3 = byte 1 :
62 // pixel : 0 1 2 3 4 5 6 7 8 9 10 11 ...etc...
63 // byte : 2 3 0 1 6 7 4 5 10 11 8 9 ...etc...
64 // dword : 0 1 2 ...etc...
65 // Thanks to https://github.com/paulscottrobson for the new macro. Before was: (row[((X) & 0xFFFC) + ((2 + (X)) & 3)])
66 #define VGA_PIXELINROW(row, X) (row[(X) ^ 2])
67 
68 // requires variables: m_viewPort
69 #define VGA_PIXEL(X, Y) VGA_PIXELINROW(m_viewPort[(Y)], X)
70 #define VGA_INVERT_PIXEL(X, Y) { auto px = &VGA_PIXEL((X), (Y)); *px = ~(*px ^ VGA_SYNC_MASK); }
71 
72 
73 
74 namespace fabgl {
75 
76 
77 
83  Sync,
86 };
87 
88 
90 struct VGATimings {
91  char label[22];
92  int frequency;
93  int16_t HVisibleArea;
94  int16_t HFrontPorch;
95  int16_t HSyncPulse;
96  int16_t HBackPorch;
97  int16_t VVisibleArea;
98  int16_t VFrontPorch;
99  int16_t VSyncPulse;
100  int16_t VBackPorch;
101  char HSyncLogic;
102  char VSyncLogic;
103  uint8_t scanCount;
104  uint8_t multiScanBlack;
106 };
107 
108 
109 
110 class VGABaseController : public GenericBitmappedDisplayController {
111 
112 public:
113 
114  VGABaseController();
115 
116  // unwanted methods
117  VGABaseController(VGABaseController const&) = delete;
118  void operator=(VGABaseController const&) = delete;
119 
136  void begin(gpio_num_t redGPIO, gpio_num_t greenGPIO, gpio_num_t blueGPIO, gpio_num_t HSyncGPIO, gpio_num_t VSyncGPIO);
137 
157  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);
158 
169  void begin();
170 
171  virtual void end();
172 
173  static bool convertModelineToTimings(char const * modeline, VGATimings * timings);
174 
175  // abstract method of BitmappedDisplayController
176  virtual void suspendBackgroundPrimitiveExecution();
177 
178  // abstract method of BitmappedDisplayController
179  virtual void resumeBackgroundPrimitiveExecution();
180 
208  void setResolution(char const * modeline, int viewPortWidth = -1, int viewPortHeight = -1, bool doubleBuffered = false);
209 
210  virtual void setResolution(VGATimings const& timings, int viewPortWidth = -1, int viewPortHeight = -1, bool doubleBuffered = false);
211 
217  int getViewPortCol() { return m_viewPortCol; }
218 
224  int getViewPortRow() { return m_viewPortRow; }
225 
226  // abstract method of BitmappedDisplayController
227  int getViewPortWidth() { return m_viewPortWidth; }
228 
229  // abstract method of BitmappedDisplayController
230  int getViewPortHeight() { return m_viewPortHeight; }
231 
245  void moveScreen(int offsetX, int offsetY);
246 
261  void shrinkScreen(int shrinkX, int shrinkY);
262 
263  VGATimings * getResolutionTimings() { return &m_timings; }
264 
272  uint8_t getBitsPerChannel() { return m_bitsPerChannel; }
273 
287  uint8_t * getScanline(int y) { return (uint8_t*) m_viewPort[y]; }
288 
301  uint8_t createRawPixel(RGB222 rgb) { return preparePixel(rgb); }
302 
317  void setRawPixel(int x, int y, uint8_t rgb) { VGA_PIXEL(x, y) = rgb; }
318 
319 
320 protected:
321 
322  static void setupGPIO(gpio_num_t gpio, int bit, gpio_mode_t mode);
323 
324  void startGPIOStream();
325 
326  void freeBuffers();
327 
328  virtual void freeViewPort();
329 
330  virtual void init();
331 
332  bool setDMABuffersCount(int buffersCount);
333 
334  uint8_t packHVSync(bool HSync, bool VSync);
335 
336  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); }
337 
338  uint8_t preparePixelWithSync(RGB222 rgb, bool HSync, bool VSync);
339 
340  void fillVertBuffers(int offsetY);
341 
342  void fillHorizBuffers(int offsetX);
343 
344  int fill(uint8_t volatile * buffer, int startPos, int length, uint8_t red, uint8_t green, uint8_t blue, bool hsync, bool vsync);
345 
346  int calcRequiredDMABuffersCount(int viewPortHeight);
347 
348  bool isMultiScanBlackLine(int scan);
349 
350  void setDMABufferBlank(int index, void volatile * address, int length, int scan, bool isStartOfVertFrontPorch);
351  void setDMABufferView(int index, int row, int scan, volatile uint8_t * * viewPort, bool onVisibleDMA);
352  void setDMABufferView(int index, int row, int scan, bool isStartOfVertFrontPorch);
353 
354  virtual void onSetupDMABuffer(lldesc_t volatile * buffer, bool isStartOfVertFrontPorch, int scan, bool isVisible, int visibleRow) = 0;
355 
356  void volatile * getDMABuffer(int index, int * length);
357 
358  void allocateViewPort(uint32_t allocCaps, int rowlen);
359  virtual void allocateViewPort() = 0;
360  virtual void checkViewPortSize() { };
361 
362  // abstract method of BitmappedDisplayController
363  virtual void swapBuffers();
364 
365 
366  // when double buffer is enabled the "drawing" view port is always m_viewPort, while the "visible" view port is always m_viewPortVisible
367  // when double buffer is not enabled then m_viewPort = m_viewPortVisible
368  volatile uint8_t * * m_viewPort;
369  volatile uint8_t * * m_viewPortVisible;
370 
371  // true: double buffering is implemented in DMA
372  bool m_doubleBufferOverDMA;
373 
374  volatile int m_primitiveProcessingSuspended; // 0 = enabled, >0 suspended
375 
376  volatile int16_t m_viewPortWidth;
377  volatile int16_t m_viewPortHeight;
378 
379  intr_handle_t m_isr_handle;
380 
381  VGATimings m_timings;
382  int16_t m_HLineSize;
383 
384  volatile int16_t m_viewPortCol;
385  volatile int16_t m_viewPortRow;
386 
387  // contains H and V signals for visible line
388  volatile uint8_t m_HVSync;
389 
390 
391 private:
392 
393 
394  // bits per channel on VGA output
395  // 1 = 8 colors, 2 = 64 colors, set by begin()
396  int m_bitsPerChannel;
397 
398  GPIOStream m_GPIOStream;
399 
400  lldesc_t volatile * m_DMABuffers;
401  int m_DMABuffersCount;
402 
403  // when double buffer is enabled at DMA level the running DMA buffer is always m_DMABuffersVisible
404  // when double buffer is not enabled then m_DMABuffers = m_DMABuffersVisible
405  lldesc_t volatile * m_DMABuffersHead;
406  lldesc_t volatile * m_DMABuffersVisible;
407 
408  // These buffers contains a full line, with FrontPorch, Sync, BackPorch and blank visible area, in the
409  // order specified by timings.HStartingBlock
410  volatile uint8_t * m_HBlankLine_withVSync;
411  volatile uint8_t * m_HBlankLine;
412 
413  uint8_t * m_viewPortMemoryPool[FABGLIB_VIEWPORT_MEMORY_POOL_COUNT + 1]; // last allocated pool is nullptr
414 
415  int16_t m_rawFrameHeight;
416 
417 };
418 
419 
420 
421 
422 
423 
424 
425 
426 } // 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.
Definition: canvas.cpp:31
This file contains FabGL library configuration settings, like number of supported colors...
VGAScanStart HStartingBlock