Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Video Library for STM32H7 boards #663

Merged
merged 78 commits into from
May 26, 2023
Merged
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
eef4750
cosmetics anx7625 library
leonardocavagnis Mar 13, 2023
0a9ef8b
cosmetics dsi library
leonardocavagnis Mar 13, 2023
95949dd
cosmetics porting module in portenta_lvgl lib
leonardocavagnis Mar 13, 2023
94e3c56
Create Portenta_Video class
leonardocavagnis Mar 14, 2023
621a649
function to get current frame buffer addr in dsi
leonardocavagnis Mar 14, 2023
78b1e05
add functions to draw elements in portenta_video lib
leonardocavagnis Mar 14, 2023
b5b3752
refactoring arduinoLogo with new portenta_video apis
leonardocavagnis Mar 14, 2023
7c7af47
remove useless include
leonardocavagnis Mar 14, 2023
4f16d11
add define for colors
leonardocavagnis Mar 14, 2023
66ea3db
add function to draw pixel, line, rect, circle and fill circle
leonardocavagnis Mar 14, 2023
6750260
add function to draw not filled rectangle
leonardocavagnis Mar 14, 2023
e5de3b2
refactoring args and fun name in portenta_video
leonardocavagnis Mar 15, 2023
40b2950
add drawChar function
leonardocavagnis Mar 15, 2023
59bd8ae
add function to draw a text
leonardocavagnis Mar 15, 2023
9347c24
refactor arduinologo example with new apis
leonardocavagnis Mar 15, 2023
0215a00
add support for giga r1 and giga display shield
leonardocavagnis Mar 17, 2023
b6a2274
add video_driver lib and remove dependence to portenta_lvgl lib
leonardocavagnis Mar 17, 2023
47413d4
remove lvgl init procedure in video_driver lib
leonardocavagnis Mar 17, 2023
6c2b8c8
add LVGLDemo example project
leonardocavagnis Mar 17, 2023
b3fb0db
create a label with lvgl library in LVGLDemo.ino
leonardocavagnis Mar 17, 2023
91ebb03
add lvgl hello world example in LVGLDemo
leonardocavagnis Mar 20, 2023
df40a17
fix display init (ST7701)
leonardocavagnis Mar 21, 2023
4c37cfd
embed LVGL engine inside Portenta_Video library for LVGLDemo example
leonardocavagnis Mar 21, 2023
29cfef6
add support for LVGL lib v7.x
leonardocavagnis Mar 21, 2023
598f2a4
fix orientation in LVGL lib
leonardocavagnis Mar 21, 2023
d9a533f
remove compatibility with LVGL v7.x
leonardocavagnis Mar 21, 2023
928addb
manage landscape and portrait mode
leonardocavagnis Mar 22, 2023
57a39bb
Add H7_Video class as a child of ArduinoGraphics lib (first attempt)
leonardocavagnis Mar 23, 2023
a7051ec
add support for LVGL and portenta in H7_Video lib (arduinographics)
leonardocavagnis Mar 23, 2023
774f0a3
add landscape management for H7_Video + LVGL
leonardocavagnis Mar 23, 2023
96f3215
fix landscape mode in H7_Video lib
leonardocavagnis Mar 24, 2023
d1dce41
Add ArduinoLogo example (draw image with H7_Video lib)
leonardocavagnis Mar 24, 2023
8811e44
Add arduinologo_old example with Portenta_Video lib (to be removed)
leonardocavagnis Mar 24, 2023
cd9ff80
add ArduinoLogoDrawing empty example
leonardocavagnis Mar 24, 2023
d9867e4
modify LVGL demo with H7_Video library
leonardocavagnis Mar 24, 2023
929d833
add ArduinoLogoDrawing example
leonardocavagnis Mar 24, 2023
575ea51
use circle function to draw arduino logo in ArduinoLogoDrawing example
leonardocavagnis Mar 27, 2023
d2b75c0
remove Portenta_Video Library
leonardocavagnis Mar 27, 2023
37a2885
rename Portenta_Video library in H7_Video library
leonardocavagnis Mar 27, 2023
9e87a04
add touch management in LVGLDemo example
leonardocavagnis Mar 28, 2023
a8ad320
add touch management to LVGL Demo
leonardocavagnis Mar 28, 2023
f24f6f4
add support for PortentaH7+GIGA Display in H7_Video library
leonardocavagnis Mar 29, 2023
3601b83
embed LVGL touch management inside H7_Video library
leonardocavagnis Mar 30, 2023
a7926cf
remove not used include from H7_Video lib
leonardocavagnis Mar 31, 2023
f259cd6
fix problem of include lvgl when using primitive function in H7_Video…
leonardocavagnis Mar 31, 2023
18fe009
remove video_driver module
leonardocavagnis Apr 3, 2023
9ad94f3
refactor display module (rename in st7701 module)
leonardocavagnis Apr 3, 2023
ff0bd6f
cosmetics
leonardocavagnis Apr 3, 2023
8566076
refactoring dsi module
leonardocavagnis Apr 3, 2023
c38444b
remove mutual dependency between anx7625 module and dsi module
leonardocavagnis Apr 4, 2023
b6b5994
add DSI initialization inside ST7701 lib
leonardocavagnis Apr 4, 2023
e910ea9
cosmetics anx7625 module
leonardocavagnis Apr 4, 2023
1e44e29
cosmetics of all modules (add file header and sections)
leonardocavagnis Apr 5, 2023
454c852
rename H7_Video lib in Arduino_H7_Video library
leonardocavagnis Apr 6, 2023
9cf2cb5
auto manage of landscape and portrait mode in Arduino_H7_Video library
leonardocavagnis Apr 6, 2023
66e3ce2
add auto-detect of EDID mode for portenta H7+USB
leonardocavagnis Apr 11, 2023
12a7c6a
fix max display resolution supported for H7 microcontroller
leonardocavagnis Apr 11, 2023
837a82f
add LOG enable define for EDID and ANX7625 module
leonardocavagnis Apr 12, 2023
887288e
check malloc return in Arduino_H7_Video Lib
leonardocavagnis Apr 12, 2023
58cac74
Move image declaration to global scope
leonardocavagnis Apr 17, 2023
f64f392
Adding singleton classes to manage anx and st7701 controller
leonardocavagnis Apr 18, 2023
c325482
fix screen tearing issue when switch between frames
leonardocavagnis Apr 26, 2023
bdb2f2d
Use Arduino_GigaDisplayTouch library in LVGLDemo example
leonardocavagnis May 8, 2023
bd97eb5
dsi: add reload callback check for LTDC layer drawing
leonardocavagnis May 10, 2023
9a66a72
update LVGL_Demo example
leonardocavagnis May 17, 2023
4b25a81
remove LVGL touch handler (moved in touch library)
leonardocavagnis May 18, 2023
4f804e4
Remove hard dependency on ArduinoGraphics
leonardocavagnis May 19, 2023
358ca41
port doom to new video library
leonardocavagnis May 19, 2023
5422ed2
LVGL Demo example update
leonardocavagnis May 23, 2023
49d32b1
doc: add readme, library.properties, keywords
leonardocavagnis May 23, 2023
94e71fb
docs: add docs/README.md
leonardocavagnis May 24, 2023
ce239d2
doc: add api
leonardocavagnis May 24, 2023
0872171
doc: add doxygen comment
leonardocavagnis May 24, 2023
94316b2
video: allow other thread to execute while waiting for screen refresh
leonardocavagnis May 24, 2023
08ce02d
video: add isRotated() API
leonardocavagnis May 24, 2023
5cccd4b
Remove Portenta_LVGL library (examples moved in Arduino_H7_Video lib)
leonardocavagnis May 26, 2023
98465eb
ci: update compile-examples according to new video lib
leonardocavagnis May 26, 2023
880f9bb
Merge branch 'main' into stm32h7_video_lib
facchinm May 26, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .github/workflows/compile-examples.yml
Original file line number Diff line number Diff line change
@@ -57,20 +57,23 @@ jobs:
fqbn: arduino:mbed:envie_m7:target_core=cm4
additional-libraries: |
- name: lvgl
version: 8.3.5
- name: ArduinoGraphics
additional-sketch-paths: |
- libraries/doom
- libraries/KernelDebug
- libraries/Portenta_SDCARD
- libraries/Portenta_SDRAM
- libraries/Portenta_Video
- libraries/Arduino_H7_Video
- libraries/RPC
- board:
fqbn: arduino:mbed:envie_m7
additional-libraries: |
- name: lvgl
version: 7.11.0
version: 8.3.5
- name: MicroNMEA
- name: ArduinoBLE
- name: ArduinoGraphics
additional-sketch-paths: |
- libraries/PDM
- libraries/doom
@@ -82,7 +85,7 @@ jobs:
- libraries/Portenta_SDCARD
- libraries/Portenta_SDRAM
- libraries/STM32H747_System
- libraries/Portenta_Video
- libraries/Arduino_H7_Video
- libraries/RPC
- libraries/ThreadDebug
- libraries/USBHID
5 changes: 5 additions & 0 deletions libraries/Arduino_H7_Video/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# 📺 Arduino H7 Video Library

The Arduino H7 Video Library manages the video output on Arduino boards based on the STM32H7 microcontroller (Portenta H7, GIGA R1 WiFi), providing functions to draw on the screen and integrate third-party video libraries such as [LVGL](https://lvgl.io/) and [emWin](https://www.segger.com/products/user-interface/emwin/).

📖 For more information about this library, please refer to the documentation [here](./docs/).
56 changes: 56 additions & 0 deletions libraries/Arduino_H7_Video/docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Arduino H7 Video Library

[![License](https://img.shields.io/badge/License-LGPLv3-blue.svg)]()

The Arduino H7 Video library is a C++ library designed to handle the video output of Arduino boards based on the STM32H7 microcontroller with DSI video interface. DSI stands for Display Serial Interface, which is a serial interface used to connect a display to the microcontroller.

This library is based on the graphics primitives of the [ArduinoGraphics](https://github.com/arduino-libraries/ArduinoGraphics) library and currently supports the Arduino Portenta H7 and Arduino Giga R1 WiFi boards. The library offers two modes of operation for the Portenta H7 board: you can connect the display to the video output via a USB Type-C connection or use the Giga Display Shield. For the Giga R1 board, only the Giga Display Shield is supported.

The library allows you to draw graphics elements on the screen using simple graphics primitives such as lines, circles, images, etc. Additionally, you can integrate third-party graphic libraries like [LVGL](https://lvgl.io/) and [emWin](https://www.segger.com/products/user-interface/emwin/) to achieve more complex GUI.

The library provides methods for initializing the video controller, clearing the screen, and drawing basic graphics elements.

## Features

- Handles video output of Arduino boards based on the STM32H7 microcontroller with DSI video interface
- Allows drawing graphics elements using simple primitives like lines, circles, images, etc.
- Integration of third-party graphic libraries like LVGL and emWin for more complex GUI

## Usage

To use this library, you must have a supported Arduino board and a display. Once you have connected the display to the board, you can include the display library in your Arduino sketch and use its functions to draw graphic elements on the screen.
Here is a minimal example for the Arduino GIGA R1 WiFi with Giga Display Shield:

```cpp
#include "Arduino_H7_Video.h"
#include "ArduinoGraphics.h"

Arduino_H7_Video Display(800, 480, GigaDisplayShield);

void setup() {
Display.begin();

// Draw a green rectangle that covers the entire display
Display.beginDraw();
Display.clear();
Display.noStroke();
Display.fill(0, 255, 0);
Display.rect(0, 0, Display.width(), Display.height());
Display.endDraw();
}

void loop() { }
```
## Examples
- **[ArduinoLogo](../examples/ArduinoLogo):** This example demonstrates how to display an Arduino logo image on the screen.
- **[ArduinoLogoDrawing](../examples/ArduinoLogoDrawing):** This example demonstrates how to draw an Arduino logo image using graphics primitives (line, circle, rect, etc.).
- **[LVGLDemo](../examples/LVGLDemo):** This example demonstrates how to create a graphical user interface (GUI) using the LVGL library. It includes the [Arduino_GigaDisplayTouch](https://github.com/arduino-libraries/Arduino_GigaDisplayTouch/) library to handle touch events.
## API
The API documentation can be found [here](./api.md).
## License
This library is released under the [LGPLv3 license]().
117 changes: 117 additions & 0 deletions libraries/Arduino_H7_Video/docs/api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Summary

Members | Descriptions
--------------------------------|---------------------------------------------
`class` [`Arduino_H7_Video`](#class-arduino_h7_video) | The main class for managing the video controller and the display.

# class [`Arduino_H7_Video`](#class-arduino_h7_video)
The main class for managing the video controller and the display.

## Summary

| Members | Descriptions |
|-------------------------------------------------------------|---------------------------------------------|
| `public ` [`Arduino_H7_Video`](#public-arduino_h7_videoint-width-int-height-h7displayshield-shield) | Construct a new Arduino_H7_Video object with the specified width, height, and display shield. |
| `public int` [`begin`](#public-int-begin) | Initialize the video controller and display. |
| `public void` [`end`](#public-void-end) | De-initialize the video controller and display. |
| `public int` [`width`](#public-int-width) | Get the width of the display. |
| `public int` [`height`](#public-int-height) | Get the height of the display. |
| `public bool` [`isRotated`](#public-bool-isrotated) | Check if the display is rotated. |
| `public void` [`clear`](#public-void-clear) | Clear the display. |
| `public void` [`beginDraw`](#public-void-begindraw) | Begin drawing operations on the display. |
| `public void` [`endDraw`](#public-void-enddraw) | End drawing operations on the display. |
| `public void` [`set`](#public-void-setint-x-int-y-uint8_t-r-uint8_t-g-uint8_t-b) | Set the color of the pixel at the specified coordinates. |

> *Note: For all drawing functions, refer to the documentation of the [`ArduinoGraphics`](https://reference.arduino.cc/reference/en/libraries/arduinographics/) library.*
## Members

### `public ` [`Arduino_H7_Video`](#)`(int width, int height, H7DisplayShield &shield)`

Construct a new Arduino_H7_Video object with the specified width, height, and display shield.

#### Parameters
- `width`: The width of the display.
- `height`: The height of the display.
- `shield`: The display shield used.
- *GigaDisplayShield*: Giga Display Shield
- *USBCVideo*: Display attach to the USB-C port

---

### `public int` [`begin`](#)`()`

Initialize the video controller and display.

#### Returns
`int`: 0 if initialization is successful, otherwise an error code.

---

### `public void` [`end`](#)`()`

De-initialize the video controller and display.

---

### `public int` [`width`](#)`()`

Get the width of the display.

#### Returns
`int`: The width of the display.

---

### `public int` [`height`](#)`()`

Get the height of the display.

#### Returns
`int`: The height of the display.

---

### `public bool` [`isRotated`](#)`()`

Check if the display is rotated.

#### Returns
`bool`: True if the display is rotated, false otherwise.

---

### `public void` [`clear`](#)`()`

Clear the display.

---

### `public void` [`beginDraw`](#)`()`

Begin drawing operations on the display.

---

### `public void` [`endDraw`](#)`()`

End drawing operations on the display.

---

### `public void` [`set`](#)`(int x, int y, uint8_t r, uint8_t g, uint8_t b)`

Set the color of the pixel at the specified coordinates.

#### Parameters
- `x`: The x-coordinate of the pixel.
- `y`: The y-coordinate of the pixel.
- `r`: The red component of the color.
- `g`: The green component of the color.
- `b`: The blue component of the color.

---

> *Note: For detailed information on drawing functions, please refer to the documentation of the [`ArduinoGraphics`](https://reference.arduino.cc/reference/en/libraries/arduinographics/) library.*

33 changes: 33 additions & 0 deletions libraries/Arduino_H7_Video/examples/ArduinoLogo/ArduinoLogo.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
ArduinoLogo
created 17 Apr 2023
by Leonardo Cavagnis
*/

#include "Arduino_H7_Video.h"
#include "ArduinoGraphics.h"

#include "img_arduinologo.h"
// Alternatively, any raw RGB565 image can be included on demand using this macro
// Online image converter: https://lvgl.io/tools/imageconverter (Output format: Binary RGB565)
/*
#define INCBIN_PREFIX
#include "incbin.h"
INCBIN(test, "/home/user/Downloads/test.bin");
*/

Arduino_H7_Video Display(800, 480, GigaDisplayShield);
//Arduino_H7_Video Display(1024, 768, USBCVideo);

Image img_arduinologo(ENCODING_RGB16, (uint8_t *) texture_raw, 300, 300);

void setup() {
Display.begin();

Display.beginDraw();
Display.image(img_arduinologo, (Display.width() - img_arduinologo.width())/2, (Display.height() - img_arduinologo.height())/2);
Display.endDraw();
}

void loop() { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
ArduinoLogoDrawing
created 17 Apr 2023
by Leonardo Cavagnis
*/

#include "Arduino_H7_Video.h"
#include "ArduinoGraphics.h"

Arduino_H7_Video Display(800, 480, GigaDisplayShield);
//Arduino_H7_Video Display(1024, 768, USBCVideo);

void setup() {
Display.begin();

Display.beginDraw();
Display.background(255, 255, 255);
Display.clear();
Display.fill(0x008184);
Display.circle(Display.width()/2, Display.height()/2, 300);
Display.stroke(255, 255, 255);
Display.noFill();
for (int i=0; i<30; i++) {
Display.circle((Display.width()/2)-55+5, Display.height()/2, 110-i);
Display.circle((Display.width()/2)+55-5, Display.height()/2, 110-i);
}
Display.fill(255, 255, 255);
Display.rect((Display.width()/2)-55-16+5, (Display.height()/2)-5, 32, 10);
Display.fill(255, 255, 255);
Display.rect((Display.width()/2)+55-16-5, (Display.height()/2)-5, 32, 10);
Display.fill(255, 255, 255);
Display.rect((Display.width()/2)+55-5-5, (Display.height()/2)-16, 10, 32);
Display.endDraw();
}

void loop() { }
139 changes: 139 additions & 0 deletions libraries/Arduino_H7_Video/examples/LVGLDemo/LVGLDemo.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@

/*
LVGLDemo
created 17 Apr 2023
by Leonardo Cavagnis
*/

#include "Arduino_H7_Video.h"
#include "Arduino_GigaDisplayTouch.h"

#include "lvgl.h"

Arduino_H7_Video Display(800, 480, GigaDisplayShield); /* Arduino_H7_Video Display(1024, 768, USBCVideo); */
Arduino_GigaDisplayTouch TouchDetector;

/* Button click event callback */
static void btn_event_cb(lv_event_t * e) {
static uint32_t cnt = 1;
lv_obj_t * btn = lv_event_get_target(e);
lv_obj_t * label = lv_obj_get_child(btn, 0);
lv_label_set_text_fmt(label, "%"LV_PRIu32, cnt);
cnt++;
}

/* Slider update value handler */
static void set_slider_val(void * bar, int32_t val) {
lv_bar_set_value((lv_obj_t *)bar, val, LV_ANIM_ON);
}

void setup() {
Serial.begin(115200);

Display.begin();
TouchDetector.begin();

/* Create a container with grid 2x2 */
static lv_coord_t col_dsc[] = {370, 370, LV_GRID_TEMPLATE_LAST};
static lv_coord_t row_dsc[] = {215, 215, LV_GRID_TEMPLATE_LAST};
lv_obj_t * cont = lv_obj_create(lv_scr_act());
lv_obj_set_grid_dsc_array(cont, col_dsc, row_dsc);
lv_obj_set_size(cont, Display.width(), Display.height());
lv_obj_set_style_bg_color(cont, lv_color_hex(0x03989e), LV_PART_MAIN);
lv_obj_center(cont);

lv_obj_t * label;
lv_obj_t * obj;

/* [0;0] - Image */
obj = lv_obj_create(cont);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1,
LV_GRID_ALIGN_STRETCH, 0, 1);

LV_IMG_DECLARE(img_arduinologo);
lv_obj_t * img1 = lv_img_create(obj);
lv_img_set_src(img1, &img_arduinologo);
lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_size(img1, 200, 150);

/* [1;0] - Checkboxes and button */
obj = lv_obj_create(cont);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 1, 1,
LV_GRID_ALIGN_STRETCH, 0, 1);
lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN);

lv_obj_t * cb;
cb = lv_checkbox_create(obj);
lv_checkbox_set_text(cb, "Apple");

cb = lv_checkbox_create(obj);
lv_checkbox_set_text(cb, "Banana");
lv_obj_add_state(cb, LV_STATE_CHECKED);

static lv_style_t style_radio;
static lv_style_t style_radio_chk;
lv_style_init(&style_radio);
lv_style_set_radius(&style_radio, LV_RADIUS_CIRCLE);
lv_style_init(&style_radio_chk);
lv_style_set_bg_img_src(&style_radio_chk, NULL);

cb = lv_checkbox_create(obj);
lv_checkbox_set_text(cb, "Lemon");
lv_obj_add_flag(cb, LV_OBJ_FLAG_EVENT_BUBBLE);
lv_obj_add_style(cb, &style_radio, LV_PART_INDICATOR);
lv_obj_add_style(cb, &style_radio_chk, LV_PART_INDICATOR | LV_STATE_CHECKED);

cb = lv_checkbox_create(obj);
lv_checkbox_set_text(cb, "Melon");
lv_obj_add_flag(cb, LV_OBJ_FLAG_EVENT_BUBBLE);
lv_obj_add_style(cb, &style_radio, LV_PART_INDICATOR);
lv_obj_add_style(cb, &style_radio_chk, LV_PART_INDICATOR | LV_STATE_CHECKED);
lv_obj_add_state(cb, LV_STATE_CHECKED);

lv_obj_t * btn = lv_btn_create(obj);
lv_obj_set_size(btn, 100, 40);
lv_obj_center(btn);
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL);

label = lv_label_create(btn);
lv_label_set_text(label, "Click me!");
lv_obj_center(label);

/* [0;1] - Slider */
obj = lv_obj_create(cont);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1,
LV_GRID_ALIGN_STRETCH, 1, 1);

lv_obj_t * slider = lv_slider_create(obj);
lv_slider_set_value(slider, 75, LV_ANIM_OFF);
lv_obj_center(slider);
label = lv_label_create(obj);
lv_label_set_text(label, "Drag me!");
lv_obj_align_to(label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

/* [1;1] - Bar */
obj = lv_obj_create(cont);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 1, 1,
LV_GRID_ALIGN_STRETCH, 1, 1);

lv_obj_t * bar = lv_bar_create(obj);
lv_obj_set_size(bar, 200, 20);
lv_obj_center(bar);
lv_bar_set_value(bar, 70, LV_ANIM_OFF);

lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_exec_cb(&a, set_slider_val);
lv_anim_set_time(&a, 3000);
lv_anim_set_playback_time(&a, 3000);
lv_anim_set_var(&a, bar);
lv_anim_set_values(&a, 0, 100);
lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
lv_anim_start(&a);
}

void loop() {
/* Feed LVGL engine */
lv_timer_handler();
}
647 changes: 647 additions & 0 deletions libraries/Arduino_H7_Video/examples/LVGLDemo/img_arduinologo.c

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions libraries/Arduino_H7_Video/keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
##################################################
# Syntax Coloring Map For Arduino_H7_Video
##################################################
# Class
##################################################

Arduino_H7_Video KEYWORD1

##################################################
# Methods and Functions
##################################################

begin KEYWORD2
end KEYWORD2

width KEYWORD2
height KEYWORD2

clear KEYWORD2
beginDraw KEYWORD2
endDraw KEYWORD2
set KEYWORD2

##################################################
# Constants
##################################################
9 changes: 9 additions & 0 deletions libraries/Arduino_H7_Video/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=Arduino_H7_Video
version=1.0
author=Arduino
maintainer=Arduino <info@arduino.cc>
sentence=Video library for Arduino boards based on the STM32H7 microcontroller
paragraph=
category=Display
url=https://github.com/arduino/ArduinoCore-mbed/tree/main/libraries/Arduino_H7_Video
architectures=mbed,mbed_portenta,mbed_giga
202 changes: 202 additions & 0 deletions libraries/Arduino_H7_Video/src/Arduino_H7_Video.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/*
* Copyright 2023 Arduino SA
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/

/**
* @file Arduino_H7_Video.cpp
* @author Leonardo Cavagnis
* @brief Source file for the Arduino H7 Video library.
*/

/* Includes ------------------------------------------------------------------*/
#include "Arduino_H7_Video.h"

#include "dsi.h"
#include "SDRAM.h"
extern "C" {
#include "video_modes.h"
}

#if __has_include ("lvgl.h")
#include "lvgl.h"
#endif

/* Private function prototypes -----------------------------------------------*/
#if __has_include ("lvgl.h")
void lvgl_displayFlushing(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p);
#endif

/* Functions -----------------------------------------------------------------*/
Arduino_H7_Video::Arduino_H7_Video(int width, int height, H7DisplayShield &shield)
#ifdef HAS_ARDUINOGRAPHICS
: ArduinoGraphics(width, height)
#endif
{
_height = height;
_width = width;
_shield = &shield;
_edidMode = _shield->getEdidMode(width, height);

switch(_edidMode) {
case EDID_MODE_640x480_60Hz ... EDID_MODE_800x600_59Hz:
case EDID_MODE_1024x768_60Hz ... EDID_MODE_1920x1080_60Hz:
_rotated = (width < height) ? true : false;
break;
case EDID_MODE_480x800_60Hz:
_rotated = (width >= height) ? true : false;
break;
default:
_rotated = false;
break;
}
}

Arduino_H7_Video::~Arduino_H7_Video() {
}

int Arduino_H7_Video::begin() {
#ifdef HAS_ARDUINOGRAPHICS
if (!ArduinoGraphics::begin()) {
return 1; /* Unknown err */
}

textFont(Font_5x7);
#endif

/* Video controller/bridge init */
_shield->init(_edidMode);

#if __has_include("lvgl.h")
/* Initiliaze LVGL library */
lv_init();

/* Create a draw buffer */
static lv_disp_draw_buf_t draw_buf;
static lv_color_t * buf1;
buf1 = (lv_color_t*)malloc((width() * height() / 10) * sizeof(lv_color_t)); /* Declare a buffer for 1/10 screen size */
if (buf1 == NULL) {
return 2; /* Insuff memory err */
}
lv_disp_draw_buf_init(&draw_buf, buf1, NULL, width() * height() / 10); /* Initialize the display buffer. */

/* Initialize display features for LVGL library */
static lv_disp_drv_t disp_drv; /* Descriptor of a display driver */
lv_disp_drv_init(&disp_drv); /* Basic initialization */
disp_drv.flush_cb = lvgl_displayFlushing; /* Set your driver function */
disp_drv.draw_buf = &draw_buf; /* Assign the buffer to the display */
if(_rotated) {
disp_drv.hor_res = height(); /* Set the horizontal resolution of the display */
disp_drv.ver_res = width(); /* Set the vertical resolution of the display */
disp_drv.rotated = LV_DISP_ROT_270;
} else {
disp_drv.hor_res = width(); /* Set the horizontal resolution of the display */
disp_drv.ver_res = height(); /* Set the vertical resolution of the display */
disp_drv.rotated = LV_DISP_ROT_NONE;
}
disp_drv.sw_rotate = 1;
lv_disp_drv_register(&disp_drv); /* Finally register the driver */
#endif

/* Configure SDRAM */
SDRAM.begin(dsi_getFramebufferEnd()); //FIXME: SDRAM init after video controller init can cause display glitch at start-up

return 0;
}

int Arduino_H7_Video::width() {
return _width;
}

int Arduino_H7_Video::height() {
return _height;
}

bool Arduino_H7_Video::isRotated() {
return _rotated;
}

void Arduino_H7_Video::end() {
#ifdef HAS_ARDUINOGRAPHICS
ArduinoGraphics::end();
#endif
}

#ifdef HAS_ARDUINOGRAPHICS
void Arduino_H7_Video::beginDraw() {
ArduinoGraphics::beginDraw();

dsi_lcdClear(0);
}

void Arduino_H7_Video::endDraw() {
ArduinoGraphics::endDraw();

dsi_drawCurrentFrameBuffer();
}

void Arduino_H7_Video::clear(){
uint32_t bg = ArduinoGraphics::background();
uint32_t x_size, y_size;

if(_rotated) {
x_size = (height() <= dsi_getDisplayXSize())? height() : dsi_getDisplayXSize();
y_size = (width() <= dsi_getDisplayYSize())? width() : dsi_getDisplayYSize();
} else {
x_size = (width() <= dsi_getDisplayXSize())? width() : dsi_getDisplayXSize();
y_size = (height() <= dsi_getDisplayYSize())? height() : dsi_getDisplayYSize();
}

dsi_lcdFillArea((void *)(dsi_getCurrentFrameBuffer()), x_size, y_size, bg);
}

void Arduino_H7_Video::set(int x, int y, uint8_t r, uint8_t g, uint8_t b) {
uint32_t x_rot, y_rot;

if (_rotated) {
x_rot = ((height()-1) - y);
y_rot = x;

if (x_rot >= height() || y_rot >= width())
return;
} else {
x_rot = x;
y_rot = y;

if (x_rot >= width() || y_rot >= height())
return;
}

if (x_rot >= dsi_getDisplayXSize() || y_rot >= dsi_getDisplayYSize())
return;

uint32_t color = (uint32_t)((uint32_t)(r << 16) | (uint32_t)(g << 8) | (uint32_t)(b << 0));
dsi_lcdFillArea((void *)(dsi_getCurrentFrameBuffer() + ((x_rot + (dsi_getDisplayXSize() * y_rot)) * sizeof(uint16_t))), 1, 1, color);
}
#endif

#if __has_include("lvgl.h")
void lvgl_displayFlushing(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p) {
uint32_t width = lv_area_get_width(area);
uint32_t height = lv_area_get_height(area);
uint32_t offsetPos = (area->x1 + (dsi_getDisplayXSize() * area->y1)) * sizeof(uint16_t);

dsi_lcdDrawImage((void *) color_p, (void *)(dsi_getActiveFrameBuffer() + offsetPos), width, height, DMA2D_INPUT_RGB565);
lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/
}
#endif

/**** END OF FILE ****/
142 changes: 142 additions & 0 deletions libraries/Arduino_H7_Video/src/Arduino_H7_Video.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* Copyright 2023 Arduino SA
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/

/**
* @file Arduino_H7_Video.h
* @author Leonardo Cavagnis
* @brief Header file for the Arduino H7 Video library.
*
* This library allows to manage the video output on Arduino boards based on the STM32H7 microcontroller
* providing functions to draw graphics on the screen.
*/

#ifndef _ARDUINO_H7_VIDEO_H
#define _ARDUINO_H7_VIDEO_H

/* Includes ------------------------------------------------------------------*/
#include "H7DisplayShield.h"
#if __has_include ("HasIncludeArduinoGraphics.h")
#include "ArduinoGraphics.h"
#define HAS_ARDUINOGRAPHICS
#endif

/* Exported defines ----------------------------------------------------------*/

/* Exported enumeration ------------------------------------------------------*/

/* Class ----------------------------------------------------------------------*/

/**
* @class Arduino_H7_Video
* @brief The main class for managing the video controller and the display.
*/
class Arduino_H7_Video
#ifdef HAS_ARDUINOGRAPHICS
: public ArduinoGraphics
#endif
{
public:
/**
* @brief Constructs a new Arduino_H7_Video object with the specified width, height, and display shield.
*
* @param width The width of the display.
* @param height The height of the display.
* @param shield The display shield used.
* - GigaDisplayShield: Giga Display Shield
* - USBCVideo: Display attach to the USB-C port
*/
#if defined(ARDUINO_PORTENTA_H7_M7)
Arduino_H7_Video(int width = 1024, int height = 768, H7DisplayShield &shield = USBCVideo);
#elif defined(ARDUINO_GIGA)
Arduino_H7_Video(int width = 800, int height = 480, H7DisplayShield &shield = GigaDisplayShield);
#endif

/**
* @brief Destructor for the Arduino_H7_Video object.
*/
~Arduino_H7_Video();

/**
* @brief Initialize the video controller and display.
*
* @return int 0 if initialization is successful, otherwise an error code.
*/
int begin();

/**
* @brief De-initialize the video controller and display.
*/
void end();

/**
* @brief Get the width of the display.
*
* @return int The width of the display.
*/
int width();

/**
* @brief Get the height of the display.
*
* @return int The height of the display.
*/
int height();

/**
* @brief Check if the display is rotated.
*
* @return bool True if the display is rotated, false otherwise.
*/
bool isRotated();

#ifdef HAS_ARDUINOGRAPHICS
/**
* @brief Clear the display.
*/
void clear();

/**
* @brief Begin drawing operations on the display.
*/
virtual void beginDraw();

/**
* @brief End drawing operations on the display.
*/
virtual void endDraw();

/**
* @brief Set the color of the pixel at the specified coordinates.
*
* @param x The x-coordinate of the pixel.
* @param y The y-coordinate of the pixel.
* @param r The red component of the color.
* @param g The green component of the color.
* @param b The blue component of the color.
*/
virtual void set(int x, int y, uint8_t r, uint8_t g, uint8_t b);
#endif
private:
H7DisplayShield* _shield;
bool _rotated;
int _edidMode;
uint32_t _width;
uint32_t _height;
};

#endif /* _ARDUINO_H7_VIDEO_H */
50 changes: 50 additions & 0 deletions libraries/Arduino_H7_Video/src/H7DisplayShield.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "H7DisplayShield.h"

#include "Arduino.h"
#include "anx7625.h"
#include "st7701.h"
extern "C" {
#include "video_modes.h"
}

int GigaDisplayShieldClass::init(int edidmode) {
//Init LCD Controller
st7701_init((enum edid_modes) edidmode);

return 0;
}

int GigaDisplayShieldClass::getEdidMode(int h, int v) {
return EDID_MODE_480x800_60Hz;
}

int USBCVideoClass::init(int edidmode) {
struct edid recognized_edid;
int err_code = 0;

//Initialization of ANX7625
err_code = anx7625_init(0);
if(err_code < 0) {
return err_code;
}

//Checking HDMI plug event
anx7625_wait_hpd_event(0);

//Read EDID
anx7625_dp_get_edid(0, &recognized_edid);

//DSI Configuration
anx7625_dp_start(0, &recognized_edid, (enum edid_modes) edidmode);

return 0;
}

int USBCVideoClass::getEdidMode(int h, int v) {
int edidmode = video_modes_get_edid(h, v);

return edidmode;
}

GigaDisplayShieldClass GigaDisplayShield;
USBCVideoClass USBCVideo;
23 changes: 23 additions & 0 deletions libraries/Arduino_H7_Video/src/H7DisplayShield.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once
#include "Arduino.h"

class H7DisplayShield {
public:
virtual int init(int edidmode) = 0;
virtual int getEdidMode(int h, int v);
};

class GigaDisplayShieldClass : public H7DisplayShield {
public:
int init(int edidmode);
int getEdidMode(int h, int v);
};

class USBCVideoClass : public H7DisplayShield {
public:
int init(int edidmode);
int getEdidMode(int h, int v);
};

extern GigaDisplayShieldClass GigaDisplayShield;
extern USBCVideoClass USBCVideo;

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions libraries/Arduino_H7_Video/src/anx7625.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
******************************************************************************
* @file anx7625.h
* @author
* @version
* @date
* @brief
******************************************************************************
*/

#ifndef _ANX7625_H
#define _ANX7625_H

/* Includes ------------------------------------------------------------------*/
extern "C" {
#include <edid.h>
}

/* Exported functions --------------------------------------------------------*/
int anx7625_dp_start(uint8_t bus, const struct edid *edid, enum edid_modes mode = EDID_MODE_AUTO);
int anx7625_dp_get_edid(uint8_t bus, struct edid *out);
int anx7625_init(uint8_t bus);
void anx7625_wait_hpd_event(uint8_t bus);
int anx7625_get_cc_status(uint8_t bus, uint8_t *cc_status);
int anx7625_read_system_status(uint8_t bus, uint8_t *sys_status);
bool anx7625_is_power_provider(uint8_t bus);

#endif /* _ANX7625_H */

Large diffs are not rendered by default.

46 changes: 46 additions & 0 deletions libraries/Arduino_H7_Video/src/dsi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
******************************************************************************
* @file dsi.h
* @author
* @version
* @date
* @brief
******************************************************************************
*/

/* Includes ------------------------------------------------------------------*/
#ifndef _DSI_H
#define _DSI_H

/* Exported struct -----------------------------------------------------------*/
struct display_timing {
unsigned int pixelclock;
unsigned int hactive;
unsigned int hfront_porch;
unsigned int hback_porch;
unsigned int hsync_len;
unsigned int vactive;
unsigned int vfront_porch;
unsigned int vback_porch;
unsigned int vsync_len;
unsigned int hpol : 1;
unsigned int vpol : 1;
};

/* Exported variables --------------------------------------------------------*/
extern DSI_HandleTypeDef dsi;

/* Exported functions --------------------------------------------------------*/
int dsi_init(uint8_t bus, struct edid *edid, struct display_timing *dt);
void dsi_lcdClear(uint32_t color);
void dsi_lcdDrawImage(void *pSrc, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t ColorMode);
void dsi_lcdFillArea(void *pDst, uint32_t xSize, uint32_t ySize, uint32_t ColorMode);
void dsi_configueCLUT(uint32_t* clut);
void dsi_drawCurrentFrameBuffer(void);
uint32_t dsi_getCurrentFrameBuffer(void);
uint32_t dsi_getActiveFrameBuffer(void);
uint32_t dsi_getFramebufferEnd(void);
uint32_t dsi_getDisplayXSize(void);
uint32_t dsi_getDisplayYSize(void);

#endif /* _DSI_H */

Large diffs are not rendered by default.

File renamed without changes.
File renamed without changes.
762 changes: 762 additions & 0 deletions libraries/Arduino_H7_Video/src/lv_conf.h

Large diffs are not rendered by default.

263 changes: 263 additions & 0 deletions libraries/Arduino_H7_Video/src/st7701.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
/**
******************************************************************************
* @file st7701.cpp
* @author
* @version
* @date
* @brief
******************************************************************************
*/

/* Includes ------------------------------------------------------------------*/
#include "Arduino.h"
#include "st7701.h"
#include "dsi.h"
#include "video_modes.h"

/* Private define ------------------------------------------------------------*/
/* Command2 BKx selection command */
#define DSI_CMD2BKX_SEL 0xFF
#define DSI_CMD2BK1_SEL 0x11
#define DSI_CMD2BK0_SEL 0x10
#define DSI_CMD2BKX_SEL_NONE 0x00

/* Command2, BK0 commands */
#define DSI_CMD2_BK0_PVGAMCTRL 0xB0 /* Positive Voltage Gamma Control */
#define DSI_CMD2_BK0_NVGAMCTRL 0xB1 /* Negative Voltage Gamma Control */
#define DSI_CMD2_BK0_LNESET 0xC0 /* Display Line setting */
#define DSI_CMD2_BK0_PORCTRL 0xC1 /* Porch control */
#define DSI_CMD2_BK0_INVSEL 0xC2 /* Inversion selection, Frame Rate Control */

/* Command2, BK1 commands */
#define DSI_CMD2_BK1_VRHS 0xB0 /* Vop amplitude setting */
#define DSI_CMD2_BK1_VCOM 0xB1 /* VCOM amplitude setting */
#define DSI_CMD2_BK1_VGHSS 0xB2 /* VGH Voltage setting */
#define DSI_CMD2_BK1_TESTCMD 0xB3 /* TEST Command Setting */
#define DSI_CMD2_BK1_VGLS 0xB5 /* VGL Voltage setting */
#define DSI_CMD2_BK1_PWCTLR1 0xB7 /* Power Control 1 */
#define DSI_CMD2_BK1_PWCTLR2 0xB8 /* Power Control 2 */
#define DSI_CMD2_BK1_SPD1 0xC1 /* Source pre_drive timing set1 */
#define DSI_CMD2_BK1_SPD2 0xC2 /* Source EQ2 Setting */
#define DSI_CMD2_BK1_MIPISET1 0xD0 /* MIPI Setting 1 */

#define MIPI_DCS_SOFT_RESET 0x01
#define MIPI_DCS_EXIT_SLEEP_MODE 0x11

#define hdsi_eval dsi

#define LCD_ST7701_ID 0x00 // VC (Virtual channel, for using muliple displays)

#define Delay(x) delay(x)

/* Private macro -------------------------------------------------------------*/
#define SSD_MODE(a,b)
#define Set_POWER(a,b,c,d)
#define Set_STANDBY()
#define Set_BOOST(a,b,c,d)
#define Set_RESET(a,b)
#define SSD_LANE(a,b)

/* Private variables ---------------------------------------------------------*/
const uint16_t _E5[17] = {0xE5,0x0E,0x2D,0xA0,0xa0,0x10,0x2D,0xA0,0xA0,0x0A,0x2D,0xA0,0xA0,0x0C,0x2D,0xA0,0xA0};
const uint16_t _E8[17] = {0xE8,0x0D,0x2D,0xA0,0xA0,0x0F,0x2D,0xA0,0xA0,0x09,0x2D,0xA0,0xA0,0x0B,0x2D,0xA0,0xA0};
const uint16_t _ED[17] = {0xED,0xAB,0x89,0x76,0x54,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x10,0x45,0x67,0x98,0xBA};

/* Private function prototypes -----------------------------------------------*/
static void Generic_Long_Write(uint8_t* pdata, int length);
static void DCS_Short_Write_NP(uint8_t data0);
static void Generic_Short_Write_1P(uint8_t data0, uint8_t data1);
static void DCS_Short_Read_NP(uint8_t data0, int length, uint8_t* p_data);

/* Functions -----------------------------------------------------------------*/

void st7701_init(enum edid_modes mode) {
struct edid _edid;
struct display_timing dt;

//DSI Configuration
dt.pixelclock = envie_known_modes[mode].pixel_clock;
dt.hactive = envie_known_modes[mode].hactive;
dt.hsync_len = envie_known_modes[mode].hsync_len;
dt.hback_porch = envie_known_modes[mode].hback_porch;
dt.hfront_porch = envie_known_modes[mode].hfront_porch;
dt.vactive = envie_known_modes[mode].vactive;
dt.vsync_len = envie_known_modes[mode].vsync_len;
dt.vback_porch = envie_known_modes[mode].vback_porch;
dt.vfront_porch = envie_known_modes[mode].vfront_porch;
dt.hpol = envie_known_modes[mode].hpol;
dt.vpol = envie_known_modes[mode].vpol;
dsi_init(0, &_edid, &dt);

DCS_Short_Write_NP(MIPI_DCS_SOFT_RESET);
Delay(200);

//ST7701S+IVO5.0
DCS_Short_Write_NP(MIPI_DCS_EXIT_SLEEP_MODE);

//------------------------------------------Bank0 Setting------------------------------------------------//
//------------------------------------Display Control setting--------------------------------------------//
Delay(800);

const uint8_t Display_Control_0[] = {0xFF,0x77,0x01,0x00,0x00,0x10};
const uint8_t Display_Control_1[] = {0xC0,0x63,0x00};
const uint8_t Display_Control_2[] = {0xC1,0x11,0x02};
const uint8_t Display_Control_3[] = {0xC2,0x01,0x08};
const uint8_t Display_Control_4[] = {0xCC,0x18};

Generic_Long_Write((uint8_t*)Display_Control_0, sizeof(Display_Control_0));
Generic_Long_Write((uint8_t*)Display_Control_1, sizeof(Display_Control_1));
Generic_Long_Write((uint8_t*)Display_Control_2, sizeof(Display_Control_2));
Generic_Long_Write((uint8_t*)Display_Control_3, sizeof(Display_Control_3));
Generic_Long_Write((uint8_t*)Display_Control_4, sizeof(Display_Control_4));

//-------------------------------------Gamma Cluster Setting---------------------------------------------//
const uint8_t _B0[] = {0xB0, 0x40, 0xc9, 0x91, 0x0d,
0x12, 0x07, 0x02, 0x09, 0x09,
0x1f, 0x04, 0x50, 0x0f, 0xe4,
0x29, 0xdf};

const uint8_t _B1[] = {0xB1, 0x40, 0xcb, 0xd0, 0x11,
0x92, 0x07, 0x00, 0x08, 0x07,
0x1c, 0x06, 0x53, 0x12, 0x63,
0xeb, 0xdf};

Generic_Long_Write((uint8_t*)_B0, sizeof(_B0));
Generic_Long_Write((uint8_t*)_B1, sizeof(_B1));

//---------------------------------------End Gamma Setting-----------------------------------------------//
//------------------------------------End Display Control setting----------------------------------------//
//-----------------------------------------Bank0 Setting End---------------------------------------------//

//-------------------------------------------Bank1 Setting-----------------------------------------------//
//-------------------------------- Power Control Registers Initial --------------------------------------//
const uint8_t _FF1[] = {DSI_CMD2BKX_SEL,0x77,0x01,0x00,0x00,DSI_CMD2BK1_SEL};
Generic_Long_Write ((uint8_t*)_FF1, sizeof(_FF1));

Generic_Short_Write_1P (DSI_CMD2_BK1_VRHS,0x65);
//-------------------------------------------Vcom Setting------------------------------------------------//
Generic_Short_Write_1P (DSI_CMD2_BK1_VCOM,0x34);
//-----------------------------------------End Vcom Setting----------------------------------------------//
Generic_Short_Write_1P (DSI_CMD2_BK1_VGHSS,0x87);
Generic_Short_Write_1P (DSI_CMD2_BK1_TESTCMD,0x80);

Generic_Short_Write_1P (DSI_CMD2_BK1_VGLS,0x49);
Generic_Short_Write_1P (DSI_CMD2_BK1_PWCTLR1,0x85);

Generic_Short_Write_1P (DSI_CMD2_BK1_PWCTLR2,0x20);
Generic_Short_Write_1P (0xB9,0x10);
Generic_Short_Write_1P (DSI_CMD2_BK1_SPD1,0x78);
Generic_Short_Write_1P (DSI_CMD2_BK1_SPD2,0x78);
Generic_Short_Write_1P (DSI_CMD2_BK1_MIPISET1,0x88);
//---------------------------------End Power Control Registers Initial ----------------------------------//
Delay(100);
//---------------------------------------------GIP Setting-----------------------------------------------//
const uint8_t _E0[] = {0xE0,0x00,0x00,0x02};
Generic_Long_Write((uint8_t*)_E0, sizeof(_E0));
//----------------------------------GIP------------------------------------------------------------------//
const uint8_t _E1[] = {0xE1,0x08,0x00,0x0A,0x00,0x07,0x00,0x09,0x00,0x00,0x33,0x33};
const uint8_t _E2[] = {0xE2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
Generic_Long_Write((uint8_t*)_E1, sizeof(_E1));
Generic_Long_Write((uint8_t*)_E2, sizeof(_E2));

//-------------------------------------------------------------------------------------------------------//
const uint8_t _E3[] = {0xE3,0x00,0x00,0x33,0x33};
const uint8_t _E4[] = {0xE4,0x44,0x44};
Generic_Long_Write((uint8_t*)_E3, sizeof(_E3));
Generic_Long_Write((uint8_t*)_E4, sizeof(_E4));

const uint8_t _E5[] = {0xE5,0x0E,0x60,0xA0,0xa0,0x10,0x60,0xA0,0xA0,0x0A,0x60,0xA0,0xA0,0x0C,0x60,0xA0,0xA0};
Generic_Long_Write((uint8_t*)_E5, sizeof(_E5));

const uint8_t _E6[] = {0xE6,0x00,0x00,0x33,0x33};
const uint8_t _E7[] = {0xE7,0x44,0x44};
Generic_Long_Write((uint8_t*)_E6, sizeof(_E6));
Generic_Long_Write((uint8_t*)_E7, sizeof(_E7));

const uint8_t _E8[] = {0xE8,0x0D,0x60,0xA0,0xA0,0x0F,0x60,0xA0,0xA0,0x09,0x60,0xA0,0xA0,0x0B,0x60,0xA0,0xA0};
Generic_Long_Write((uint8_t*)_E8, sizeof(_E8));

const uint8_t _EB[] = {0xEB,0x02,0x01,0xE4,0xE4,0x44,0x00,0x40};
const uint8_t _EC[] = {0xEC,0x02,0x01};
Generic_Long_Write((uint8_t*)_EB, sizeof(_EB));
Generic_Long_Write((uint8_t*)_EC, sizeof(_EC));

const uint8_t _ED[17] = {0xED,0xAB,0x89,0x76,0x54,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x10,0x45,0x67,0x98,0xBA};
Generic_Long_Write((uint8_t*)_ED, sizeof(_ED));

//--------------------------------------------End GIP Setting-----------------------------------------------//
//------------------------------ Power Control Registers Initial End----------------------------------------//
//------------------------------------------Bank1 Setting---------------------------------------------------//
const uint8_t _FF2[] = {DSI_CMD2BKX_SEL,0x77,0x01,0x00,0x00,DSI_CMD2BKX_SEL_NONE};
Generic_Long_Write ((uint8_t*)_FF2, sizeof(_FF2));

Delay(10);
DCS_Short_Write_NP(0x29);
Delay(200);

SSD_MODE(0,1);
}

void st7701_DisplayOn() {
Set_POWER(1,1,1,1);//1.8V ON, 2.8V ON, 5V ON, BL ON
}

void st7701_PowerOffSequence() {
DCS_Short_Write_NP(0x28);
Delay(200);
DCS_Short_Write_NP(0x10);
Delay(100);
Set_STANDBY();//Video transfer stop
Delay(50);

Set_RESET(1,0);//MIPI RESET 1, LCD RESET 0
Delay(50);
Set_RESET(0,0);//MIPI RESET 0, LCD RESET 0
Delay(50);

Set_POWER(1,1,0,1);//1.8V ON, 2.8V ON, 5V OFF, BL ON
Delay(50);

Set_BOOST(5.00, 5.00, 0x81, 50);//VDD, VEE, OFF:VDD->VEE, 10ms
Delay(50);

Set_POWER(1,0,0,1);//1.8V ON, 2.8V OFF, 5V OFF, BL ON
Delay(100);
Set_POWER(0,0,0,0);//1.8V OFF, 2.8V OFF, 5V OFF, BL OFF
}

void st7701_ReadOperation() {
uint8_t BUFFER[8];

//Clean memory: BUFFER
memset(BUFFER, 0, sizeof(BUFFER));//BUFFER size: 8 Bytes

//Read value to BUFFER
DCS_Short_Read_NP(0xDA, 1, BUFFER+0);
DCS_Short_Read_NP(0xDB, 1, BUFFER+1);
DCS_Short_Read_NP(0xDC, 1, BUFFER+2);
}

void DCS_Short_Write_NP(uint8_t data0) {
HAL_DSI_ShortWrite(&hdsi_eval, LCD_ST7701_ID, DSI_DCS_SHORT_PKT_WRITE_P1, data0, 0x00); // DSI_DCS_SHORT_PKT_WRITE_P0
}

void Generic_Short_Write_1P(uint8_t data0, uint8_t data1) {
HAL_DSI_ShortWrite(&hdsi_eval, LCD_ST7701_ID, DSI_GEN_SHORT_PKT_WRITE_P1, data0, data1);
}

void Generic_Long_Write(uint8_t* pdata, int length) {
uint8_t data_buf[19] = {0}; // data_buf size with command(*pdata) = 20 so data is alligned 4
uint8_t data_length = length- 1;

if (data_length > sizeof(data_buf))
return;

memcpy(data_buf, pdata+1, data_length);
HAL_DSI_LongWrite(&hdsi_eval, LCD_ST7701_ID, DSI_DCS_LONG_PKT_WRITE, data_length, *pdata, data_buf);
}

void DCS_Short_Read_NP(uint8_t data0, int length, uint8_t* p_data) {
HAL_DSI_Read(&hdsi_eval, LCD_ST7701_ID, p_data, length, DSI_DCS_SHORT_PKT_READ, data0, NULL);
}

/**** END OF FILE ****/
20 changes: 20 additions & 0 deletions libraries/Arduino_H7_Video/src/st7701.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
******************************************************************************
* @file st7701.h
* @author
* @version
* @date
* @brief
******************************************************************************
*/

#ifndef _ST7701_H
#define _ST7701_H

/* Includes ------------------------------------------------------------------*/
#include "edid.h"

/* Exported functions --------------------------------------------------------*/
void st7701_init(enum edid_modes mode);

#endif /* _ST7701_H */
107 changes: 107 additions & 0 deletions libraries/Arduino_H7_Video/src/video_modes.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/**
******************************************************************************
* @file video_modes.c
* @author
* @version
* @date
* @brief
******************************************************************************
*/

/* Includes ------------------------------------------------------------------*/
#include "video_modes.h"

/* Exported variables --------------------------------------------------------*/
struct envie_edid_mode envie_known_modes[NUM_KNOWN_MODES] = {
[EDID_MODE_640x480_60Hz] = {
.name = "640x480@75Hz", .pixel_clock = 29400, .refresh = 60,
.hactive = 640, .hback_porch = 160, .hfront_porch = 16, .hsync_len = 96,
.vactive = 480, .vback_porch = 45, .vfront_porch = 10, .vsync_len = 2,
},
[EDID_MODE_720x480_60Hz] = {
.name = "720x480@60Hz", .pixel_clock = 27800, .refresh = 60,
.hactive = 720, .hback_porch = 60, .hfront_porch = 16, .hsync_len = 62,
.vactive = 480, .vback_porch = 45, .vfront_porch = 9, .vsync_len = 6,
},
[EDID_MODE_800x600_59Hz] = {
.name = "800x600@60Hz", .pixel_clock = 37800, .refresh = 60,
.hactive = 800, .hback_porch = 104, .hfront_porch = 24, .hsync_len = 80,
.vactive = 600, .vback_porch = 17, .vfront_porch = 3, .vsync_len = 4,
},
[EDID_MODE_480x800_60Hz] = {
.name = "480x800@60Hz", .pixel_clock = 38000, .refresh = 60,
.hactive = 480, .hback_porch = 30, .hfront_porch = 320, .hsync_len = 24,
.vactive = 800, .vback_porch = 50, .vfront_porch = 20, .vsync_len = 4,
.hpol = 1, .vpol = 1,
},
[EDID_MODE_1024x768_60Hz] = {
.name = "1024x768@60Hz", .pixel_clock = 57800, .refresh = 60,
.hactive = 1024, .hback_porch = 80, .hfront_porch = 24, .hsync_len = 68, .hpol = 0,
.vactive = 768, .vback_porch = 29, .vfront_porch = 3, .vsync_len = 6, .vpol = 0,
},
//NOTE: Not supported by STM32H747: Pixel Clock > 58MHz (LTDC + DMA2D + SDRAM 16-bit, source: AN4861rev4-Table12)
[EDID_MODE_1280x768_60Hz] = {
.name = "1280x768@60Hz", .pixel_clock = 68300, .refresh = 60,
.hactive = 1280, .hback_porch = 120, .hfront_porch = 32, .hsync_len = 20,
.vactive = 768, .vback_porch = 10, .vfront_porch = 45, .vsync_len = 12,
},
//NOTE: Not supported by STM32H747: Pixel Clock > 58MHz (LTDC + DMA2D + SDRAM 16-bit, source: AN4861rev4-Table12)
[EDID_MODE_1280x720_60Hz] = {
.name = "1280x720@60Hz", .pixel_clock = 74300, .refresh = 60,
.hactive = 1280, .hback_porch = 370, .hfront_porch = 110, .hsync_len = 40,
.vactive = 720, .vback_porch = 30, .vfront_porch = 5, .vsync_len = 20,
},
//NOTE: Not supported by STM32H747: Pixel Clock > 58MHz (LTDC + DMA2D + SDRAM 16-bit, source: AN4861rev4-Table12)
[EDID_MODE_1920x1080_60Hz] = {
.name = "1920x1080@60Hz", .pixel_clock = 148500, .refresh = 60,
.hactive = 1920, .hback_porch = 280, .hfront_porch = 88, .hsync_len = 44,
.vactive = 1080, .vback_porch = 45, .vfront_porch = 4, .vsync_len = 4,
},
};

/* Functions -----------------------------------------------------------------*/

enum edid_modes video_modes_get_edid(uint32_t h_check, uint32_t v_check) {
int sum = 0;
int sel_mode = -1;
int sel_sum = 0;

for (int i = 0; i<NUM_KNOWN_MODES; i++) {
if (h_check <= envie_known_modes[i].hactive && v_check <= envie_known_modes[i].vactive) {
sum = ((int)envie_known_modes[i].hactive - h_check) +
((int)envie_known_modes[i].vactive - v_check);
} else {
sum = -1;
}

if (sum >= 0 && ((sel_mode == -1) || (sum < sel_sum))) {
sel_mode = i;
sel_sum = sum;
}
}

for (int i = 0; i<NUM_KNOWN_MODES; i++) {
if (h_check <= envie_known_modes[i].vactive && v_check <= envie_known_modes[i].hactive) {
sum = ((int)envie_known_modes[i].vactive - h_check) +
((int)envie_known_modes[i].hactive - v_check);
} else {
sum = -1;
}

if (sum >= 0 && ((sel_mode == -1) || (sum < sel_sum))) {
sel_mode = i;
sel_sum = sum;
}
}

if (sel_mode == -1 ||
sel_mode == EDID_MODE_1280x768_60Hz ||
sel_mode == EDID_MODE_1280x720_60Hz ||
sel_mode == EDID_MODE_1920x1080_60Hz) {
sel_mode = EDID_MODE_1024x768_60Hz;
}

return sel_mode;
}

/**** END OF FILE ****/
41 changes: 41 additions & 0 deletions libraries/Arduino_H7_Video/src/video_modes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
******************************************************************************
* @file video_modes.h
* @author
* @version
* @date
* @brief
******************************************************************************
*/

#ifndef _VIDEO_MODES_H
#define _VIDEO_MODES_H

/* Includes ------------------------------------------------------------------*/
#include "edid.h"

/* Exported struct -----------------------------------------------------------*/
struct envie_edid_mode {
const char *name;
unsigned int pixel_clock;
unsigned int refresh;
unsigned int hactive;
unsigned int hback_porch;
unsigned int hfront_porch;
unsigned int hsync_len;
unsigned int vactive;
unsigned int vsync_len;
unsigned int vback_porch;
unsigned int vfront_porch;
unsigned int voffset;
unsigned int hpol : 1;
unsigned int vpol : 1;
};

/* Exported variables --------------------------------------------------------*/
extern struct envie_edid_mode envie_known_modes[];

/* Exported functions --------------------------------------------------------*/
enum edid_modes video_modes_get_edid(uint32_t h_check, uint32_t v_check);

#endif /* _VIDEO_MODES_H */
27 changes: 0 additions & 27 deletions libraries/Portenta_Video/examples/ArduinoLogo/ArduinoLogo.ino

This file was deleted.

9 changes: 0 additions & 9 deletions libraries/Portenta_Video/library.properties

This file was deleted.

2 changes: 0 additions & 2 deletions libraries/Portenta_Video/src/Portenta_Video.h

This file was deleted.

380 changes: 0 additions & 380 deletions libraries/Portenta_Video/src/anx7625.h

This file was deleted.

16 changes: 0 additions & 16 deletions libraries/Portenta_Video/src/dsi.h

This file was deleted.

49 changes: 0 additions & 49 deletions libraries/Portenta_Video/src/video_modes.c

This file was deleted.

16 changes: 0 additions & 16 deletions libraries/Portenta_Video/src/video_modes.h

This file was deleted.

51 changes: 0 additions & 51 deletions libraries/Portenta_lvgl/examples/Giga_lvgl/Giga_lvgl.ino

This file was deleted.

347 changes: 0 additions & 347 deletions libraries/Portenta_lvgl/examples/Giga_lvgl/display.cpp

This file was deleted.

73 changes: 0 additions & 73 deletions libraries/Portenta_lvgl/examples/Giga_lvgl/i2c_touch.cpp

This file was deleted.

261 changes: 0 additions & 261 deletions libraries/Portenta_lvgl/examples/Giga_lvgl/img_clothes.c

This file was deleted.

653 changes: 0 additions & 653 deletions libraries/Portenta_lvgl/examples/Giga_lvgl/img_demo_widget_avatar.c

This file was deleted.

209 changes: 0 additions & 209 deletions libraries/Portenta_lvgl/examples/Giga_lvgl/img_logo.c

This file was deleted.

414 changes: 0 additions & 414 deletions libraries/Portenta_lvgl/examples/Giga_lvgl/lv_demo_widgets.c

This file was deleted.

38 changes: 0 additions & 38 deletions libraries/Portenta_lvgl/examples/Giga_lvgl/lv_demo_widgets.h

This file was deleted.

1,576 changes: 0 additions & 1,576 deletions libraries/Portenta_lvgl/examples/Giga_lvgl/lv_demo_widgets_next.c

This file was deleted.

1,528 changes: 0 additions & 1,528 deletions libraries/Portenta_lvgl/examples/Giga_lvgl/lv_demo_widgets_v8.c

This file was deleted.

This file was deleted.

15 changes: 0 additions & 15 deletions libraries/Portenta_lvgl/examples/Portenta_lvgl/Portenta_lvgl.ino

This file was deleted.

261 changes: 0 additions & 261 deletions libraries/Portenta_lvgl/examples/Portenta_lvgl/img_clothes.c

This file was deleted.

This file was deleted.

209 changes: 0 additions & 209 deletions libraries/Portenta_lvgl/examples/Portenta_lvgl/img_logo.c

This file was deleted.

414 changes: 0 additions & 414 deletions libraries/Portenta_lvgl/examples/Portenta_lvgl/lv_demo_widgets.c

This file was deleted.

38 changes: 0 additions & 38 deletions libraries/Portenta_lvgl/examples/Portenta_lvgl/lv_demo_widgets.h

This file was deleted.

1,576 changes: 0 additions & 1,576 deletions libraries/Portenta_lvgl/examples/Portenta_lvgl/lv_demo_widgets_next.c

This file was deleted.

1,528 changes: 0 additions & 1,528 deletions libraries/Portenta_lvgl/examples/Portenta_lvgl/lv_demo_widgets_v8.c

This file was deleted.

This file was deleted.

9 changes: 0 additions & 9 deletions libraries/Portenta_lvgl/library.properties

This file was deleted.

3 changes: 0 additions & 3 deletions libraries/Portenta_lvgl/src/Portenta_LittleVGL.h

This file was deleted.

4 changes: 0 additions & 4 deletions libraries/Portenta_lvgl/src/Portenta_lvgl.h

This file was deleted.

699 changes: 0 additions & 699 deletions libraries/Portenta_lvgl/src/lv_conf.h

This file was deleted.

268 changes: 0 additions & 268 deletions libraries/Portenta_lvgl/src/porting.cpp

This file was deleted.

39 changes: 11 additions & 28 deletions libraries/doom/src/doomgeneric_arduino.cpp
Original file line number Diff line number Diff line change
@@ -2,7 +2,8 @@

#include "Arduino.h"
#include "mbed.h"
#include "Portenta_Video.h"
#include "Arduino_H7_Video.h"
#include "dsi.h"

#define sleep _sleep

@@ -89,8 +90,6 @@ static void addKeyToQueue(int pressed, unsigned char keyCode)
s_KeyQueueWriteIndex %= KEYQUEUE_SIZE;
}

struct edid recognized_edid;

uint32_t LCD_X_Size = 0, LCD_Y_Size = 0;
DMA2D_HandleTypeDef DMA2D_Handle;

@@ -162,30 +161,13 @@ static void DMA2D_Init(uint16_t xsize, uint16_t ysize)
HAL_DMA2D_PollForTransfer(&DMA2D_Handle, 100);
}

void DG_Init()
{
int ret = -1;

ret = anx7625_init(0);
if(ret < 0) {
printf("Cannot continue, anx7625 init failed.\n");
while(1);
}
Arduino_H7_Video display(640, 480, USBCVideo);

anx7625_wait_hpd_event(0);
anx7625_dp_get_edid(0, &recognized_edid);
//edid_set_framebuffer_bits_per_pixel(&recognized_edid, 16, 0);
//set_display_mode(&recognized_edid, EDID_MODE_720x480_60Hz);
//anx7625_dp_start(0, &recognized_edid, EDID_MODE_1280x720_60Hz);
anx7625_dp_start(0, &recognized_edid, EDID_MODE_640x480_60Hz);
uint32_t fbs[2];

LCD_X_Size = stm32_getXSize();
LCD_Y_Size = stm32_getYSize();

SDRAM.begin(getFramebufferEnd());

stm32_LCD_Clear(0);
stm32_LCD_Clear(0);
void DG_Init()
{
display.begin();
}

void DG_OnPaletteReload() {
@@ -224,8 +206,8 @@ static void DMA2D_CopyBuffer(uint32_t *pSrc, uint32_t *pDst)
uint32_t xPos, yPos, destination;

/*##-1- calculate the destination transfer address ############*/
xPos = (stm32_getXSize() - DOOMGENERIC_RESX) / 2;
yPos = (stm32_getYSize() - DOOMGENERIC_RESY) / 2;
xPos = (display.width() - DOOMGENERIC_RESX) / 2;
yPos = (display.height() - DOOMGENERIC_RESY) / 2;

destination = (uint32_t)pDst; // + ((yPos * stm32_getXSize()) + xPos) * 4;

@@ -239,14 +221,15 @@ static void DMA2D_CopyBuffer(uint32_t *pSrc, uint32_t *pDst)

void DG_DrawFrame()
{
uint32_t fb = getNextFrameBuffer();
uint32_t fb = dsi_getCurrentFrameBuffer();
#ifdef CORE_CM7
//SCB_CleanInvalidateDCache();
//SCB_InvalidateICache();
SCB_InvalidateDCache_by_Addr((uint32_t *)fb, DOOMGENERIC_RESX * DOOMGENERIC_RESY * 4);
#endif

DMA2D_CopyBuffer((uint32_t *)DG_ScreenBuffer, (uint32_t *)fb);
dsi_drawCurrentFrameBuffer();
//handleKeyInput();
}

3 changes: 2 additions & 1 deletion libraries/doom/src/i_video.c
Original file line number Diff line number Diff line change
@@ -114,7 +114,7 @@ int mouse_threshold = 10;

// Gamma correction level to use

int usegamma = 0;
int usegamma = 2;

typedef struct
{
@@ -266,6 +266,7 @@ void I_FinishUpdate (void)
uint8_t* inbuf = I_VideoBuffer;
uint8_t* outbuf = I_VideoBuffer_FB;

// this function simply doubles the resolution
for (uint32_t i = 0; i < SCREENHEIGHT; i++) {
uint8_t* inbuf_temp = inbuf;
uint8_t* outbuf_temp = outbuf;