diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 7f266fa9..1cb401b3 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -8,6 +8,7 @@ on:
push:
branches:
- master
+ - dev*
jobs:
build:
@@ -16,12 +17,24 @@ jobs:
BUILD_TAG: 0
runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ board: [teensy41,disco_f769ni,disco_f750n8,template]
steps:
- name: Checkout repo
uses: actions/checkout@v1
- with:
- submodules: recursive
+
+ - name: Get submoduiles
+ run: |
+ git submodule init
+ git submodule update
+ # If manually get TinyUSBs submodules we need otherwise its a huge repo
+ cd src/lib/tinyusb
+ # Teensy41 Specific
+ git submodule init hw/mcu/nxp/mcux-sdk
+ git submodule update
+ cd ../../../
- name: Set up Python
uses: actions/setup-python@v1
@@ -34,9 +47,23 @@ jobs:
echo "BUILD_TAG=$BUILD_TAG" >> $GITHUB_ENV
- name: Compile code
- run: platformio run -e teensy41
+ run: |
+ platformio platform update
+ platformio run -e ${{ matrix.board }}
+ # platformio system prune --force
+
+ - if: matrix.board != 'template'
+ name: Upload firmware artifact to current run
+ uses: actions/upload-artifact@v2
+ with:
+ name: test-firmware-${{ matrix.board }}
+ path: |
+ .pio/build/**/*.hex
+ # .pio/build/**/*.bin # Should not be required for any boards, and makes upload file size incorrect!
+ .pio/build/**/*.elf
+ # .pio/build/**/*.map # Currently not generated.
- - if: github.event_name == 'push'
+ - if: github.event_name == 'push' && github.ref == 'refs/heads/master' #TODO handle previews
name: Create Release
id: create_release
uses: "actions/create-release@v1"
@@ -46,12 +73,12 @@ jobs:
draft: false
prerelease: false
- - if: github.event_name == 'push'
- name: Upload binary to release
+ - if: github.event_name == 'push' && github.ref == 'refs/heads/master' && matrix.board != 'template' #TODO handle previews
+ name: Upload binary for release
id: upload-release-asset
uses: actions/upload-release-asset@v1
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
- asset_path: .pio/build/teensy41/firmware.hex
- asset_name: firmware-teensy41.hex
+ asset_path: .pio/build/${{ matrix.board }}/firmware.hex
+ asset_name: firmware-${{ matrix.board }}.hex
asset_content_type: application/hex
diff --git a/.gitmodules b/.gitmodules
index 510011ce..b87e9f42 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,11 +1,9 @@
-[submodule "src/printf"]
- path = src/printf
- url = https://github.com/mpaland/printf
-
-[submodule "src/USBHost_t36"]
- path = src/USBHost_t36
- url = https://github.com/Ryzee119/USBHost_t36.git
-
-[submodule "src/ILI9341_t3n"]
- path = src/ILI9341_t3n
+[submodule "src/lib/tinyusb"]
+ path = src/lib/tinyusb
+ url = https://github.com/Ryzee119/tinyusb.git
+[submodule "src/teensy41/ILI9341_t3n"]
+ path = src/port_teensy41/ILI9341_t3n
url = https://github.com/KurtE/ILI9341_t3n.git
+[submodule "src/lib/tinyalloc"]
+ path = src/lib/tinyalloc
+ url = https://github.com/thi-ng/tinyalloc.git
diff --git a/README.md b/README.md
index 2577f6a6..134d18e7 100644
--- a/README.md
+++ b/README.md
@@ -6,14 +6,14 @@ Precompiled binaries can be downloaded from [Releases](https://github.com/Ryzee1
**NOTE: This project is still in development, PRs and ideas are welcome. See todo list for ideas.**
- [x] N64 controller emulation (up to four controllers at once!).
-- [x] Rumblepak emulation.
-- [x] Mempak emulation with four selectable banks. Technically unlimited.
-- [x] Transferpak emulation. Put Gameboy ROMS on an SD Card!
+- [x] Rumble Pak emulation.
+- [x] Controller Pak emulation with four selectable banks. Technically unlimited.
+- [x] Transfer Pak emulation. Put Gameboy ROMS on an SD Card!
- [x] N64 mouse emulation. Use a USB Mouse!
- [x] N64 Randnet emulation. Use a USB keyboard!
- [x] Configurable deadzones and sensitivity from the N64 Console.
- [x] True dual analog sticks with GoldenEye and Perfect Dark.
-- [x] SD card driver with FATFS support for storage/backup of Gameboy ROMS, mempaks etc.
+- [x] SD card driver with FATFS support for storage/backup of Gameboy ROMS, controller paks etc.
- [x] A single hardwired controller interface for ultimate hacking.
- [x] Optional TFT LCD Support.
@@ -36,10 +36,10 @@ Precompiled binaries can be downloaded from [Releases](https://github.com/Ryzee1
- A hardwired controller, use your own buttons etc.
## Controls
-- Back + D-Pad = Insert Mempak banks 1 to 4
+- Back + D-Pad = Insert Controller Pak banks 0 to 3
- Back + LB = Insert Rumblepak
- Back + RB = Insert Transferpak
-- Back + Start = Select *virtual pak* (Use in-game mempak managers to configure the device)
+- Back + Start = Select *virtual pak* (Use in-game Controller Pak managers to configure the device)
- Back + B = Switch to true dual-analog stick more for GoldenEye 007/Perfect Dark
- Back + A = Backup buffered memory to SD Card **(DO THIS BEFORE POWER OFF!)**
diff --git a/USAGE.md b/USAGE.md
index d819e2f4..2ee72242 100644
--- a/USAGE.md
+++ b/USAGE.md
@@ -1,24 +1,24 @@
# Usage
-* [Mempaks](#mempaks)
-* [Rumblepaks](#rumblepaks)
-* [Transferpaks](#transferpaks)
-* [Virtualpak](#virtualpak)
+* [Controller Paks](#controller-paks)
+* [Rumble Paks](#rumble-paks)
+* [Transfer Paks](#transfer-paks)
+* [Virtual Pak](#virtual-pak)
* [Dual Stick Mode](#dual-stick-mode)
* [N64 Mouse](#n64-mouse)
* [TFT LCD Display](#tft-lcd-display)
* [Debug](#debug)
-## Mempaks
+## Controller Paks
* usb64 can simulate four Mempaks simultaneously. To select a Mempak press `BACK+D-PAD` direction to select the respective bank.
* Two controllers cannot have the same bank selected. The second controller will revert to a Rumblepak.
* Do not unplug the usb64's power before turning off the n64 console to prevent data loss. The usb64 senses the n64 console turning off and flushes data to the SD Card.
* Inserting the SD card into your PC will show Mempaks as `MEMPAKXX.MPK` where XX is the bank number. You can back these up to your PC.
-## Rumblepaks
+## Rumble Paks
* usb64 can simulate four Rumblepaks simultaneously. Rumblepaks are the default peripheral on power up. To select a Rumblepak press `BACK+LB`.
* The usb controller must support force feedback.
-## Transferpaks
+## Transfer Paks
* usb64 can simulate four transferpaks simulateneously. The select a Transferpak press `BACK+RB`. The transferpak will attempt to load the previously set Gameboy or Gameboy Colour ROM from the SD Card.
* To select the ROM to load, you must first use the [*VirtualPak*](#virtualpak). If a ROM isn't selected, or fails to load, it will revert to a Rumblepak.
* Avoid having two controllers access the same ROM at once.
@@ -26,11 +26,11 @@
* Gameboy saves can be copied over to the SD Card for use with the Transferpak. The file name must match the ROM save with a `.SAV` extension.
* You can simulate four transferpaks, with four difference ROMS, with four different save files!
-## Virtualpak
-* The Virtualpak is one of my favourite features. It's like a Mempak, but is not used for save files. It exploits the Mempak managers built into some N64 games to configure the usb64 device!
+## Virtual Pak
+* The VirtualCpak is one of my favourite features. It's like a Controller Pak, but is not used for save files. It exploits the Mempak managers built into some N64 games to configure the usb64 device!
* To select the Virtualpak press `BACK+START`.
-* To use the Virtualpak, boot into a game that has a Mempak manager. Some games will work better than others. `Army Men: Air Combat` is a good one. `Perfect Dark` works well too. Hold START whilst the game is booting to access the Mempak manager. The follow screens show `Army Men: Air Combat` and `Perfect Dark` as an example.
-* To select an item, you actually delete that note from the Mempak. usb64 detects what row you selected as if navigating a menu!
+* To use the Virtualpak, boot into a game that has a Contrroller Pak manager. Some games will work better than others. `Army Men: Air Combat` is a good one. `Perfect Dark` works well too. Hold START whilst the game is booting to access the Controller Pak manager. The follow screens show `Army Men: Air Combat` and `Perfect Dark` as an example.
+* To select an item, you actually delete that note from the Controller Pak. usb64 detects what row you selected as if navigating a menu!
* **TPAK SETTINGS** is used to configure what ROM to load into the Transferpak. This will scan the SD card for files with `.gb` and `.gbc` extensions. A `*` will print next to the currently set ROM. You can have up to ten ROMs on the SD card. After this they will just get ignored.
* **CONT SETTINGS** is used to configure the controller. You can change deadzone, Sensitivity, toggle on/off snapping to 45deg angles and toggle on/off a octagonal N64 stick correction. The set values is shown as a number next to the row. Each controller can be configured individually. Note: Some controllers will have deadzones or 45 degree angle snapping built in. For these, usb64 can't disable it.
* **USB64 INFO1** shows what controller is connected to that port.
diff --git a/boards/disco_f750n8_extflash.json b/boards/disco_f750n8_extflash.json
new file mode 100644
index 00000000..a1902d56
--- /dev/null
+++ b/boards/disco_f750n8_extflash.json
@@ -0,0 +1,44 @@
+{
+ "build": {
+ "cpu": "cortex-m7",
+ "extra_flags": "-DSTM32F750xx",
+ "f_cpu": "216000000L",
+ "mcu": "stm32f750n8h6",
+ "product_line": "STM32F750xx"
+ },
+ "connectivity": [
+ "can",
+ "ethernet"
+ ],
+ "debug": {
+ "default_tools": [
+ "stlink"
+ ],
+ "jlink_device": "STM32F750N8",
+ "onboard_tools": [
+ "stlink"
+ ],
+ "openocd_board": "stm32f7discovery",
+ "openocd_target": "stm32f7x",
+ "svd_path": "STM32F750x.svd"
+ },
+ "frameworks": [
+ "cmsis",
+ "stm32cube",
+ "libopencm3"
+ ],
+ "name": "STM32F7508-DK",
+ "upload": {
+ "maximum_ram_size": 327680,
+ "maximum_size": 16777216,
+ "protocol": "stlink",
+ "protocols": [
+ "jlink",
+ "cmsis-dap",
+ "stlink",
+ "blackmagic"
+ ]
+ },
+ "url": "https://www.st.com/content/st_com/en/products/evaluation-tools/product-evaluation-tools/mcu-mpu-eval-tools/stm32-mcu-mpu-eval-tools/stm32-discovery-kits/stm32f7508-dk.html",
+ "vendor": "ST"
+}
diff --git a/hex_from_elf.py b/hex_from_elf.py
new file mode 100644
index 00000000..3be426bc
--- /dev/null
+++ b/hex_from_elf.py
@@ -0,0 +1,10 @@
+Import("env")
+
+# Custom HEX from ELF
+env.AddPostAction(
+ "$BUILD_DIR/${PROGNAME}.elf",
+ env.VerboseAction(" ".join([
+ "$OBJCOPY", "-O", "ihex", "-R", ".eeprom",
+ "$BUILD_DIR/${PROGNAME}.elf", "$BUILD_DIR/${PROGNAME}.hex"
+ ]), "Building $BUILD_DIR/${PROGNAME}.hex")
+)
\ No newline at end of file
diff --git a/platformio.ini b/platformio.ini
index 965f8bbb..d8adca2b 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -25,16 +25,37 @@
src_filter =
+<*.cpp> +<*.c>
+
- +
- +
+ +
+ +
+ +
+ +
+
+ +
+ +
+ +
+ +
build_flags =
-O2
-Wall
- -Isrc/
+ -Isrc
-Isrc/n64
- -Isrc/printf
- -Isrc/tinyalloc
+ -Isrc/tft
+ -Isrc/lib
+ -Isrc/lib/printf
+ -Isrc/lib/tinyalloc
+ -Isrc/lib/tinyusb/src
+ ;DEBUG OUTPUT CONFIG
+ -DDEBUG_STATUS=1 ;General information
+ -DDEBUG_N64=0 ;For debugging N64 low level info
+ -DDEBUG_TPAK=0 ;For debugging N64 TPAK low level info. It's complex so has its own flag
+ -DDEBUG_USBHOST=0 ;For debugging the USB Host Stack (1,2 or 3. Higher = more output)
+ -DDEBUG_MEMORY=0 ;For debugging the memory allocator in external RAM.
+ -DDEBUG_FATFS=0 ;For debugging the FATFS io
+ -DDEBUG_ERROR=1 ;For showing critical errors
+
+ -DCFG_TUSB_DEBUG_PRINTF="tusb_printf_hook"
+ -DCFG_TUSB_DEBUG=DEBUG_USBHOST
; Printf Configuration
-DPRINTF_DISABLE_SUPPORT_FLOAT
@@ -49,23 +70,103 @@ build_flags =
platform = teensy@~4.13.1
board = teensy41
framework = arduino
-monitor_port = COM25
-monitor_speed = 256000
-; Disable the inbuilt framework lib so I can use my own fork
-lib_ignore = USBHost_t36
+src_filter =
+ ${common_env_data.src_filter}
+ +
+ +
+ +
+ +
+ ;TinyUSB (T4 specific)
+ +
+ +
+ +
+
+build_flags =
+ ${common_env_data.build_flags}
+ -Isrc/port_teensy41/
+ -Isrc/port_teensy41/ILI9341_t3n/src
+ ;TinyUSB (T4 specific)
+ -Isrc/lib/tinyusb/hw/mcu/nxp/mcux-sdk/CMSIS/Include
+ -Isrc/lib/tinyusb/hw/mcu/nxp/mcux-sdk/devices/MIMXRT1062
+ -Isrc/lib/tinyusb/hw/mcu/nxp/mcux-sdk/devices/MIMXRT1062/drivers
+ -Isrc/lib/tinyusb/hw/mcu/nxp/mcux-sdk/drivers/common
+ -DCPU_MIMXRT1062DVL6A
+ -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX
+ -DMCU_VARIANT=MIMXRT1062
+
+[env:disco_f750n8]
+platform = ststm32
+board = disco_f750n8_extflash
+framework = stm32cube
+; This board has hardly any internal flash. My code is booted from the QSPI external flash.
+; This custom linker will copy all code to RAM after boot for noticably better performance.
+; I also created code/data areas for flash when I want functions/data to remain on flash to save RAM.
+board_build.ldscript = src/port_stm32f7/stm37f750-dk/STM32F750N8HX_EXTFLASH.ld
src_filter =
${common_env_data.src_filter}
- +
- +
- +
- +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
build_flags =
${common_env_data.build_flags}
- -Isrc/USBHost_t36
- -Isrc/ILI9341_t3n/src
- -Isrc/tft
- ; -DUSBHOST_PRINT_DEBUG
- ; -DDEBUG_JOYSTICK
+ -Isrc/port_stm32f7/stm37f750-dk
+ -Isrc/port_stm32f7/common/fatfs
+ -Isrc/port_stm32f7/common/fatfs/drivers
+ -Isrc/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery
+ -DCFG_TUSB_MCU=OPT_MCU_STM32F7
+ -DAPPLICATION_ADDRESS=0x90000000U ;My entry point is in QSPI Flash for this board
+ -DUSE_HAL_DRIVER
+ -DSTM32F750xx
+ -DUSB_USB_FS
+
+[env:disco_f769ni]
+platform = ststm32
+board = disco_f769ni
+framework = stm32cube
+extra_scripts = post:hex_from_elf.py
+board_build.ldscript = src/port_stm32f7/stm37f769-dk/STM32F769NIHX_FLASH.ld
+
+src_filter =
+ ${common_env_data.src_filter}
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+build_flags =
+ ${common_env_data.build_flags}
+ -Isrc/port_stm32f7/stm37f769-dk
+ -Isrc/port_stm32f7/common/fatfs
+ -Isrc/port_stm32f7/common/fatfs/drivers
+ -Isrc/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery
+ -DCFG_TUSB_MCU=OPT_MCU_STM32F7
+ -DAPPLICATION_ADDRESS=0x8000000U ;Entry point is internal FLASH.
+ -DUSE_HAL_DRIVER
+ -DSTM32F769xx
+ -DUSB_USB_HS
+
+[env:template]
+platform = native
+
+src_filter =
+ ${common_env_data.src_filter}
+ +
+ +
+ +
+
+build_flags =
+ ${common_env_data.build_flags}
+ -Isrc/port_template/
+ -DCFG_TUSB_MCU=OPT_MCU_NONE
+ -lpthread
diff --git a/src/ILI9341_t3n b/src/ILI9341_t3n
deleted file mode 160000
index bb307299..00000000
--- a/src/ILI9341_t3n
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit bb30729973d1d9f14648fb20543a777ee9b91f20
diff --git a/src/USBHost_t36 b/src/USBHost_t36
deleted file mode 160000
index 637c4cbe..00000000
--- a/src/USBHost_t36
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 637c4cbe7266795dea6490a4de0f38d8ec289643
diff --git a/src/analog_stick.cpp b/src/analog_stick.cpp
index 1cbef81b..e471ebf1 100644
--- a/src/analog_stick.cpp
+++ b/src/analog_stick.cpp
@@ -1,9 +1,7 @@
// Copyright 2020, Ryan Wendland, usb64
// SPDX-License-Identifier: MIT
-#include
-#include "usb64_conf.h"
-#include "printf.h"
+#include "common.h"
void astick_apply_deadzone(float *out_x, float *out_y, float x, float y, float dz_low, float dz_high) {
float magnitude = sqrtf(powf(x,2) + powf(y,2));
diff --git a/src/analog_stick.h b/src/analog_stick.h
index bd578c75..08192b1d 100644
--- a/src/analog_stick.h
+++ b/src/analog_stick.h
@@ -4,7 +4,7 @@
#ifndef _ANALOG_STICK_H
#define _ANALOG_STICK_H
-#include
+#include "common.h"
void astick_apply_deadzone(float *out_x, float *out_y, float x, float y, float dz_low, float dz_high);
float astick_apply_sensitivity(int sensitivity, float *x, float *y);
diff --git a/src/common.h b/src/common.h
new file mode 100644
index 00000000..a62ac93b
--- /dev/null
+++ b/src/common.h
@@ -0,0 +1,107 @@
+// Copyright 2020, Ryan Wendland, usb64
+// SPDX-License-Identifier: MIT
+
+#ifndef N64_N64_WRAPPER_H_
+#define N64_N64_WRAPPER_H_
+
+#ifdef ARDUINO
+#include
+#endif
+#include
+#include
+#include
+#include
+#include
+#include "printf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define N64_OUTPUT 1
+#define N64_INPUT 2
+#define N64_INPUT_PULLUP 2
+#define N64_INPUT_PULLDOWN 3
+
+#define N64_INTMODE_FALLING 1
+#define N64_INTMODE_CHANGE 2
+#define N64_INTMODE_RISING 3
+
+/* DEBUG PRINTERS - See platformio.ini to enable */
+#define debug_print_status(fmt, ...) do { if (DEBUG_STATUS) usb64_printf(fmt, ##__VA_ARGS__); } while (0)
+#define debug_print_n64(fmt, ...) do { if (DEBUG_N64) usb64_printf(fmt, ##__VA_ARGS__); } while (0)
+#define debug_print_tpak(fmt, ...) do { if (DEBUG_TPAK) usb64_printf(fmt, ##__VA_ARGS__); } while (0)
+#define debug_print_usbhost(fmt, ...) do { if (DEBUG_USBHOST) usb64_printf(fmt, ##__VA_ARGS__); } while (0)
+#define debug_print_fatfs(fmt, ...) do { if (DEBUG_FATFS) usb64_printf(fmt, ##__VA_ARGS__); } while (0)
+#define debug_print_memory(fmt, ...) do { if (DEBUG_MEMORY) usb64_printf(fmt, ##__VA_ARGS__); } while (0)
+#define debug_print_error(fmt, ...) do { if (DEBUG_ERROR) usb64_printf(fmt, ##__VA_ARGS__); } while (0)
+
+/* N64 LIB */
+#define MAX_CONTROLLERS 4 //Max is 4
+#define MAX_MICE 4 //0 to disable N64 mouse support. Must be <= MAX_CONTROLLERS
+#define MAX_KB 4 //0 to disable N64 randnet keyboard support. Must be <= MAX_CONTROLLERS
+#define MAX_GBROMS 10 //ROMS over this will just get ignored
+#define ENABLE_I2C_CONTROLLERS 0 //Received button presses over I2C, useful for integrating with a rasp pi etc.
+#define ENABLE_HARDWIRED_CONTROLLER 1 //Ability to hardware a N64 controller into the usb64.
+#define PERI_CHANGE_TIME 750 //Milliseconds to simulate a peripheral changing time. Needed for some games.
+
+/* FILESYSTEM */
+#define MAX_FILENAME_LEN 256
+#define SETTINGS_FILENAME "SETTINGS.DAT"
+#define GAMEBOY_SAVE_EXT ".SAV" //ROMFILENAME.SAV
+#define CPAK_SAVE_EXT ".MPK" //CONTROLLER_PAK_XX.MPK
+
+/* FIRMWARE DEFAULTS (CONFIGURABLE DURING USE) */
+#define DEFAULT_SENSITIVITY 2 //0 to 4 (0 = low sensitivity, 4 = max)
+#define DEFAULT_DEADZONE 2 //0 to 4 (0 = no deadzone correction, 4 = max (40%))
+#define DEFAULT_SNAP 1 //0 or 1 (0 = will output raw analog stick angle, 1 will snap to 45deg angles)
+#define DEFAULT_OCTA_CORRECT 1 //0 or 1 (Will correct the circular analog stuck shape to N64 octagonal)
+
+/* FIRMWARE DEFAULTS (NOT CONFIGURABLE DURING USE) */
+#define SNAP_RANGE 5 //+/- what angle range will snap. 5 will snap to 45 degree if between 40 and 50 degrees.
+#define MOUSE_SENSITIVITY 2.0f //Just what felt right to me with my mouse.
+#define MAG_AT_45DEG 1.1f //Octagonal shape has a larger magnitude at the 45degree points. 1.1 times larger seems about right
+
+#include "port_conf.h"
+
+//System wrappers
+void n64hal_system_init();
+void n64hal_debug_init();
+void n64hal_debug_write(char c);
+void n64hal_attach_interrupt(usb64_pin_t pin, void (*handler)(void), int mode);
+void n64hal_detach_interrupt(usb64_pin_t pin);
+void n64hal_disable_interrupts();
+void n64hal_enable_interrupts();
+
+//RTC wrapper prototypes (For gameboy roms with RTC, i.e Pokemon games)
+void n64hal_rtc_read(uint8_t *day_high, uint8_t *day_low, uint8_t *h, uint8_t *m, uint8_t *s);
+void n64hal_rtc_write(uint8_t *day_high, uint8_t *day_low, uint8_t *h, uint8_t *m, uint8_t *s);
+
+//Timer wrappers
+uint32_t n64hal_hs_tick_get_speed();
+void n64hal_hs_tick_init();
+uint32_t n64hal_hs_tick_get();
+uint32_t n64hal_millis();
+
+//RAM access wrappers
+void n64hal_read_extram(void *rx_buff, void *src, uint32_t offset, uint32_t len);
+void n64hal_write_extram(void *tx_buff, void *dst, uint32_t offset, uint32_t len);
+
+//GPIO wrappers
+void n64hal_gpio_init();
+void n64hal_output_set(usb64_pin_t pin, uint8_t level);
+void n64hal_input_swap(usb64_pin_t pin, uint8_t val);
+uint8_t n64hal_input_read(usb64_pin_t pin);
+
+//FileIO wrappers
+uint32_t n64hal_list_gb_roms(char **list, uint32_t max);
+void n64hal_read_storage(char *name, uint32_t file_offset, uint8_t *data, uint32_t len);
+
+//Memory wrappers
+void *n64hal_malloc(uint32_t len);
+void n64hal_free(void *addr);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* N64_N64_WRAPPER_H_ */
diff --git a/src/fileio.cpp b/src/fileio.cpp
index 19e0ac9f..55bd0a8a 100644
--- a/src/fileio.cpp
+++ b/src/fileio.cpp
@@ -1,20 +1,22 @@
// Copyright 2020, Ryan Wendland, usb64
// SPDX-License-Identifier: MIT
-#include
-#include
-#include "usb64_conf.h"
-#include "printf.h"
+#include "common.h"
+#include "fileio.h"
+#include "memory.h"
-void fileio_init()
+static bool fileio_ok = false;
+
+FLASHMEM void fileio_init()
{
- if (!SD.sdfs.begin(SdioConfig(FIFO_SDIO)))
+ if (!fileio_dev_init())
{
debug_print_error("[FILEIO] ERROR: Could not open SD Card\n");
}
else
{
- debug_print_fatfs("[FILEIO] Opened SD card OK! Size: %lld MB\n", SD.totalSize()/1024/1024);
+ debug_print_fatfs("[FILEIO] Opened SD card OK!\n");
+ fileio_ok = true;
}
}
@@ -31,30 +33,31 @@ void fileio_init()
uint32_t fileio_list_directory(char **list, uint32_t max)
{
int file_count = 0;
- File root = SD.open("/");
+ int root = fileio_dev_open_dir("/");
- if (root == false)
+ if (root == 0)
{
debug_print_error("[FILEIO] ERROR: Could not read SD Card\n");
return 0;
}
+ debug_print_fatfs("[FILEIO] fileio_list_directory %08x!\n", root);
+
while (true)
{
- File entry = root.openNextFile();
- if (entry == false)
- break;
+ const char* filename = fileio_dev_get_next_filename(root);
- if (!entry.isDirectory())
+ if (filename == NULL)
{
- debug_print_fatfs("Found file: %s\n", entry.name());
- list[file_count] = (char *)malloc(strlen(entry.name()) + 1);
- strcpy(list[file_count], entry.name());
- file_count++;
+ break;
}
- entry.close();
+
+ debug_print_fatfs("Found file: %s\n", filename);
+ list[file_count] = (char *)memory_dev_malloc(strlen(filename) + 1);
+ strcpy(list[file_count], filename);
+ file_count++;
}
- root.close();
+ fileio_dev_close_dir(root);
return file_count;
}
@@ -69,13 +72,12 @@ uint32_t fileio_list_directory(char **list, uint32_t max)
*/
void fileio_write_to_file(char *filename, uint8_t *data, uint32_t len)
{
- FsFile fil = SD.sdfs.open(filename, O_WRITE | O_CREAT);
- if (fil == false)
+ int ret = fileio_dev_write(filename, data, len);
+ if (ret == -1)
{
debug_print_error("[FILEIO] ERROR: Could not open %s for WRITE\n", filename);
- return;
}
- if (fil.write(data, len) != len)
+ else if (ret == -2)
{
debug_print_error("[FILEIO] ERROR: Could not write %s\n", filename);
}
@@ -83,7 +85,6 @@ void fileio_write_to_file(char *filename, uint8_t *data, uint32_t len)
{
debug_print_status("[FILEIO] Writing %s for %u bytes ok!\n", filename, len);
}
- fil.close();
}
/*
@@ -99,16 +100,13 @@ void fileio_write_to_file(char *filename, uint8_t *data, uint32_t len)
*/
void fileio_read_from_file(char *filename, uint32_t file_offset, uint8_t *data, uint32_t len)
{
- FsFile fil = SD.sdfs.open(filename, O_READ);
- if (fil == false)
+ int ret = fileio_dev_read(filename, file_offset, data, len);
+
+ if (ret == -1)
{
debug_print_error("[FILEIO] ERROR: Could not open %s for READ\n", filename);
- return;
}
-
- fil.seekSet(file_offset);
-
- if (fil.read(data, len) != (int)len)
+ else if (ret == -2)
{
debug_print_error("[FILEIO] ERROR: Could not read %s\n", filename);
}
@@ -116,5 +114,9 @@ void fileio_read_from_file(char *filename, uint32_t file_offset, uint8_t *data,
{
debug_print_status("[FILEIO] Reading %s for %u bytes ok!\n", filename, len);
}
- fil.close();
}
+
+bool fileio_detected()
+{
+ return fileio_ok;
+}
\ No newline at end of file
diff --git a/src/fileio.h b/src/fileio.h
index 1dedebf8..9be02366 100644
--- a/src/fileio.h
+++ b/src/fileio.h
@@ -4,16 +4,21 @@
#ifndef _FILEIO_H
#define _FILEIO_H
-#include
-#include "usb64_conf.h"
+#include "common.h"
+//File access API
void fileio_init(void);
void fileio_write_to_file(char *filename, uint8_t *data, uint32_t len);
void fileio_read_from_file(char *filename, uint32_t file_offset, uint8_t *data, uint32_t len);
uint32_t fileio_list_directory(char **list, uint32_t max);
+bool fileio_detected();
-int fileio_open_file_readonly(const char *filename);
-void fileio_close_file();
-int fileio_get_line(char* buffer, int max_len);
+//Device specific API. Implement for porting.
+bool fileio_dev_init();
+int fileio_dev_open_dir(const char* dir);
+void fileio_dev_close_dir(int handle);
+const char* fileio_dev_get_next_filename(int handle);
+int fileio_dev_read(char *filename, uint32_t file_offset, uint8_t *data, uint32_t len);
+int fileio_dev_write(char *filename, uint8_t *data, uint32_t len);
#endif
diff --git a/src/input.cpp b/src/input.cpp
index 57e1d626..a601654d 100644
--- a/src/input.cpp
+++ b/src/input.cpp
@@ -1,255 +1,193 @@
// Copyright 2020, Ryan Wendland, usb64
// SPDX-License-Identifier: MIT
-#include
-#include "USBHost_t36.h"
-#include "usb64_conf.h"
+#include "common.h"
#include "n64_controller.h"
#include "input.h"
-#include "printf.h"
#include "tft.h"
+#include "tusb.h"
-//USB Host Interface
-USBHost usbh;
-
-#if (ENABLE_USB_HUB == 1)
-USBHub hub1(usbh);
-USBHub hub2(usbh);
-USBHub hub3(usbh);
-USBHub hub4(usbh);
-#endif
-
-JoystickController joy1(usbh);
-JoystickController joy2(usbh);
-JoystickController joy3(usbh);
-JoystickController joy4(usbh);
-JoystickController joy5(usbh);
-JoystickController joy6(usbh);
-JoystickController joy7(usbh);
-JoystickController joy8(usbh);
-
-USBHIDParser hid1(usbh);
-USBHIDParser hid2(usbh);
-USBHIDParser hid3(usbh);
-USBHIDParser hid4(usbh);
-MouseController mouse1(usbh);
-MouseController mouse2(usbh);
-MouseController mouse3(usbh);
-MouseController mouse4(usbh);
-KeyboardController kb1(usbh);
-KeyboardController kb2(usbh);
-KeyboardController kb3(usbh);
-KeyboardController kb4(usbh);
-
-JoystickController *gamecontroller[] = {&joy1, &joy2, &joy3, &joy4, &joy5, &joy6, &joy7, &joy8};
-MouseController *mousecontroller[] = {&mouse1, &mouse2, &mouse3, &mouse4};
-KeyboardController *kbcontroller[] = {&kb1, &kb2, &kb3, &kb4};
+#define MAX_USB_CONTROLLERS (CFG_TUH_DEVICE_MAX)
+
+input_driver_t input_devices[MAX_USB_CONTROLLERS];
uint32_t hardwired1;
-#define MAX_USB_CONTROLLERS (8)
-static input input_devices[MAX_CONTROLLERS];
-static uint8_t kb_keys_pressed[RANDNET_MAX_BUTTONS];
+static uint8_t kb_modifier_to_key(uint8_t modifier)
+{
+ if (modifier & KEYBOARD_MODIFIER_LEFTCTRL)
+ return HID_KEY_CONTROL_LEFT;
+ if (modifier & KEYBOARD_MODIFIER_LEFTSHIFT)
+ return HID_KEY_SHIFT_LEFT;
+ if (modifier & KEYBOARD_MODIFIER_LEFTALT)
+ return HID_KEY_ALT_LEFT;
+ if (modifier & KEYBOARD_MODIFIER_LEFTGUI)
+ return HID_KEY_GUI_LEFT;
+ if (modifier & KEYBOARD_MODIFIER_RIGHTCTRL)
+ return HID_KEY_CONTROL_RIGHT;
+ if (modifier & KEYBOARD_MODIFIER_RIGHTSHIFT)
+ return HID_KEY_SHIFT_RIGHT;
+ if (modifier & KEYBOARD_MODIFIER_RIGHTALT)
+ return HID_KEY_ALT_RIGHT;
+ if (modifier & KEYBOARD_MODIFIER_RIGHTGUI)
+ return HID_KEY_GUI_RIGHT;
+ return 0;
+}
-static void kb_pressed_cb(uint8_t keycode)
+static input_driver_t *find_slot(uint16_t uid)
{
- //Check if its already pressed
- for (int i = 0; i < RANDNET_MAX_BUTTONS; i++)
+ //See if input device already exists
+ for (int i = 0; i < MAX_USB_CONTROLLERS; i++)
{
- if (kb_keys_pressed[i] == keycode)
+ if (input_devices[i].uid == uid && uid > 0)
{
- return;
+ return &input_devices[i];
}
}
- //Register the keypress
- for (int i = 0; i < RANDNET_MAX_BUTTONS; i++)
+ //Allocate new input device
+ for (int i = 0; i < MAX_USB_CONTROLLERS; i++)
{
- if (kb_keys_pressed[i] == 0)
+ if (input_devices[i].type == INPUT_NONE && uid == 0)
{
- kb_keys_pressed[i] = keycode;
- break;
+ input_devices[i].slot = i;
+ return &input_devices[i];
}
}
+ return NULL;
}
-static void kb_released_cb(uint8_t keycode)
+void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *desc_report, uint16_t desc_len)
{
- for (int i = 0; i < RANDNET_MAX_BUTTONS; i++)
+ uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
+
+ if (itf_protocol != HID_ITF_PROTOCOL_NONE)
{
- if (kb_keys_pressed[i] == keycode)
- {
- kb_keys_pressed[i] = 0;
- }
+ input_driver_t *in_dev = find_slot(0);
+
+ in_dev->type = (itf_protocol == HID_ITF_PROTOCOL_MOUSE) ? INPUT_MOUSE : INPUT_KEYBOARD;
+ in_dev->backend = (itf_protocol == HID_ITF_PROTOCOL_MOUSE) ? BACKEND_HID_MOUSE : BACKEND_HID_KEYBOARD;
+ in_dev->uid = dev_addr << 8 | instance;
+ in_dev->set_rumble = NULL;
+ in_dev->set_led = NULL;
+ in_dev->data = in_dev->_data;
+
+ tuh_hid_receive_report(dev_addr, instance);
}
}
-static int _check_id(uint8_t id)
+// Invoked when received report from device via interrupt endpoint
+static uint32_t hid_data_tick[MAX_USB_CONTROLLERS] = {0};
+void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len)
{
- if (id > MAX_CONTROLLERS)
- return 0;
- if (input_devices[id].driver == NULL)
- return 0;
+ uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
+ input_driver_t *in_dev = find_slot(dev_addr << 8 | instance);
- return 1;
+ if (in_dev != NULL && itf_protocol != HID_ITF_PROTOCOL_NONE)
+ {
+ hid_data_tick[in_dev->slot] = n64hal_millis();
+ memcpy(in_dev->data, report, TU_MIN(len, CFG_TUH_XINPUT_EPIN_BUFSIZE));
+ }
+
+ tuh_hid_receive_report(dev_addr, instance);
}
-void input_init()
+void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance)
{
- usbh.begin();
- for (int i = 0; i < MAX_CONTROLLERS; i++)
+ uint16_t uid = dev_addr << 8 | instance;
+ input_driver_t *in_dev = find_slot(uid);
+ while (in_dev != NULL)
{
- input_devices[i].driver = NULL;
- input_devices[i].type = USB_GAMECONTROLLER;
+ memset(in_dev, 0, sizeof(input_driver_t));
+ in_dev = find_slot(uid);
}
}
-void input_update_input_devices()
+void tuh_xinput_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len)
{
- //Clear disconnected devices
- for (int i = 0; i < MAX_CONTROLLERS; i++)
+ xinputh_interface_t *xid_itf = (xinputh_interface_t *)report;
+ uint16_t uid = dev_addr << 8 | instance;
+ input_driver_t *in_dev = find_slot(uid);
+ if (in_dev != NULL && xid_itf->new_pad_data == true)
{
- if (input_is_connected(i) == 0)
- {
- if (input_devices[i].driver != NULL)
- {
- debug_print_status("[INPUT] Cleared device from slot %u\n", i);
- tft_flag_update();
- }
- input_devices[i].driver = NULL;
- }
+ memcpy(in_dev->data, &xid_itf->pad, TU_MIN(len, CFG_TUH_XINPUT_EPIN_BUFSIZE));
}
-
-#if (ENABLE_HARDWIRED_CONTROLLER >=1)
- //Find hardwired game controller
- if (digitalRead(HW_EN) == 0)
+ else if (in_dev == NULL && xid_itf->type == XBOX360_WIRELESS)
{
- //Hardwired will always overwrite the first slot
- if (input_devices[0].driver != &hardwired1)
+ if (xid_itf->connected == true)
{
- input_devices[0].driver = &hardwired1;
- input_devices[0].type = HW_GAMECONTROLLER;
- debug_print_status("[INPUT] Registered hardwired gamecontroller to slot %u\n", 0);
- tft_flag_update();
+ tuh_xinput_mount_cb(dev_addr, instance, xid_itf);
}
}
-#endif
-
- //Find new game controllers
- for (uint32_t i = 0; i < MAX_USB_CONTROLLERS; i++)
+ else if (in_dev != NULL && xid_itf->type == XBOX360_WIRELESS)
{
- //Game controller is connected
- if (*(gamecontroller[i]) == true)
+ if (xid_itf->connected == false)
{
- //Is it already a registered input device
- bool already_registered = false;
- for (int j = 0; j < MAX_CONTROLLERS; j++)
- {
- if (gamecontroller[i] == input_devices[j].driver)
- {
- already_registered = true;
- break;
- }
- }
- //Its a new controller, find empty slot and register it now
- if (already_registered == false)
- {
- for (int j = 0; j < MAX_CONTROLLERS; j++)
- {
- if (input_devices[j].driver == NULL)
- {
- input_devices[j].driver = gamecontroller[i];
- input_devices[j].type = USB_GAMECONTROLLER;
- debug_print_status("[INPUT] Registered gamecontroller to slot %u\n", j);
- gamecontroller[i]->setLEDs(j + 2);
- tft_flag_update();
- break;
- }
- }
- }
+ tuh_xinput_umount_cb(dev_addr, instance);
}
}
-#if (MAX_MICE >= 1)
- //Find new mice
- for (int i = 0; i < MAX_MICE; i++)
+ tuh_xinput_receive_report(dev_addr, instance);
+}
+
+void tuh_xinput_mount_cb(uint8_t dev_addr, uint8_t instance, const xinputh_interface_t *xinput_itf)
+{
+ //If this is a Xbox 360 Wireless controller, dont register yet. Need to wait for a connection packet
+ //on the in pipe.
+ if (xinput_itf->type == XBOX360_WIRELESS && xinput_itf->connected == false)
{
- //Mouse is connected
- USBHIDInput *m = (USBHIDInput *)mousecontroller[i];
- if (*m == true)
- {
- //Is it already a registered input device
- bool already_registered = false;
- for (int j = 0; j < MAX_CONTROLLERS; j++)
- {
- if (mousecontroller[i] == input_devices[j].driver)
- {
- already_registered = true;
- break;
- }
- }
- //Its a new mouse, find empty slot and register it now
- if (already_registered == false)
- {
- for (int j = 0; j < MAX_CONTROLLERS; j++)
- {
- if (input_devices[j].driver == NULL)
- {
- input_devices[j].driver = mousecontroller[i];
- input_devices[j].type = USB_MOUSE;
- debug_print_status("[INPUT] Register mouse to slot %u\n", j);
- tft_flag_update();
- break;
- }
- }
- }
- }
+ tuh_xinput_receive_report(dev_addr, instance);
+ return;
}
-#endif
-#if (MAX_KB >= 1)
- //Find new keyboard
- for (int i = 0; i < MAX_KB; i++)
+
+ input_driver_t *in_dev = find_slot(0);
+
+ in_dev->type = INPUT_GAMECONTROLLER;
+ in_dev->backend = BACKEND_XINPUT;
+ in_dev->uid = dev_addr << 8 | instance;
+ in_dev->set_rumble = tuh_xinput_set_rumble;
+ in_dev->set_led = tuh_xinput_set_led;
+ in_dev->data = in_dev->_data;
+
+ tuh_xinput_set_led(dev_addr, instance, 0, true);
+ tuh_xinput_set_led(dev_addr, instance, in_dev->slot + 1, true);
+ tuh_xinput_set_rumble(dev_addr, instance, 0, 0, true);
+ tuh_xinput_receive_report(dev_addr, instance);
+}
+
+void tuh_xinput_umount_cb(uint8_t dev_addr, uint8_t instance)
+{
+ uint16_t uid = dev_addr << 8 | instance;
+ input_driver_t *in_dev = find_slot(uid);
+ while (in_dev != NULL)
{
- //Keyboard is connected
- USBHIDInput *kb = (USBHIDInput *)kbcontroller[i];
- if (*kb == true)
- {
- //Is it already a registered input device
- bool already_registered = false;
- for (int j = 0; j < MAX_CONTROLLERS; j++)
- {
- if (kbcontroller[i] == input_devices[j].driver)
- {
- already_registered = true;
- break;
- }
- }
- //Its a new keyboard, find empty slot and register it now
- if (already_registered == false)
- {
- for (int j = 0; j < MAX_CONTROLLERS; j++)
- {
- if (input_devices[j].driver == NULL)
- {
- input_devices[j].driver = kbcontroller[i];
- input_devices[j].type = USB_KB;
- debug_print_status("[INPUT] Register keyboard to slot %u\n", j);
- tft_flag_update();
- kbcontroller[i]->attachRawPress(kb_pressed_cb);
- kbcontroller[i]->attachRawRelease(kb_released_cb);
- break;
- }
- }
- }
- }
+ memset(in_dev, 0, sizeof(input_driver_t));
+ in_dev = find_slot(uid);
}
-#endif
}
-uint16_t input_get_state(uint8_t id, void *response, bool *combo_pressed)
+static int _check_id(uint8_t id)
{
- uint32_t _buttons = 0;
- int32_t _axis[JoystickController::STANDARD_AXIS_COUNT] = {0};
- int32_t right_axis[2] = {0};
+ if (id >= MAX_USB_CONTROLLERS)
+ return 0;
+
+ if (input_devices[id].backend == BACKEND_NONE)
+ return 0;
+ return 1;
+}
+
+FLASHMEM void input_init()
+{
+ tusb_init();
+ memset(input_devices, 0x00, sizeof(input_devices));
+}
+
+void input_update_input_devices()
+{
+ tuh_task();
+}
+
+uint16_t input_get_state(uint8_t id, void *response, bool *combo_pressed)
+{
*combo_pressed = 0;
if (_check_id(id) == 0)
@@ -258,199 +196,62 @@ uint16_t input_get_state(uint8_t id, void *response, bool *combo_pressed)
if (response == NULL)
return 0;
- if (input_is_gamecontroller(id))
+ input_driver_t *in_dev = &input_devices[id];
+
+ if (in_dev == NULL)
+ return 0;
+
+ if (input_is(id, INPUT_GAMECONTROLLER))
{
//Prep N64 response
n64_buttonmap *state = (n64_buttonmap *)response;
state->dButtons = 0;
- //Get latest info from USB devices
- JoystickController *joy = (JoystickController *)input_devices[id].driver;
- _buttons = joy->getButtons();
-
- for (uint8_t i = 0; i < JoystickController::STANDARD_AXIS_COUNT; i++)
+ int32_t right_axis[2] = {0};
+ if (in_dev->backend == BACKEND_XINPUT)
{
- _axis[i] = joy->getAxis(i);
- }
- joy->joystickDataClear();
+ xinput_gamepad_t *pad = (xinput_gamepad_t *)in_dev->data;
+ if (pad->wButtons & XINPUT_GAMEPAD_DPAD_UP) state->dButtons |= N64_DU; //DUP
+ if (pad->wButtons & XINPUT_GAMEPAD_DPAD_DOWN) state->dButtons |= N64_DD; //DDOWN
+ if (pad->wButtons & XINPUT_GAMEPAD_DPAD_LEFT) state->dButtons |= N64_DL; //DLEFT
+ if (pad->wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) state->dButtons |= N64_DR; //DRIGHT
+ if (pad->wButtons & XINPUT_GAMEPAD_START) state->dButtons |= N64_ST; //START
+ if (pad->wButtons & XINPUT_GAMEPAD_BACK) state->dButtons |= 0; //BACK
+ if (pad->wButtons & XINPUT_GAMEPAD_LEFT_THUMB) state->dButtons |= 0; //LS
+ if (pad->wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) state->dButtons |= 0; //RS
+ if (pad->wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) state->dButtons |= N64_LB; //LB
+ if (pad->wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) state->dButtons |= N64_RB; //RB
+ if (pad->wButtons & (1 << 10)) state->dButtons |= 0; //XBOX BUTTON
+ if (pad->wButtons & (1 << 11)) state->dButtons |= 0; //XBOX SYNC
+ if (pad->wButtons & XINPUT_GAMEPAD_A) state->dButtons |= N64_A; //A
+ if (pad->wButtons & XINPUT_GAMEPAD_B) state->dButtons |= N64_B; //B
+ if (pad->wButtons & XINPUT_GAMEPAD_X) state->dButtons |= N64_B; //X
+ if (pad->wButtons & XINPUT_GAMEPAD_Y) state->dButtons |= 0; //Y
+ if (pad->wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) state->dButtons |= N64_CU | //RS triggers
+ N64_CD | //all C usb_buttons
+ N64_CL |
+ N64_CR;
- switch (joy->joystickType())
- {
- case JoystickController::XBOX360:
- case JoystickController::XBOX360_WIRED:
- //Digital usb_buttons
- //FIXME Modifier to make A,B,X,Y be C buttons
- if (_buttons & (1 << 0)) state->dButtons |= N64_DU; //DUP
- if (_buttons & (1 << 1)) state->dButtons |= N64_DD; //DDOWN
- if (_buttons & (1 << 2)) state->dButtons |= N64_DL; //DLEFT
- if (_buttons & (1 << 3)) state->dButtons |= N64_DR; //DRIGHT
- if (_buttons & (1 << 4)) state->dButtons |= N64_ST; //START
- if (_buttons & (1 << 5)) state->dButtons |= 0; //BACK
- if (_buttons & (1 << 6)) state->dButtons |= 0; //LS
- if (_buttons & (1 << 7)) state->dButtons |= 0; //RS
- if (_buttons & (1 << 8)) state->dButtons |= N64_LB; //LB
- if (_buttons & (1 << 9)) state->dButtons |= N64_RB; //RB
- if (_buttons & (1 << 10)) state->dButtons |= 0; //XBOX BUTTON
- if (_buttons & (1 << 11)) state->dButtons |= 0; //XBOX SYNC
- if (_buttons & (1 << 12)) state->dButtons |= N64_A; //A
- if (_buttons & (1 << 13)) state->dButtons |= N64_B; //B
- if (_buttons & (1 << 14)) state->dButtons |= N64_B; //X
- if (_buttons & (1 << 15)) state->dButtons |= 0; //Y
- if (_buttons & (1 << 7)) state->dButtons |= N64_CU | //RS triggers
- N64_CD | //all C usb_buttons
- N64_CL |
- N64_CR;
//Analog stick (Normalise 0 to +/-100)
- state->x_axis = _axis[0] * 100 / 32768;
- state->y_axis = _axis[1] * 100 / 32768;
+ state->x_axis = pad->sThumbLX * 100 / 32768;
+ state->y_axis = pad->sThumbLY * 100 / 32768;
//Z button
- if (_axis[4] > 10) state->dButtons |= N64_Z; //LT
- if (_axis[5] > 10) state->dButtons |= N64_Z; //RT
+ if (pad->bLeftTrigger > 10) state->dButtons |= N64_Z; //LT
+ if (pad->bRightTrigger > 10) state->dButtons |= N64_Z; //RT
//C usb_buttons
- if (_axis[2] > 16000) state->dButtons |= N64_CR;
- if (_axis[2] < -16000) state->dButtons |= N64_CL;
- if (_axis[3] > 16000) state->dButtons |= N64_CU;
- if (_axis[3] < -16000) state->dButtons |= N64_CD;
+ if (pad->sThumbRX > 16000) state->dButtons |= N64_CR;
+ if (pad->sThumbRX < -16000) state->dButtons |= N64_CL;
+ if (pad->sThumbRY > 16000) state->dButtons |= N64_CU;
+ if (pad->sThumbRY < -16000) state->dButtons |= N64_CD;
//Button to hold for 'combos'
- if (combo_pressed)
- *combo_pressed = (_buttons & (1 << 5)); //back
+ *combo_pressed = (pad->wButtons & XINPUT_GAMEPAD_BACK); //back
//Map right axis for dual stick mode
- right_axis[0] = _axis[2] * 100 / 32768;
- right_axis[1] = _axis[3] * 100 / 32768;
-
- break;
- case JoystickController::XBOXONE:
- if (_buttons & (1 << 8)) state->dButtons |= N64_DU; //DUP
- if (_buttons & (1 << 9)) state->dButtons |= N64_DD; //DDOWN
- if (_buttons & (1 << 10)) state->dButtons |= N64_DL; //DLEFT
- if (_buttons & (1 << 11)) state->dButtons |= N64_DR; //DRIGHT
- if (_buttons & (1 << 2)) state->dButtons |= N64_ST; //START
- if (_buttons & (1 << 3)) state->dButtons |= 0; //BACK
- if (_buttons & (1 << 14)) state->dButtons |= 0; //LS
- if (_buttons & (1 << 15)) state->dButtons |= 0; //RS
- if (_buttons & (1 << 12)) state->dButtons |= N64_LB; //LB
- if (_buttons & (1 << 13)) state->dButtons |= N64_RB; //RB
- if (_buttons & (1 << 4)) state->dButtons |= N64_A; //A
- if (_buttons & (1 << 5)) state->dButtons |= N64_B; //B
- if (_buttons & (1 << 6)) state->dButtons |= N64_B; //X
- if (_buttons & (1 << 7)) state->dButtons |= 0; //Y
- if (_buttons & (1 << 15)) state->dButtons |= N64_CU | //RS triggers
- N64_CD | //all C usb_buttons
- N64_CL |
- N64_CR;
- //Analog stick (Normalise 0 to +/-100)
- state->x_axis = _axis[0] * 100 / 32768;
- state->y_axis = _axis[1] * 100 / 32768;
-
- //Z button
- if (_axis[3] > 10) state->dButtons |= N64_Z; //LT
- if (_axis[4] > 10) state->dButtons |= N64_Z; //RT
-
- //C usb_buttons
- if (_axis[2] > 16000) state->dButtons |= N64_CR;
- if (_axis[2] < -16000) state->dButtons |= N64_CL;
- if (_axis[5] > 16000) state->dButtons |= N64_CU;
- if (_axis[5] < -16000) state->dButtons |= N64_CD;
-
- //Button to hold for 'combos'
- if (combo_pressed)
- *combo_pressed = (_buttons & (1 << 3)); //back
-
- right_axis[0] = _axis[2] * 100 / 32768;
- right_axis[1] = _axis[5] * 100 / 32768;
- break;
- case JoystickController::PS4:
- if (_buttons & (1 << 9)) state->dButtons |= N64_ST; //START
- if (_buttons & (1 << 4)) state->dButtons |= N64_LB; //L1
- if (_buttons & (1 << 5)) state->dButtons |= N64_RB; //R1
- if (_buttons & (1 << 6)) state->dButtons |= N64_Z; //L2
- if (_buttons & (1 << 7)) state->dButtons |= N64_Z; //R2
- if (_buttons & (1 << 1)) state->dButtons |= N64_A; //X
- if (_buttons & (1 << 0)) state->dButtons |= N64_B; //SQUARE
- if (_buttons & (1 << 2)) state->dButtons |= N64_B; //CIRCLE
- if (_buttons & (1 << 11)) state->dButtons |= N64_CU | //RS triggers
- N64_CD | //all C usb_buttons
- N64_CL |
- N64_CR;
- //Analog stick (Normalise 0 to +/-100)
- state->x_axis = (_axis[0] - 127) * 100 / 127;
- state->y_axis = -(_axis[1] - 127) * 100 / 127;
-
- //D Pad button
- switch(_axis[9])
- {
- case 0: state->dButtons |= N64_DU; break;
- case 1: state->dButtons |= N64_DU | N64_DR; break;
- case 2: state->dButtons |= N64_DR; break;
- case 3: state->dButtons |= N64_DR | N64_DD; break;
- case 4: state->dButtons |= N64_DD; break;
- case 5: state->dButtons |= N64_DD | N64_DL; break;
- case 6: state->dButtons |= N64_DL; break;
- case 7: state->dButtons |= N64_DL | N64_DU; break;
- }
-
- //C usb_buttons
- if (_axis[2] > 256/2 + 64) state->dButtons |= N64_CR;
- if (_axis[2] < 256/2 - 64) state->dButtons |= N64_CL;
- if (_axis[5] > 256/2 + 64) state->dButtons |= N64_CD;
- if (_axis[5] < 256/2 - 64) state->dButtons |= N64_CU;
-
- //Button to hold for 'combos'
- if (combo_pressed)
- *combo_pressed = (_buttons & (1 << 8)); //back
-
- //Map right axis for dual stick mode
- right_axis[0] = (_axis[2] - 127) * 100 / 127;
- right_axis[1] = -(_axis[5] - 127) * 100 / 127;
- break;
- case JoystickController::UNKNOWN:
- #if (0)
- //Mapper helper
- static uint32_t print_slower = 0;
- if (millis() - print_slower > 100)
- {
- debug_print_status("%04x %04i %04i %04i %04i\n", _buttons, _axis[0], _axis[1], _axis[2], _axis[3]);
- if (_buttons)
- {
- int bit = 0;
- while ((_buttons & (1 << bit++)) == 0);
- debug_print_status("button bit: %i\n", bit-1);
- }
- print_slower = millis();
- }
- #endif
- //Generic HID controllers //FIXME: Load from file?
- //Example of a basic Chinese NES HID Controller. The button mapping nubmers are from a bit of trial and error.
- //You can use the mapper helper above to assist.
- //The controller doesnt have enough buttons, so we're missing alot here.
- //NEXT SNES Controller
- if (joy->idVendor() == 0x0810 && joy->idProduct() == 0xE501)
- {
- if (_buttons & (1 << 9)) state->dButtons |= N64_ST;
- if (_buttons & (1 << 4)) state->dButtons |= N64_Z;
- if (_buttons & (1 << 6)) state->dButtons |= N64_RB;
- if (_buttons & (1 << 2)) state->dButtons |= N64_A;
- if (_buttons & (1 << 1)) state->dButtons |= N64_B;
- if (_buttons & (1 << 3)) state->dButtons |= N64_B;
-
- //Button to hold for 'combos'
- if (combo_pressed)
- *combo_pressed = (_buttons & (1 << 8)); //back
-
- //Analog stick (Normalise 0 to +/-100)
- state->x_axis = (_axis[0] - 127) * 100 / 127;
- state->y_axis = - (_axis[1] - 127) * 100 / 127;
- }
- break;
- //TODO: OTHER USB CONTROLLERS
- case JoystickController::PS3:
- case JoystickController::PS3_MOTION:
- default:
- break;
+ right_axis[0] = pad->sThumbRX * 100 / 32768;
+ right_axis[1] = pad->sThumbRY * 100 / 32768;
}
//Use 2.4 GOODHEAD layout, axis not inverted
@@ -480,327 +281,149 @@ uint16_t input_get_state(uint8_t id, void *response, bool *combo_pressed)
state->dButtons |= N64_RES;
}
}
-#if (MAX_MICE >= 1)
- else if (input_is_mouse(id))
+ else if (input_is(id, INPUT_MOUSE))
{
- //Prep N64 response
+ //N64 report is basically a n64 controller response
n64_buttonmap *state = (n64_buttonmap *)response;
- state->dButtons = 0;
+ hid_mouse_report_t *report = (hid_mouse_report_t *)in_dev->data;
- //Get latest info from USB devices
- MouseController *mouse = (MouseController *)input_devices[id].driver;
- _buttons = mouse->getButtons();
+ state->dButtons = 0;
+ state->x_axis = report->x;
+ state->y_axis = -report->y;
- _axis[0] = mouse->getMouseX();
- _axis[1] = mouse->getMouseY();
+ if (report->buttons & (1 << 0)) state->dButtons |= N64_A; //A left click
+ if (report->buttons & (1 << 1)) state->dButtons |= N64_B; //B right click
+ if (report->buttons & (1 << 2)) state->dButtons |= N64_ST; //ST middle click
- static uint32_t idle_timer[4] = {0};
- if (mouse->available()) idle_timer[id] = millis();
- mouse->mouseDataClear();
- if (millis() - idle_timer[id] > 100)
+ //Need to do this for stale data and mouse wont send a 0 byte if its not moving
+ if (n64hal_millis() - hid_data_tick[in_dev->slot] > 10)
{
- _axis[0] = 0;
- _axis[1] = 0;
+ report->x = 0;
+ report->y = 0;
}
-
- //Mouse input is pretty standard, Map to N64 mouse
- if (_axis[0] * MOUSE_SENSITIVITY > 127) _axis[0] = 127;
- if (_axis[1] * MOUSE_SENSITIVITY > 127) _axis[1] = 127;
- if (_axis[0] * MOUSE_SENSITIVITY < -128) _axis[0] = -128;
- if (_axis[1] * MOUSE_SENSITIVITY < -128) _axis[1] = -128;
- state->x_axis = _axis[0] * MOUSE_SENSITIVITY;
- state->y_axis = -_axis[1] * MOUSE_SENSITIVITY;
- if (_buttons & (1 << 0)) state->dButtons |= N64_A; //A
- if (_buttons & (1 << 1)) state->dButtons |= N64_B; //B
- if (_buttons & (1 << 2)) state->dButtons |= N64_ST; //ST
}
-#endif
-
-#if (MAX_KB >= 1)
- else if (input_is_kb(id))
+ else if (input_is(id, INPUT_KEYBOARD))
{
- //Prep N64 response
- n64_randnet_kb *state = (n64_randnet_kb *)response;
-
- //Get latest info from USB devices
- KeyboardController *kb = (KeyboardController *)input_devices[id].driver;
+ n64_randnet_kb *new_state = (n64_randnet_kb *)response;
+ hid_keyboard_report_t *report = (hid_keyboard_report_t *)in_dev->data;
+ memset(new_state->buttons, 0, sizeof(new_state->buttons));
+ new_state->flags = 0;
- kb->capsLock((state->led_state & RANDNET_LED_CAPSLOCK) != 0);
- kb->numLock((state->led_state & RANDNET_LED_NUMLOCK) != 0);
- kb->scrollLock((state->led_state & RANDNET_LED_POWER) != 0);
- uint8_t home_key_flag = 0;
- //Map up to 3 keys to the randnet response packet
- for (int i = 0; i < RANDNET_MAX_BUTTONS; i++)
+ //https://sites.google.com/site/consoleprotocols/home/nintendo-joy-bus-documentation/n64-specific/randnet-keyboard
+ uint8_t a = 0, b = 0, c = 0;
+ uint8_t mod = report->modifier;
+ uint8_t hid_keyboard_press = kb_modifier_to_key(mod & (1 << c));
+ mod &= ~(1 << c);
+ while (a < RANDNET_MAX_BUTTONS && b < sizeof(report->keycode))
{
- state->buttons[i] = 0;
- if (kb_keys_pressed[i] == 0)
- continue;
-
- if (kb_keys_pressed[i] == (uint8_t)(KEY_HOME & 0xFF))
- {
- home_key_flag = 1;
- continue;
- }
-
- //Keyboard is pressed, get the corressponding randnet code and put it in the response
- uint16_t randnet_code = 0;
- for (uint32_t j = 0; j < (sizeof(randnet_map) / sizeof(randnet_map_t)); j++)
+ if (hid_keyboard_press != 0)
{
- if (kb_keys_pressed[i] == (uint8_t)(randnet_map[j].keypad & 0xFF))
+ //report outputs 1 if too many keys are pressed on the keyboard
+ if (hid_keyboard_press == 1)
+ {
+ new_state->flags |= RANDNET_FLAG_EXCESS_BUTTONS;
+ break;
+ }
+ //Randnet has a status flag for the home button.
+ if (hid_keyboard_press == HID_KEY_HOME)
{
- randnet_code = randnet_map[j].randnet_matrix;
+ new_state->flags |= RANDNET_FLAG_HOME_KEY;
+ break;
+ }
+ //Handle all other key presses
+ for (uint32_t d = 0; d < (sizeof(randnet_map) / sizeof(randnet_map_t)); d++)
+ {
+ if (hid_keyboard_press == randnet_map[d].keypad)
+ {
+ new_state->buttons[a++] = randnet_map[d].randnet_matrix;
+ break;
+ }
}
}
- state->buttons[i] = randnet_code;
+ //Get the next key (modifier or normal key)
+ if (mod)
+ {
+ c++;
+ hid_keyboard_press = kb_modifier_to_key(mod & (1 << c));
+ mod &= ~(1 << c);
+ }
+ else
+ {
+ hid_keyboard_press = report->keycode[b++];
+ }
}
-
- (home_key_flag) ? state->flags |= RANDNET_FLAG_HOME_KEY :
- state->flags &= ~RANDNET_FLAG_HOME_KEY;
}
-#endif
-
-#if (ENABLE_HARDWIRED_CONTROLLER >=1)
- else if (input_is_hw_gamecontroller(id))
- {
- n64_buttonmap *state = (n64_buttonmap *)response;
- state->dButtons = 0;
-
- if (!digitalRead(HW_A)) state->dButtons |= N64_A;
- if (!digitalRead(HW_B)) state->dButtons |= N64_B;
- if (!digitalRead(HW_CU)) state->dButtons |= N64_CU;
- if (!digitalRead(HW_CD)) state->dButtons |= N64_CD;
- if (!digitalRead(HW_CL)) state->dButtons |= N64_CL;
- if (!digitalRead(HW_CR)) state->dButtons |= N64_CR;
- if (!digitalRead(HW_DU)) state->dButtons |= N64_DU;
- if (!digitalRead(HW_DD)) state->dButtons |= N64_DD;
- if (!digitalRead(HW_DL)) state->dButtons |= N64_DL;
- if (!digitalRead(HW_DR)) state->dButtons |= N64_DR;
- if (!digitalRead(HW_START)) state->dButtons |= N64_ST;
- if (!digitalRead(HW_Z)) state->dButtons |= N64_Z;
- if (!digitalRead(HW_L)) state->dButtons |= N64_LB;
- if (!digitalRead(HW_R)) state->dButtons |= N64_RB;
-
- //10bit ADC
- state->x_axis = analogRead(HW_X) * 200 / 1024 - 100; //+/-100
- state->y_axis = analogRead(HW_Y) * 200 / 1024 - 100; //+/-100
-
- if (combo_pressed)
- *combo_pressed = !digitalRead(HW_L) && !digitalRead(HW_R); //FIXME: ADD A COMBO INPUT?
- }
-#endif
- else
- {
- return 0;
- }
-
return 1;
}
void input_apply_rumble(int id, uint8_t strength)
{
- JoystickController *joy;
- if (input_is_gamecontroller(id))
- {
- joy = (JoystickController *)input_devices[id].driver;
- joy->setRumble(strength, strength, 20);
- }
-#if (ENABLE_HARDWIRED_CONTROLLER >=1)
- else if (input_is_hw_gamecontroller(id))
- {
- (strength > 0) ? digitalWrite(HW_RUMBLE, HIGH) : digitalWrite(HW_RUMBLE, LOW);
- }
-#endif
-}
-
-bool input_is_connected(int id)
-{
- bool connected = false;
if (_check_id(id) == 0)
- return false;
-
- if (input_is_gamecontroller(id))
- {
- JoystickController *joy = (JoystickController *)input_devices[id].driver;
- if (*joy == true)
- connected = true;
- }
-
-#if (MAX_MICE >=1)
- else if (input_is_mouse(id))
- {
- USBHIDInput *mouse = (USBHIDInput *)input_devices[id].driver;
- if (*mouse == true)
- connected = true;
- }
-#endif
+ return;
-#if (MAX_KB >=1)
- else if (input_is_kb(id))
+ input_driver_t *in_dev = &input_devices[id];
+ if (in_dev->set_rumble)
{
- USBHIDInput *kb = (USBHIDInput *)input_devices[id].driver;
- if (*kb == true)
- connected = true;
+ uint8_t dev_addr = in_dev->uid >> 8;
+ uint8_t instance = in_dev->uid & 0xFF;
+ in_dev->set_rumble(dev_addr, instance, strength, strength, true);
}
-#endif
-
-#if (ENABLE_HARDWIRED_CONTROLLER >=1)
- else if (input_is_hw_gamecontroller(id))
- {
- if (digitalRead(HW_EN) == 0)
- connected = true;
- }
-#endif
-
- return connected;
}
-bool input_is_mouse(int id)
+bool input_is_connected(int id)
{
- if (_check_id(id) == 0)
+ if (id >= MAX_USB_CONTROLLERS)
return false;
- if (input_devices[id].type == USB_MOUSE)
- return true;
- return false;
-}
-bool input_is_kb(int id)
-{
- if (_check_id(id) == 0)
- return false;
- if (input_devices[id].type == USB_KB)
- return true;
- return false;
+ return (input_devices[id].backend != BACKEND_NONE);
}
-bool input_is_gamecontroller(int id)
+bool input_is(int id, input_type_t type)
{
- if (_check_id(id) == 0)
+ if (id >= MAX_USB_CONTROLLERS)
return false;
- if (input_devices[id].type == USB_GAMECONTROLLER)
- return true;
- return false;
-}
-bool input_is_hw_gamecontroller(int id)
-{
- if (_check_id(id) == 0)
- return false;
- if (input_devices[id].type == HW_GAMECONTROLLER)
- return true;
- return false;
+ return (input_devices[id].type == type);
}
uint16_t input_get_id_product(int id)
{
- if (_check_id(id) == 0 || input_is_connected(id) == 0)
+ if (_check_id(id) == 0)
return 0;
- if (input_is_gamecontroller(id))
- {
- JoystickController *joy = (JoystickController *)input_devices[id].driver;
- return joy->idProduct();
- }
- else if (input_is_mouse(id))
- {
- USBHIDInput *mouse = (USBHIDInput *)input_devices[id].driver;
- return mouse->idProduct();
- }
- else if (input_is_kb(id))
- {
- USBHIDInput *kb = (USBHIDInput *)input_devices[id].driver;
- return kb->idProduct();
- }
- else if (input_is_hw_gamecontroller(id))
- {
- return 0xBEEF;
- }
+ input_driver_t *in_dev = &input_devices[id];
- return 0;
+ uint16_t pid, vid;
+ tuh_vid_pid_get(in_dev->uid >> 8, &vid, &pid);
+ return pid;
}
uint16_t input_get_id_vendor(int id)
{
- if (_check_id(id) == 0 || input_is_connected(id) == 0)
+ if (_check_id(id) == 0)
return 0;
- if (input_is_gamecontroller(id))
- {
- JoystickController *joy = (JoystickController *)input_devices[id].driver;
- return joy->idVendor();
- }
- else if (input_is_mouse(id))
- {
- USBHIDInput *mouse = (USBHIDInput *)input_devices[id].driver;
- return mouse->idVendor();
- }
- else if (input_is_kb(id))
- {
- USBHIDInput *kb = (USBHIDInput *)input_devices[id].driver;
- return kb->idVendor();
- }
- else if (input_is_hw_gamecontroller(id))
- {
- return 0xDEAD;
- }
+ input_driver_t *in_dev = &input_devices[id];
- return 0;
+ uint16_t pid, vid;
+ tuh_vid_pid_get(in_dev->uid >> 8, &vid, &pid);
+ return vid;
}
const char *input_get_manufacturer_string(int id)
{
+ //FIXME
static const char NC[] = "NOT CONNECTED";
if (_check_id(id) == 0 || input_is_connected(id) == false)
return NC;
- if (input_is_gamecontroller(id))
- {
- JoystickController *joy = (JoystickController *)input_devices[id].driver;
- return (const char *)joy->manufacturer();
- }
- else if (input_is_mouse(id))
- {
- USBHIDInput *mouse = (USBHIDInput *)input_devices[id].driver;
- return (const char *)mouse->manufacturer();
- }
- else if (input_is_kb(id))
- {
- USBHIDInput *kb = (USBHIDInput *)input_devices[id].driver;
- return (const char *)kb->manufacturer();
- }
- else if (input_is_hw_gamecontroller(id))
- {
- return "USB64";
- }
-
- return NC;
+ return "USB64";
}
const char *input_get_product_string(int id)
{
+ //FIXME
static const char NC[] = "";
- if (_check_id(id) == 0 || input_is_connected(id) == 0)
- return NC;
-
- if (input_is_gamecontroller(id))
- {
- JoystickController *joy = (JoystickController *)input_devices[id].driver;
- return (const char *)joy->product();
- }
- else if (input_is_mouse(id))
- {
- USBHIDInput *mouse = (USBHIDInput *)input_devices[id].driver;
- return (const char *)mouse->product();
- }
- else if (input_is_kb(id))
- {
- USBHIDInput *kb = (USBHIDInput *)input_devices[id].driver;
- return (const char *)kb->product();
- }
- else if (input_is_hw_gamecontroller(id))
- {
- return "HARDWIRED";
- }
-
return NC;
}
@@ -814,7 +437,7 @@ void input_enable_dualstick_mode(int id)
return;
//Copy driver into the next slot to make a 'fake' input
- memcpy(&input_devices[id + 1], &input_devices[id], sizeof(input));
+ memcpy(&input_devices[id + 1], &input_devices[id], sizeof(input_driver_t));
}
void input_disable_dualstick_mode(int id)
@@ -826,8 +449,7 @@ void input_disable_dualstick_mode(int id)
return;
//Clear the 'fake' controller driver
- input_devices[id + 1].driver = NULL;
-
+ memset(&input_devices[id + 1], 0, sizeof(input_driver_t ));
}
bool input_is_dualstick_mode(int id)
@@ -836,14 +458,14 @@ bool input_is_dualstick_mode(int id)
return false;
//Check if this is a 'fake' mirror of a main controller
- if ((id == 1 || id == 3) && input_devices[id].driver == input_devices[id - 1].driver)
+ if ((id == 1 || id == 3) && input_devices[id].uid == input_devices[id - 1].uid)
return true;
if (id + 1 >= MAX_CONTROLLERS)
return false;
//Check if this is a main controller that is mirrored
- if (input_devices[id].driver == input_devices[id + 1].driver)
+ if (input_devices[id].uid == input_devices[id + 1].uid)
return true;
return false;
diff --git a/src/input.h b/src/input.h
index 7806e1d7..d8062a96 100644
--- a/src/input.h
+++ b/src/input.h
@@ -4,123 +4,135 @@
#ifndef _INPUT_H
#define _INPUT_H
-#include
+#include "common.h"
+#include "tusb.h"
typedef struct
{
- uint16_t keypad;
+ uint8_t keypad;
uint16_t randnet_matrix;
} randnet_map_t;
-static const randnet_map_t randnet_map[] = {
- {KEY_ESC, 0x0A08}, //Escape
- {KEY_F1, 0x0B01}, // F1
- {KEY_F2, 0x0A01}, // F2
- {KEY_F3, 0x0B08}, // F3
- {KEY_F4, 0x0A07}, // F4
- {KEY_F5, 0x0B07}, // F5
- {KEY_F6, 0x0A02}, // F6
- {KEY_F7, 0x0B02}, // F7
- {KEY_F8, 0x0A03}, // F8
- {KEY_F9, 0x0B03}, // F9
- {KEY_F10, 0x0A04}, // F10
- {KEY_F11, 0x0203}, // F11
- {KEY_F12, 0x0B06}, // F12
- {KEY_NUM_LOCK, 0x0A05}, // Num Lock
- {KEY_PRINTSCREEN, 0x0B05}, //Japanese Key below Numlock LED
- {KEY_SCROLL_LOCK, 0x0208}, //Japanese Key below Caps Lock LED
- {KEY_PAUSE, 0x0207}, // Japanese Key below Power LED
- {KEY_TILDE, 0x0D05}, //~
- {KEY_1, 0x0C05}, //Number 1
- {KEY_2, 0x0505}, //Number 2
- {KEY_3, 0x0605}, //Number 3
- {KEY_4, 0x0705}, //Number 4
- {KEY_5, 0x0805}, //Number 5
- {KEY_6, 0x0905}, //Number 6
- {KEY_7, 0x0906}, //Number 7
- {KEY_8, 0x0806}, //Number 8
- {KEY_9, 0x0706}, //Number 9
- {KEY_0, 0x0606}, //Number 0
- {KEYPAD_MINUS, 0x0506}, //-
- {KEYPAD_PLUS, 0x0C06}, //^
- {KEY_BACKSPACE, 0x0D06}, //Backspace
- {KEY_TAB, 0x0D01}, //Tab
- {KEY_Q, 0x0C01}, //Q
- {KEY_W, 0x0501}, //W
- {KEY_E, 0x0601}, //E
- {KEY_R, 0x0701}, //R
- {KEY_T, 0x0801}, //T
- {KEY_Y, 0x0901}, //Y
- {KEY_U, 0x0904}, //U
- {KEY_I, 0x0804}, //I
- {KEY_O, 0x0704}, //O
- {KEY_P, 0x0604}, //P
- {KEY_QUOTE, 0x0504}, //'
- {KEY_LEFT_BRACE, 0x0C04}, //{
- {KEY_RIGHT_BRACE, 0x0406}, //}
- {KEY_CAPS_LOCK, 0x0F05}, //Caps Lock
- {KEY_A, 0x0D07}, //A
- {KEY_S, 0x0C07}, //S
- {KEY_D, 0x0507}, //D
- {KEY_F, 0x0607}, //F
- {KEY_G, 0x0707}, //G
- {KEY_H, 0x0807}, //H
- {KEY_J, 0x0907}, //J
- {KEY_K, 0x0903}, //K
- {KEY_L, 0x0803}, //L
- {KEYPAD_PLUS, 0x0703}, //+
- {KEYPAD_ASTERIX, 0x0603}, //*
- {KEY_ENTER, 0x0D04}, //Enter
- {104, 0x0E01}, //Left Shift
- {KEY_Z, 0x0D08}, //Z
- {KEY_X, 0x0C08}, //X
- {KEY_C, 0x0508}, //C
- {KEY_V, 0x0608}, //V
- {KEY_B, 0x0708}, //B
- {KEY_N, 0x0808}, //N
- {KEY_M, 0x0908}, //M
- {KEY_COMMA, 0x0902}, //<
- {KEY_PERIOD, 0x0802}, //>
- {KEY_SLASH, 0x0702}, //?
- {KEY_MINUS, 0x1004}, //- (Long dash)
- {KEY_UP, 0x0204}, //Up Cursor
- {104, 0x0E06}, //Right Shift
- {103, 0x1107}, //Ctrl
- {110, 0x0F07}, //Opt
- {KEY_SEMICOLON, 0x1105}, //| (Pipes)
- {105, 0x1008}, //Alt
- {KEYPAD_1, 0x1002}, //Japanese 'alphanumeric key'
- {KEY_SPACE, 0x0602}, //Space
- {KEYPAD_2, 0x0E02}, //Japanese 'kana'
- {KEYPAD_3, 0x1006}, //Japanese Character
- {KEY_END, 0x0206}, //End 行末
- {KEY_LEFT, 0x0205}, //Left Cursor
- {KEY_DOWN, 0x0305}, //Down Cursor
- {KEY_RIGHT, 0x0405}, //Right Cursor
+static const randnet_map_t randnet_map[] PROGMEM = {
+ {HID_KEY_ESCAPE, 0x0A08}, //Escape
+ {HID_KEY_F1, 0x0B01}, // F1
+ {HID_KEY_F2, 0x0A01}, // F2
+ {HID_KEY_F3, 0x0B08}, // F3
+ {HID_KEY_F4, 0x0A07}, // F4
+ {HID_KEY_F5, 0x0B07}, // F5
+ {HID_KEY_F6, 0x0A02}, // F6
+ {HID_KEY_F7, 0x0B02}, // F7
+ {HID_KEY_F8, 0x0A03}, // F8
+ {HID_KEY_F9, 0x0B03}, // F9
+ {HID_KEY_F10, 0x0A04}, // F10
+ {HID_KEY_F11, 0x0203}, // F11
+ {HID_KEY_F12, 0x0B06}, // F12
+ {HID_KEY_NUM_LOCK, 0x0A05}, // Num Lock
+ {HID_KEY_PRINT_SCREEN, 0x0B05}, //Japanese Key below Numlock LED
+ {HID_KEY_SCROLL_LOCK, 0x0208}, //Japanese Key below Caps Lock LED
+ {HID_KEY_PAUSE, 0x0207}, // Japanese Key below Power LED
+ {HID_KEY_GRAVE, 0x0D05}, //~
+ {HID_KEY_1, 0x0C05}, //Number 1
+ {HID_KEY_2, 0x0505}, //Number 2
+ {HID_KEY_3, 0x0605}, //Number 3
+ {HID_KEY_4, 0x0705}, //Number 4
+ {HID_KEY_5, 0x0805}, //Number 5
+ {HID_KEY_6, 0x0905}, //Number 6
+ {HID_KEY_7, 0x0906}, //Number 7
+ {HID_KEY_8, 0x0806}, //Number 8
+ {HID_KEY_9, 0x0706}, //Number 9
+ {HID_KEY_0, 0x0606}, //Number 0
+ {HID_KEY_KEYPAD_SUBTRACT, 0x0506}, //-
+ {HID_KEY_KEYPAD_ADD, 0x0C06}, //^
+ {HID_KEY_BACKSPACE, 0x0D06}, //Backspace
+ {HID_KEY_TAB, 0x0D01}, //Tab
+ {HID_KEY_Q, 0x0C01}, //Q
+ {HID_KEY_W, 0x0501}, //W
+ {HID_KEY_E, 0x0601}, //E
+ {HID_KEY_R, 0x0701}, //R
+ {HID_KEY_T, 0x0801}, //T
+ {HID_KEY_Y, 0x0901}, //Y
+ {HID_KEY_U, 0x0904}, //U
+ {HID_KEY_I, 0x0804}, //I
+ {HID_KEY_O, 0x0704}, //O
+ {HID_KEY_P, 0x0604}, //P
+ {HID_KEY_APOSTROPHE, 0x0504}, //'
+ {HID_KEY_BRACKET_LEFT, 0x0C04}, //{
+ {HID_KEY_BRACKET_RIGHT, 0x0406}, //}
+ {HID_KEY_CAPS_LOCK, 0x0F05}, //Caps Lock
+ {HID_KEY_A, 0x0D07}, //A
+ {HID_KEY_S, 0x0C07}, //S
+ {HID_KEY_D, 0x0507}, //D
+ {HID_KEY_F, 0x0607}, //F
+ {HID_KEY_G, 0x0707}, //G
+ {HID_KEY_H, 0x0807}, //H
+ {HID_KEY_J, 0x0907}, //J
+ {HID_KEY_K, 0x0903}, //K
+ {HID_KEY_L, 0x0803}, //L
+ {HID_KEY_KEYPAD_ADD, 0x0703}, //+
+ {HID_KEY_KEYPAD_MULTIPLY, 0x0603}, //*
+ {HID_KEY_ENTER, 0x0D04}, //Enter
+ {HID_KEY_SHIFT_LEFT, 0x0E01}, //Left Shift
+ {HID_KEY_Z, 0x0D08}, //Z
+ {HID_KEY_X, 0x0C08}, //X
+ {HID_KEY_C, 0x0508}, //C
+ {HID_KEY_V, 0x0608}, //V
+ {HID_KEY_B, 0x0708}, //B
+ {HID_KEY_N, 0x0808}, //N
+ {HID_KEY_M, 0x0908}, //M
+ {HID_KEY_COMMA, 0x0902}, //<
+ {HID_KEY_PERIOD, 0x0802}, //>
+ {HID_KEY_SLASH, 0x0702}, //?
+ {HID_KEY_MINUS, 0x1004}, //- (Long dash)
+ {HID_KEY_ARROW_UP, 0x0204}, //Up Cursor
+ {HID_KEY_SHIFT_RIGHT, 0x0E06}, //Right Shift
+ {HID_KEY_CONTROL_LEFT, 0x1107},//Ctrl
+ {HID_KEY_GUI_LEFT, 0x0F07}, //Opt
+ {HID_KEY_SEMICOLON, 0x1105}, //| (Pipes)
+ {HID_KEY_ALT_LEFT, 0x1008}, //Alt
+ {HID_KEY_KEYPAD_1, 0x1002}, //Japanese 'alphanumeric key'
+ {HID_KEY_SPACE, 0x0602}, //Space
+ {HID_KEY_KEYPAD_2, 0x0E02}, //Japanese 'kana'
+ {HID_KEY_KEYPAD_3, 0x1006}, //Japanese Character
+ {HID_KEY_END, 0x0206}, //End 行末
+ {HID_KEY_ARROW_LEFT, 0x0205}, //Left Cursor
+ {HID_KEY_ARROW_DOWN, 0x0305}, //Down Cursor
+ {HID_KEY_ARROW_RIGHT, 0x0405}, //Right Cursor
};
-enum
+typedef enum
{
- USB_MOUSE,
- USB_KB,
- USB_GAMECONTROLLER,
- HW_GAMECONTROLLER,
- I2C_GAMECONTROLLER
-};
+ INPUT_NONE,
+ INPUT_MOUSE,
+ INPUT_KEYBOARD,
+ INPUT_GAMECONTROLLER,
+} input_type_t;
-typedef struct
+typedef enum input_backend
+{
+ BACKEND_NONE,
+ BACKEND_XINPUT,
+ BACKEND_HID_KEYBOARD,
+ BACKEND_HID_MOUSE,
+ BACKEND_HARDWIRED,
+} input_backend_t;
+
+typedef struct input_driver
{
- void *driver;
- int type;
-} input;
+ uint8_t slot;
+ input_type_t type;
+ input_backend_t backend;
+ uint8_t _data[CFG_TUH_XINPUT_EPIN_BUFSIZE];
+ uint8_t *data;
+ uint16_t uid;
+ bool (*set_rumble)(uint8_t dev_addr, uint8_t instance, uint8_t lValue, uint8_t rValue, bool block);
+ bool (*set_led)(uint8_t dev_addr, uint8_t instance, uint8_t quadrant, bool block);
+}input_driver_t;
void input_init();
void input_update_input_devices();
bool input_is_connected(int id);
-bool input_is_mouse(int id);
-bool input_is_kb(int id);
-bool input_is_gamecontroller(int id);
-bool input_is_hw_gamecontroller(int id);
+bool input_is(int id, input_type_t type);
uint16_t input_get_id_product(int id);
uint16_t input_get_id_vendor(int id);
const char *input_get_manufacturer_string(int id);
diff --git a/src/lib/GuiLite.h b/src/lib/GuiLite.h
new file mode 100644
index 00000000..b6652636
--- /dev/null
+++ b/src/lib/GuiLite.h
@@ -0,0 +1,4343 @@
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wreorder"
+#pragma GCC diagnostic ignored "-Wsign-compare"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+
+#pragma once
+
+#define REAL_TIME_TASK_CYCLE_MS 50
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#define MIN(a,b) (((a)<(b))?(a):(b))
+
+#define GL_ARGB(a, r, g, b) ((((unsigned int)(a)) << 24) | (((unsigned int)(r)) << 16) | (((unsigned int)(g)) << 8) | ((unsigned int)(b)))
+#define GL_ARGB_A(rgb) ((((unsigned int)(rgb)) >> 24) & 0xFF)
+
+#define GL_RGB(r, g, b) ((0xFF << 24) | (((unsigned int)(r)) << 16) | (((unsigned int)(g)) << 8) | ((unsigned int)(b)))
+#define GL_RGB_R(rgb) ((((unsigned int)(rgb)) >> 16) & 0xFF)
+#define GL_RGB_G(rgb) ((((unsigned int)(rgb)) >> 8) & 0xFF)
+#define GL_RGB_B(rgb) (((unsigned int)(rgb)) & 0xFF)
+#define GL_RGB_32_to_16(rgb) (((((unsigned int)(rgb)) & 0xFF) >> 3) | ((((unsigned int)(rgb)) & 0xFC00) >> 5) | ((((unsigned int)(rgb)) & 0xF80000) >> 8))
+#define GL_RGB_16_to_32(rgb) ((0xFF << 24) | ((((unsigned int)(rgb)) & 0x1F) << 3) | ((((unsigned int)(rgb)) & 0x7E0) << 5) | ((((unsigned int)(rgb)) & 0xF800) << 8))
+
+#define ALIGN_HCENTER 0x00000000L
+#define ALIGN_LEFT 0x01000000L
+#define ALIGN_RIGHT 0x02000000L
+#define ALIGN_HMASK 0x03000000L
+
+#define ALIGN_VCENTER 0x00000000L
+#define ALIGN_TOP 0x00100000L
+#define ALIGN_BOTTOM 0x00200000L
+#define ALIGN_VMASK 0x00300000L
+
+typedef struct
+{
+ unsigned short year;
+ unsigned short month;
+ unsigned short date;
+ unsigned short day;
+ unsigned short hour;
+ unsigned short minute;
+ unsigned short second;
+}T_TIME;
+
+void register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log));
+void _assert(const char* file, int line);
+#define ASSERT(condition) \
+ do{ \
+ if(!(condition))_assert(__FILE__, __LINE__);\
+ }while(0)
+void log_out(const char* log);
+
+long get_time_in_second();
+T_TIME second_to_day(long second);
+T_TIME get_time();
+
+void start_real_timer(void (*func)(void* arg));
+void register_timer(int milli_second, void func(void* param), void* param);
+
+unsigned int get_cur_thread_id();
+void create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg);
+void thread_sleep(unsigned int milli_seconds);
+int build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data);
+
+#define FIFO_BUFFER_LEN 1024
+class c_fifo
+{
+public:
+ c_fifo();
+ int read(void* buf, int len);
+ int write(void* buf, int len);
+private:
+ unsigned char m_buf[FIFO_BUFFER_LEN];
+ int m_head;
+ int m_tail;
+ void* m_read_sem;
+ void* m_write_mutex;
+};
+
+class c_rect
+{
+public:
+ c_rect(){ m_left = m_top = m_right = m_bottom = -1; }
+ c_rect(int left, int top, int width, int height)
+ {
+ set_rect(left, top, width, height);
+ }
+ void set_rect(int left, int top, int width, int height)
+ {
+ ASSERT(width > 0 && height > 0);
+ m_left = left;
+ m_top = top;
+ m_right = left + width - 1;
+ m_bottom = top + height -1;
+ }
+ bool pt_in_rect(int x, int y) const
+ {
+ return x >= m_left && x <= m_right && y >= m_top && y <= m_bottom;
+ }
+ int operator==(const c_rect& rect) const
+ {
+ return (m_left == rect.m_left) && (m_top == rect.m_top) && (m_right == rect.m_right) && (m_bottom == rect.m_bottom);
+ }
+ int width() const { return m_right - m_left + 1; }
+ int height() const { return m_bottom - m_top + 1 ; }
+
+ int m_left;
+ int m_top;
+ int m_right;
+ int m_bottom;
+};
+//BITMAP
+typedef struct struct_bitmap_info
+{
+ unsigned short width;
+ unsigned short height;
+ unsigned short color_bits;//support 16 bits only
+ const unsigned short* pixel_color_array;
+} BITMAP_INFO;
+//FONT
+typedef struct struct_lattice
+{
+ unsigned int utf8_code;
+ unsigned char width;
+ const unsigned char* pixel_buffer;
+} LATTICE;
+typedef struct struct_lattice_font_info
+{
+ unsigned char height;
+ unsigned int count;
+ LATTICE* lattice_array;
+} LATTICE_FONT_INFO;
+//Rebuild gui library once you change this file
+enum FONT_LIST
+{
+ FONT_NULL,
+ FONT_DEFAULT,
+ FONT_CUSTOM1,
+ FONT_CUSTOM2,
+ FONT_CUSTOM3,
+ FONT_CUSTOM4,
+ FONT_CUSTOM5,
+ FONT_CUSTOM6,
+ FONT_MAX
+};
+enum IMAGE_LIST
+{
+ IMAGE_CUSTOM1,
+ IMAGE_CUSTOM2,
+ IMAGE_CUSTOM3,
+ IMAGE_CUSTOM4,
+ IMAGE_CUSTOM5,
+ IMAGE_CUSTOM6,
+ IMAGE_MAX
+};
+enum COLOR_LIST
+{
+ COLOR_WND_FONT,
+ COLOR_WND_NORMAL,
+ COLOR_WND_PUSHED,
+ COLOR_WND_FOCUS,
+ COLOR_WND_BORDER,
+ COLOR_CUSTOME1,
+ COLOR_CUSTOME2,
+ COLOR_CUSTOME3,
+ COLOR_CUSTOME4,
+ COLOR_CUSTOME5,
+ COLOR_CUSTOME6,
+ COLOR_MAX
+};
+class c_theme
+{
+public:
+ static int add_font(FONT_LIST index, const void* font)
+ {
+ if (index >= FONT_MAX)
+ {
+ ASSERT(false);
+ return -1;
+ }
+ s_font_map[index] = font;
+ return 0;
+ }
+ static const void* get_font(FONT_LIST index)
+ {
+ if (index >= FONT_MAX)
+ {
+ ASSERT(false);
+ return 0;
+ }
+ return s_font_map[index];
+ }
+ static int add_image(IMAGE_LIST index, const void* image_info)
+ {
+ if (index >= IMAGE_MAX)
+ {
+ ASSERT(false);
+ return -1;
+ }
+ s_image_map[index] = image_info;
+ return 0;
+ }
+ static const void* get_image(IMAGE_LIST index)
+ {
+ if (index >= IMAGE_MAX)
+ {
+ ASSERT(false);
+ return 0;
+ }
+ return s_image_map[index];
+ }
+
+ static int add_color(COLOR_LIST index, const unsigned int color)
+ {
+ if (index >= COLOR_MAX)
+ {
+ ASSERT(false);
+ return -1;
+ }
+ s_color_map[index] = color;
+ return 0;
+ }
+ static const unsigned int get_color(COLOR_LIST index)
+ {
+ if (index >= COLOR_MAX)
+ {
+ ASSERT(false);
+ return 0;
+ }
+ return s_color_map[index];
+ }
+private:
+ static const void* s_font_map[FONT_MAX];
+ static const void* s_image_map[IMAGE_MAX];
+ static unsigned int s_color_map[COLOR_MAX];
+};
+#include
+#include
+#include
+#define SURFACE_CNT_MAX 6//root + pages
+typedef enum
+{
+ Z_ORDER_LEVEL_0,//lowest graphic level
+ Z_ORDER_LEVEL_1,//middle graphic level
+ Z_ORDER_LEVEL_2,//highest graphic level
+ Z_ORDER_LEVEL_MAX
+}Z_ORDER_LEVEL;
+struct EXTERNAL_GFX_OP
+{
+ void(*draw_pixel)(int x, int y, unsigned int rgb);
+ void(*fill_rect)(int x0, int y0, int x1, int y1, unsigned int rgb);
+};
+class c_surface;
+class c_display {
+ friend class c_surface;
+public:
+ inline c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, EXTERNAL_GFX_OP* gfx_op = 0);//multiple surface or surface_no_fb
+ inline c_display(void* phy_fb, int display_width, int display_height, c_surface* surface);//single custom surface
+ inline c_surface* alloc_surface(Z_ORDER_LEVEL max_zorder, c_rect layer_rect = c_rect());//for multiple surfaces
+ inline int swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset);
+ int get_width() { return m_width; }
+ int get_height() { return m_height; }
+ void* get_updated_fb(int* width, int* height, bool force_update = false)
+ {
+ if (width && height)
+ {
+ *width = get_width();
+ *height = get_height();
+ }
+ if (force_update)
+ {
+ return m_phy_fb;
+ }
+ if (m_phy_read_index == m_phy_write_index)
+ {//No update
+ return 0;
+ }
+ m_phy_read_index = m_phy_write_index;
+ return m_phy_fb;
+ }
+ int snap_shot(const char* file_name)
+ {
+ if (!m_phy_fb || (m_color_bytes !=2 && m_color_bytes != 4))
+ {
+ return -1;
+ }
+ int width = get_width();
+ int height = get_height();
+ //16 bits framebuffer
+ if (m_color_bytes == 2)
+ {
+ return build_bmp(file_name, width, height, (unsigned char*)m_phy_fb);
+ }
+ //32 bits framebuffer
+ unsigned short* p_bmp565_data = new unsigned short[width * height];
+ unsigned int* p_raw_data = (unsigned int*)m_phy_fb;
+ for (int i = 0; i < width * height; i++)
+ {
+ unsigned int rgb = *p_raw_data++;
+ p_bmp565_data[i] = GL_RGB_32_to_16(rgb);
+ }
+ int ret = build_bmp(file_name, width, height, (unsigned char*)p_bmp565_data);
+ delete[]p_bmp565_data;
+ return ret;
+ }
+private:
+ int m_width; //in pixels
+ int m_height; //in pixels
+ int m_color_bytes; //16 bits, 32 bits only
+ void* m_phy_fb; //physical framebuffer
+ int m_phy_read_index;
+ int m_phy_write_index;
+ c_surface* m_surface_group[SURFACE_CNT_MAX];
+ int m_surface_cnt; //surface count
+ int m_surface_index;
+};
+class c_layer
+{
+public:
+ c_layer() { fb = 0; }
+ void* fb; //framebuffer
+ c_rect rect; //framebuffer area
+};
+class c_surface {
+ friend class c_display; friend class c_bitmap_operator;
+public:
+ c_surface(unsigned int width, unsigned int height, unsigned int color_bytes, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0, c_rect overlpa_rect = c_rect()) : m_width(width), m_height(height), m_color_bytes(color_bytes), m_fb(0), m_is_active(false), m_top_zorder(Z_ORDER_LEVEL_0), m_phy_fb(0), m_phy_write_index(0), m_display(0)
+ {
+ (overlpa_rect == c_rect()) ? set_surface(max_zorder, c_rect(0, 0, width - 1, height - 1)) : set_surface(max_zorder, overlpa_rect);
+ }
+ int get_width() { return m_width; }
+ int get_height() { return m_height; }
+ unsigned int get_pixel(int x, int y, unsigned int z_order)
+ {
+ if (x >= m_width || y >= m_height || x < 0 || y < 0 || z_order >= Z_ORDER_LEVEL_MAX)
+ {
+ ASSERT(false);
+ return 0;
+ }
+ if (m_layers[z_order].fb)
+ {
+ return (m_color_bytes == 4) ? ((unsigned int*)(m_layers[z_order].fb))[y * m_width + x] : GL_RGB_16_to_32(((unsigned short*)(m_layers[z_order].fb))[y * m_width + x]);
+ }
+ else if (m_fb)
+ {
+ return (m_color_bytes == 4) ? ((unsigned int*)m_fb)[y * m_width + x] : GL_RGB_16_to_32(((unsigned short*)m_fb)[y * m_width + x]);
+ }
+ else if (m_phy_fb)
+ {
+ return (m_color_bytes == 4) ? ((unsigned int*)m_phy_fb)[y * m_width + x] : GL_RGB_16_to_32(((unsigned short*)m_phy_fb)[y * m_width + x]);
+ }
+ return 0;
+ }
+ virtual void draw_pixel(int x, int y, unsigned int rgb, unsigned int z_order)
+ {
+ if (x >= m_width || y >= m_height || x < 0 || y < 0)
+ {
+ return;
+ }
+ if (z_order > (unsigned int)m_max_zorder)
+ {
+ ASSERT(false);
+ return;
+ }
+ if (z_order == m_max_zorder)
+ {
+ return draw_pixel_on_fb(x, y, rgb);
+ }
+
+ if (z_order > (unsigned int)m_top_zorder)
+ {
+ m_top_zorder = (Z_ORDER_LEVEL)z_order;
+ }
+ if (m_layers[z_order].rect.pt_in_rect(x, y))
+ {
+ c_rect layer_rect = m_layers[z_order].rect;
+ if (m_color_bytes == 4)
+ {
+ ((unsigned int*)(m_layers[z_order].fb))[(x - layer_rect.m_left) + (y - layer_rect.m_top) * layer_rect.width()] = rgb;
+ }
+ else
+ {
+ ((unsigned short*)(m_layers[z_order].fb))[(x - layer_rect.m_left) + (y - layer_rect.m_top) * layer_rect.width()] = GL_RGB_32_to_16(rgb);
+ }
+ }
+
+ if (z_order == m_top_zorder)
+ {
+ return draw_pixel_on_fb(x, y, rgb);
+ }
+ bool be_overlapped = false;
+ for (unsigned int tmp_z_order = Z_ORDER_LEVEL_MAX - 1; tmp_z_order > z_order; tmp_z_order--)
+ {
+ if (m_layers[tmp_z_order].rect.pt_in_rect(x, y))
+ {
+ be_overlapped = true;
+ break;
+ }
+ }
+ if (!be_overlapped)
+ {
+ draw_pixel_on_fb(x, y, rgb);
+ }
+ }
+ virtual void fill_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order)
+ {
+ x0 = (x0 < 0) ? 0 : x0;
+ y0 = (y0 < 0) ? 0 : y0;
+ x1 = (x1 > (m_width - 1)) ? (m_width - 1) : x1;
+ y1 = (y1 > (m_height - 1)) ? (m_height - 1) : y1;
+ if (z_order == m_max_zorder)
+ {
+ return fill_rect_on_fb(x0, y0, x1, y1, rgb);
+ }
+ if (z_order == m_top_zorder)
+ {
+ int x, y;
+ c_rect layer_rect = m_layers[z_order].rect;
+ unsigned int rgb_16 = GL_RGB_32_to_16(rgb);
+ for (y = y0; y <= y1; y++)
+ {
+ for (x = x0; x <= x1; x++)
+ {
+ if (layer_rect.pt_in_rect(x, y))
+ {
+ if (m_color_bytes == 4)
+ {
+ ((unsigned int*)m_layers[z_order].fb)[(y - layer_rect.m_top) * layer_rect.width() + (x - layer_rect.m_left)] = rgb;
+ }
+ else
+ {
+ ((unsigned short*)m_layers[z_order].fb)[(y - layer_rect.m_top) * layer_rect.width() + (x - layer_rect.m_left)] = rgb_16;
+ }
+ }
+ }
+ }
+ return fill_rect_on_fb(x0, y0, x1, y1, rgb);
+ }
+ for (; y0 <= y1; y0++)
+ {
+ draw_hline(x0, x1, y0, rgb, z_order);
+ }
+ }
+ void draw_hline(int x0, int x1, int y, unsigned int rgb, unsigned int z_order)
+ {
+ for (; x0 <= x1; x0++)
+ {
+ draw_pixel(x0, y, rgb, z_order);
+ }
+ }
+ void draw_vline(int x, int y0, int y1, unsigned int rgb, unsigned int z_order)
+ {
+ for (; y0 <= y1; y0++)
+ {
+ draw_pixel(x, y0, rgb, z_order);
+ }
+ }
+ void draw_line(int x1, int y1, int x2, int y2, unsigned int rgb, unsigned int z_order)
+ {
+ int dx, dy, x, y, e;
+ (x1 > x2) ? (dx = x1 - x2) : (dx = x2 - x1);
+ (y1 > y2) ? (dy = y1 - y2) : (dy = y2 - y1);
+ if (((dx > dy) && (x1 > x2)) || ((dx <= dy) && (y1 > y2)))
+ {
+ x = x2; y = y2;
+ x2 = x1; y2 = y1;
+ x1 = x; y1 = y;
+ }
+ x = x1; y = y1;
+ if (dx > dy)
+ {
+ e = dy - dx / 2;
+ for (; x1 <= x2; ++x1, e += dy)
+ {
+ draw_pixel(x1, y1, rgb, z_order);
+ if (e > 0) { e -= dx; (y > y2) ? --y1 : ++y1; }
+ }
+ }
+ else
+ {
+ e = dx - dy / 2;
+ for (; y1 <= y2; ++y1, e += dx)
+ {
+ draw_pixel(x1, y1, rgb, z_order);
+ if (e > 0) { e -= dy; (x > x2) ? --x1 : ++x1; }
+ }
+ }
+ }
+ void draw_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order, unsigned int size = 1)
+ {
+ for (unsigned int offset = 0; offset < size; offset++)
+ {
+ draw_hline(x0 + offset, x1 - offset, y0 + offset, rgb, z_order);
+ draw_hline(x0 + offset, x1 - offset, y1 - offset, rgb, z_order);
+ draw_vline(x0 + offset, y0 + offset, y1 - offset, rgb, z_order);
+ draw_vline(x1 - offset, y0 + offset, y1 - offset, rgb, z_order);
+ }
+ }
+ void draw_rect(c_rect rect, unsigned int rgb, unsigned int size, unsigned int z_order)
+ {
+ draw_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, rgb, z_order, size);
+ }
+ void fill_rect(c_rect rect, unsigned int rgb, unsigned int z_order)
+ {
+ fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, rgb, z_order);
+ }
+ int flush_screen(int left, int top, int right, int bottom)
+ {
+ if (left < 0 || left >= m_width || right < 0 || right >= m_width ||
+ top < 0 || top >= m_height || bottom < 0 || bottom >= m_height)
+ {
+ ASSERT(false);
+ }
+ if (!m_is_active || (0 == m_phy_fb) || (0 == m_fb))
+ {
+ return -1;
+ }
+ int display_width = m_display->get_width();
+ int display_height = m_display->get_height();
+ left = (left >= display_width) ? (display_width - 1) : left;
+ right = (right >= display_width) ? (display_width - 1) : right;
+ top = (top >= display_height) ? (display_height - 1) : top;
+ bottom = (bottom >= display_height) ? (display_height - 1) : bottom;
+ for (int y = top; y < bottom; y++)
+ {
+ void* s_addr = (char*)m_fb + ((y * m_width + left) * m_color_bytes);
+ void* d_addr = (char*)m_phy_fb + ((y * display_width + left) * m_color_bytes);
+ memcpy(d_addr, s_addr, (right - left) * m_color_bytes);
+ }
+ *m_phy_write_index = *m_phy_write_index + 1;
+ return 0;
+ }
+ bool is_active() { return m_is_active; }
+ c_display* get_display() { return m_display; }
+ int show_layer(c_rect& rect, unsigned int z_order)
+ {
+ ASSERT(z_order >= Z_ORDER_LEVEL_0 && z_order < Z_ORDER_LEVEL_MAX);
+ c_rect layer_rect = m_layers[z_order].rect;
+ ASSERT(rect.m_left >= layer_rect.m_left && rect.m_right <= layer_rect.m_right &&
+ rect.m_top >= layer_rect.m_top && rect.m_bottom <= layer_rect.m_bottom);
+ void* fb = m_layers[z_order].fb;
+ int width = layer_rect.width();
+ for (int y = rect.m_top; y <= rect.m_bottom; y++)
+ {
+ for (int x = rect.m_left; x <= rect.m_right; x++)
+ {
+ unsigned int rgb = (m_color_bytes == 4) ? ((unsigned int*)fb)[(x - layer_rect.m_left) + (y - layer_rect.m_top) * width] : GL_RGB_16_to_32(((unsigned short*)fb)[(x - layer_rect.m_left) + (y - layer_rect.m_top) * width]);
+ draw_pixel_on_fb(x, y, rgb);
+ }
+ }
+ return 0;
+ }
+ void set_active(bool flag) { m_is_active = flag; }
+protected:
+ virtual void fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb)
+ {
+ int display_width = m_display->get_width();
+ int display_height = m_display->get_height();
+ if (m_color_bytes == 4)
+ {
+ int x;
+ unsigned int* fb, * phy_fb;
+ for (; y0 <= y1; y0++)
+ {
+ x = x0;
+ fb = m_fb ? &((unsigned int*)m_fb)[y0 * m_width + x] : 0;
+ phy_fb = &((unsigned int*)m_phy_fb)[y0 * display_width + x];
+ *m_phy_write_index = *m_phy_write_index + 1;
+ for (; x <= x1; x++)
+ {
+ if (fb)
+ {
+ *fb++ = rgb;
+ }
+ if (m_is_active && (x < display_width) && (y0 < display_height))
+ {
+ *phy_fb++ = rgb;
+ }
+ }
+ }
+ }
+ else if (m_color_bytes == 2)
+ {
+ int x;
+ unsigned short* fb, * phy_fb;
+ rgb = GL_RGB_32_to_16(rgb);
+ for (; y0 <= y1; y0++)
+ {
+ x = x0;
+ fb = m_fb ? &((unsigned short*)m_fb)[y0 * m_width + x] : 0;
+ phy_fb = &((unsigned short*)m_phy_fb)[y0 * display_width + x];
+ *m_phy_write_index = *m_phy_write_index + 1;
+ for (; x <= x1; x++)
+ {
+ if (fb)
+ {
+ *fb++ = rgb;
+ }
+ if (m_is_active && (x < display_width) && (y0 < display_height))
+ {
+ *phy_fb++ = rgb;
+ }
+ }
+ }
+ }
+ }
+ virtual void draw_pixel_on_fb(int x, int y, unsigned int rgb)
+ {
+ if (m_fb)
+ {
+ (m_color_bytes == 4) ? ((unsigned int*)m_fb)[y * m_width + x] = rgb : ((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb);
+ }
+ if (m_is_active && (x < m_display->get_width()) && (y < m_display->get_height()))
+ {
+ if (m_color_bytes == 4)
+ {
+ ((unsigned int*)m_phy_fb)[y * (m_display->get_width()) + x] = rgb;
+ }
+ else
+ {
+ ((unsigned short*)m_phy_fb)[y * (m_display->get_width()) + x] = GL_RGB_32_to_16(rgb);
+ }
+ *m_phy_write_index = *m_phy_write_index + 1;
+ }
+ }
+ void attach_display(c_display* display)
+ {
+ ASSERT(display);
+ m_display = display;
+ m_phy_fb = display->m_phy_fb;
+ m_phy_write_index = &display->m_phy_write_index;
+ }
+ void set_surface(Z_ORDER_LEVEL max_z_order, c_rect layer_rect)
+ {
+ m_max_zorder = max_z_order;
+ if (m_display && (m_display->m_surface_cnt > 1))
+ {
+ m_fb = calloc(m_width * m_height, m_color_bytes);
+ }
+ for (int i = Z_ORDER_LEVEL_0; i < m_max_zorder; i++)
+ {//Top layber fb always be 0
+ ASSERT(m_layers[i].fb = calloc(layer_rect.width() * layer_rect.height(), m_color_bytes));
+ m_layers[i].rect = layer_rect;
+ }
+ }
+ int m_width; //in pixels
+ int m_height; //in pixels
+ int m_color_bytes; //16 bits, 32 bits only
+ void* m_fb; //frame buffer you could see
+ c_layer m_layers[Z_ORDER_LEVEL_MAX];//all graphic layers
+ bool m_is_active; //active flag
+ Z_ORDER_LEVEL m_max_zorder; //the highest graphic layer the surface will have
+ Z_ORDER_LEVEL m_top_zorder; //the current highest graphic layer the surface have
+ void* m_phy_fb; //physical framebufer
+ int* m_phy_write_index;
+ c_display* m_display;
+};
+class c_surface_no_fb : public c_surface {//No physical framebuffer, render with external graphic interface
+ friend class c_display;
+public:
+ c_surface_no_fb(unsigned int width, unsigned int height, unsigned int color_bytes, struct EXTERNAL_GFX_OP* gfx_op, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0, c_rect overlpa_rect = c_rect()) : c_surface(width, height, color_bytes, max_zorder, overlpa_rect), m_gfx_op(gfx_op) {}
+protected:
+ virtual void fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb)
+ {
+ if (!m_gfx_op)
+ {
+ return;
+ }
+ if (m_gfx_op->fill_rect)
+ {
+ return m_gfx_op->fill_rect(x0, y0, x1, y1, rgb);
+ }
+ if (m_gfx_op->draw_pixel && m_is_active)
+ {
+ for (int y = y0; y <= y1; y++)
+ {
+ for (int x = x0; x <= x1; x++)
+ {
+ m_gfx_op->draw_pixel(x, y, rgb);
+ }
+ }
+ }
+ if (!m_fb) { return; }
+ if (m_color_bytes == 4)
+ {
+ unsigned int* fb;
+ for (int y = y0; y <= y1; y++)
+ {
+ fb = &((unsigned int*)m_fb)[y0 * m_width + x0];
+ for (int x = x0; x <= x1; x++)
+ {
+ *fb++ = rgb;
+ }
+ }
+ }
+ else if (m_color_bytes == 2)
+ {
+ unsigned short* fb;
+ rgb = GL_RGB_32_to_16(rgb);
+ for (int y = y0; y <= y1; y++)
+ {
+ fb = &((unsigned short*)m_fb)[y0 * m_width + x0];
+ for (int x = x0; x <= x1; x++)
+ {
+ *fb++ = rgb;
+ }
+ }
+ }
+ }
+ virtual void draw_pixel_on_fb(int x, int y, unsigned int rgb)
+ {
+ if (m_gfx_op && m_gfx_op->draw_pixel && m_is_active)
+ {
+ m_gfx_op->draw_pixel(x, y, rgb);
+ }
+ if (!m_fb) { return; }
+ if (m_color_bytes == 4)
+ {
+ ((unsigned int*)m_fb)[y * m_width + x] = rgb;
+ }
+ else if (m_color_bytes == 2)
+ {
+ ((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb);
+ }
+ }
+ struct EXTERNAL_GFX_OP* m_gfx_op;//Rendering by external method
+};
+inline c_display::c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, EXTERNAL_GFX_OP* gfx_op) : m_width(display_width), m_height(display_height), m_color_bytes(color_bytes), m_phy_fb(phy_fb), m_phy_read_index(0), m_phy_write_index(0), m_surface_cnt(surface_cnt), m_surface_index(0)
+{
+ ASSERT(color_bytes == 2 || color_bytes == 4);
+ ASSERT(m_surface_cnt <= SURFACE_CNT_MAX);
+ memset(m_surface_group, 0, sizeof(m_surface_group));
+
+ for (int i = 0; i < m_surface_cnt; i++)
+ {
+ m_surface_group[i] = (phy_fb) ? new c_surface(surface_width, surface_height, color_bytes) : new c_surface_no_fb(surface_width, surface_height, color_bytes, gfx_op);
+ m_surface_group[i]->attach_display(this);
+ }
+}
+inline c_display::c_display(void* phy_fb, int display_width, int display_height, c_surface* surface) : m_width(display_width), m_height(display_height), m_phy_fb(phy_fb), m_phy_read_index(0), m_phy_write_index(0), m_surface_cnt(1), m_surface_index(0)
+{
+ m_color_bytes = surface->m_color_bytes;
+ surface->m_is_active = true;
+ (m_surface_group[0] = surface)->attach_display(this);
+}
+inline c_surface* c_display::alloc_surface(Z_ORDER_LEVEL max_zorder, c_rect layer_rect)
+{
+ ASSERT(max_zorder < Z_ORDER_LEVEL_MAX && m_surface_index < m_surface_cnt);
+ (layer_rect == c_rect()) ? m_surface_group[m_surface_index]->set_surface(max_zorder, c_rect(0, 0, m_width - 1, m_height - 1)) : m_surface_group[m_surface_index]->set_surface(max_zorder, layer_rect);
+ return m_surface_group[m_surface_index++];
+}
+inline int c_display::swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset)
+{
+ int surface_width = s0->get_width();
+ int surface_height = s0->get_height();
+ if (offset < 0 || offset > surface_width || y0 < 0 || y0 >= surface_height ||
+ y1 < 0 || y1 >= surface_height || x0 < 0 || x0 >= surface_width || x1 < 0 || x1 >= surface_width)
+ {
+ ASSERT(false);
+ return -1;
+ }
+ int width = (x1 - x0 + 1);
+ if (width < 0 || width > surface_width || width < offset)
+ {
+ ASSERT(false);
+ return -1;
+ }
+ x0 = (x0 >= m_width) ? (m_width - 1) : x0;
+ x1 = (x1 >= m_width) ? (m_width - 1) : x1;
+ y0 = (y0 >= m_height) ? (m_height - 1) : y0;
+ y1 = (y1 >= m_height) ? (m_height - 1) : y1;
+ if (m_phy_fb)
+ {
+ for (int y = y0; y <= y1; y++)
+ {
+ //Left surface
+ char* addr_s = ((char*)(s0->m_fb) + (y * (s0->get_width()) + x0 + offset) * m_color_bytes);
+ char* addr_d = ((char*)(m_phy_fb)+(y * m_width + x0) * m_color_bytes);
+ memcpy(addr_d, addr_s, (width - offset) * m_color_bytes);
+ //Right surface
+ addr_s = ((char*)(s1->m_fb) + (y * (s1->get_width()) + x0) * m_color_bytes);
+ addr_d = ((char*)(m_phy_fb)+(y * m_width + x0 + (width - offset)) * m_color_bytes);
+ memcpy(addr_d, addr_s, offset * m_color_bytes);
+ }
+ }
+ else if (m_color_bytes == 4)
+ {
+ void(*draw_pixel)(int x, int y, unsigned int rgb) = ((c_surface_no_fb*)s0)->m_gfx_op->draw_pixel;
+ for (int y = y0; y <= y1; y++)
+ {
+ //Left surface
+ for (int x = x0; x <= (x1 - offset); x++)
+ {
+ draw_pixel(x, y, ((unsigned int*)s0->m_fb)[y * m_width + x + offset]);
+ }
+ //Right surface
+ for (int x = x1 - offset; x <= x1; x++)
+ {
+ draw_pixel(x, y, ((unsigned int*)s1->m_fb)[y * m_width + x + offset - x1 + x0]);
+ }
+ }
+ }
+ else if (m_color_bytes == 2)
+ {
+ void(*draw_pixel)(int x, int y, unsigned int rgb) = ((c_surface_no_fb*)s0)->m_gfx_op->draw_pixel;
+ for (int y = y0; y <= y1; y++)
+ {
+ //Left surface
+ for (int x = x0; x <= (x1 - offset); x++)
+ {
+ draw_pixel(x, y, GL_RGB_16_to_32(((unsigned short*)s0->m_fb)[y * m_width + x + offset]));
+ }
+ //Right surface
+ for (int x = x1 - offset; x <= x1; x++)
+ {
+ draw_pixel(x, y, GL_RGB_16_to_32(((unsigned short*)s1->m_fb)[y * m_width + x + offset - x1 + x0]));
+ }
+ }
+ }
+ m_phy_write_index++;
+ return 0;
+}
+#include
+#include
+#define VALUE_STR_LEN 16
+class c_surface;
+class c_font_operator
+{
+public:
+ virtual void draw_string(c_surface* surface, int z_order, const void* string, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color) = 0;
+ virtual void draw_string_in_rect(c_surface* surface, int z_order, const void* string, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT) = 0;
+ virtual void draw_value(c_surface* surface, int z_order, int value, int dot_position, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color) = 0;
+ virtual void draw_value_in_rect(c_surface* surface, int z_order, int value, int dot_position, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT) = 0;
+ virtual int get_str_size(const void* string, const void* font, int& width, int& height) = 0;
+ void get_string_pos(const void* string, const void* font, c_rect rect, unsigned int align_type, int& x, int& y)
+ {
+ int x_size, y_size;
+ get_str_size(string, font, x_size, y_size);
+ int height = rect.m_bottom - rect.m_top + 1;
+ int width = rect.m_right - rect.m_left + 1;
+ x = y = 0;
+ switch (align_type & ALIGN_HMASK)
+ {
+ case ALIGN_HCENTER:
+ //m_text_org_x=0
+ if (width > x_size)
+ {
+ x = (width - x_size) / 2;
+ }
+ break;
+ case ALIGN_LEFT:
+ x = 0;
+ break;
+ case ALIGN_RIGHT:
+ //m_text_org_x=0
+ if (width > x_size)
+ {
+ x = width - x_size;
+ }
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ switch (align_type & ALIGN_VMASK)
+ {
+ case ALIGN_VCENTER:
+ //m_text_org_y=0
+ if (height > y_size)
+ {
+ y = (height - y_size) / 2;
+ }
+ break;
+ case ALIGN_TOP:
+ y = 0;
+ break;
+ case ALIGN_BOTTOM:
+ //m_text_org_y=0
+ if (height > y_size)
+ {
+ y = height - y_size;
+ }
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
+};
+class c_lattice_font_op : public c_font_operator
+{
+public:
+ void draw_string(c_surface* surface, int z_order, const void* string, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color)
+ {
+ const char* s = (const char*)string;
+ if (0 == s)
+ {
+ return;
+ }
+ int offset = 0;
+ unsigned int utf8_code;
+ while (*s)
+ {
+ s += get_utf8_code(s, utf8_code);
+ offset += draw_single_char(surface, z_order, utf8_code, (x + offset), y, (const LATTICE_FONT_INFO*)font, font_color, bg_color);
+ }
+ }
+ void draw_string_in_rect(c_surface* surface, int z_order, const void* string, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)
+ {
+ const char* s = (const char*)string;
+ if (0 == s)
+ {
+ return;
+ }
+ int x, y;
+ get_string_pos(s, (const LATTICE_FONT_INFO*)font, rect, align_type, x, y);
+ draw_string(surface, z_order, string, rect.m_left + x, rect.m_top + y, font, font_color, bg_color);
+ }
+ void draw_value(c_surface* surface, int z_order, int value, int dot_position, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color)
+ {
+ char buf[VALUE_STR_LEN];
+ value_2_string(value, dot_position, buf, VALUE_STR_LEN);
+ draw_string(surface, z_order, buf, x, y, (const LATTICE_FONT_INFO*)font, font_color, bg_color);
+ }
+ void draw_value_in_rect(c_surface* surface, int z_order, int value, int dot_position, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)
+ {
+ char buf[VALUE_STR_LEN];
+ value_2_string(value, dot_position, buf, VALUE_STR_LEN);
+ draw_string_in_rect(surface, z_order, buf, rect, (const LATTICE_FONT_INFO*)font, font_color, bg_color, align_type);
+ }
+ int get_str_size(const void *string, const void* font, int& width, int& height)
+ {
+ const char* s = (const char*)string;
+ if (0 == s || 0 == font)
+ {
+ width = height = 0;
+ return -1;
+ }
+ int lattice_width = 0;
+ unsigned int utf8_code;
+ int utf8_bytes;
+ while (*s)
+ {
+ utf8_bytes = get_utf8_code(s, utf8_code);
+ const LATTICE* p_lattice = get_lattice((const LATTICE_FONT_INFO*)font, utf8_code);
+ lattice_width += p_lattice ? p_lattice->width : ((const LATTICE_FONT_INFO*)font)->height;
+ s += utf8_bytes;
+ }
+ width = lattice_width;
+ height = ((const LATTICE_FONT_INFO*)font)->height;
+ return 0;
+ }
+private:
+ void value_2_string(int value, int dot_position, char* buf, int len)
+ {
+ memset(buf, 0, len);
+ switch (dot_position)
+ {
+ case 0:
+ sprintf(buf, "%d", value);
+ break;
+ case 1:
+ sprintf(buf, "%.1f", value * 1.0 / 10);
+ break;
+ case 2:
+ sprintf(buf, "%.2f", value * 1.0 / 100);
+ break;
+ case 3:
+ sprintf(buf, "%.3f", value * 1.0 / 1000);
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+ }
+ int draw_single_char(c_surface* surface, int z_order, unsigned int utf8_code, int x, int y, const LATTICE_FONT_INFO* font, unsigned int font_color, unsigned int bg_color)
+ {
+ unsigned int error_color = 0xFFFFFFFF;
+ if (font)
+ {
+ const LATTICE* p_lattice = get_lattice(font, utf8_code);
+ if (p_lattice)
+ {
+ draw_lattice(surface, z_order, x, y, p_lattice->width, font->height, p_lattice->pixel_buffer, font_color, bg_color);
+ return p_lattice->width;
+ }
+ }
+ else
+ {
+ error_color = GL_RGB(255, 0, 0);
+ }
+ //lattice/font not found, draw "X"
+ int len = 16;
+ for (int y_ = 0; y_ < len; y_++)
+ {
+ for (int x_ = 0; x_ < len; x_++)
+ {
+ int diff = (x_ - y_);
+ int sum = (x_ + y_);
+ (diff == 0 || diff == -1 || diff == 1 || sum == len || sum == (len - 1) || sum == (len + 1)) ?
+ surface->draw_pixel((x + x_), (y + y_), error_color, z_order) : surface->draw_pixel((x + x_), (y + y_), 0, z_order);
+ }
+ }
+ return len;
+ }
+ void draw_lattice(c_surface* surface, int z_order, int x, int y, int width, int height, const unsigned char* p_data, unsigned int font_color, unsigned int bg_color)
+ {
+ unsigned int r, g, b, rgb;
+ unsigned char blk_value = *p_data++;
+ unsigned char blk_cnt = *p_data++;
+ b = (GL_RGB_B(font_color) * blk_value + GL_RGB_B(bg_color) * (255 - blk_value)) >> 8;
+ g = (GL_RGB_G(font_color) * blk_value + GL_RGB_G(bg_color) * (255 - blk_value)) >> 8;
+ r = (GL_RGB_R(font_color) * blk_value + GL_RGB_R(bg_color) * (255 - blk_value)) >> 8;
+ rgb = GL_RGB(r, g, b);
+ for (int y_ = 0; y_ < height; y_++)
+ {
+ for (int x_ = 0; x_ < width; x_++)
+ {
+ ASSERT(blk_cnt);
+ if (0x00 == blk_value)
+ {
+ if (GL_ARGB_A(bg_color))
+ {
+ surface->draw_pixel(x + x_, y + y_, bg_color, z_order);
+ }
+ }
+ else
+ {
+ surface->draw_pixel((x + x_), (y + y_), rgb, z_order);
+ }
+ if (--blk_cnt == 0)
+ {//reload new block
+ blk_value = *p_data++;
+ blk_cnt = *p_data++;
+ b = (GL_RGB_B(font_color) * blk_value + GL_RGB_B(bg_color) * (255 - blk_value)) >> 8;
+ g = (GL_RGB_G(font_color) * blk_value + GL_RGB_G(bg_color) * (255 - blk_value)) >> 8;
+ r = (GL_RGB_R(font_color) * blk_value + GL_RGB_R(bg_color) * (255 - blk_value)) >> 8;
+ rgb = GL_RGB(r, g, b);
+ }
+ }
+ }
+ }
+
+ const LATTICE* get_lattice(const LATTICE_FONT_INFO* font, unsigned int utf8_code)
+ {
+ int first = 0;
+ int last = font->count - 1;
+ int middle = (first + last) / 2;
+ while (first <= last)
+ {
+ if (font->lattice_array[middle].utf8_code < utf8_code)
+ first = middle + 1;
+ else if (font->lattice_array[middle].utf8_code == utf8_code)
+ {
+ return &font->lattice_array[middle];
+ }
+ else
+ {
+ last = middle - 1;
+ }
+ middle = (first + last) / 2;
+ }
+ return 0;
+ }
+
+ static int get_utf8_code(const char* s, unsigned int& output_utf8_code)
+ {
+ static unsigned char s_utf8_length_table[256] =
+ {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1
+ };
+ unsigned char* us = (unsigned char*)s;
+ int utf8_bytes = s_utf8_length_table[*us];
+ switch (utf8_bytes)
+ {
+ case 1:
+ output_utf8_code = *us;
+ break;
+ case 2:
+ output_utf8_code = (*us << 8) | (*(us + 1));
+ break;
+ case 3:
+ output_utf8_code = (*us << 16) | ((*(us + 1)) << 8) | *(us + 2);
+ break;
+ case 4:
+ output_utf8_code = (*us << 24) | ((*(us + 1)) << 16) | (*(us + 2) << 8) | *(us + 3);
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+ return utf8_bytes;
+ }
+};
+class c_word
+{
+public:
+ static void draw_string(c_surface* surface, int z_order, const void* string, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color)//string: char or wchar_t
+ {
+ fontOperator->draw_string(surface, z_order, string, x, y, font, font_color, bg_color);
+ }
+ static void draw_string_in_rect(c_surface* surface, int z_order, const void* string, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)//string: char or wchar_t
+ {
+ fontOperator->draw_string_in_rect(surface, z_order, string, rect, font, font_color, bg_color, align_type);
+ }
+ static void draw_value_in_rect(c_surface* surface, int z_order, int value, int dot_position, c_rect rect, const void* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)
+ {
+ fontOperator->draw_value_in_rect(surface, z_order, value, dot_position, rect, font, font_color, bg_color, align_type);
+ }
+ static void draw_value(c_surface* surface, int z_order, int value, int dot_position, int x, int y, const void* font, unsigned int font_color, unsigned int bg_color)
+ {
+ fontOperator->draw_value(surface, z_order, value, dot_position, x, y, font, font_color, bg_color);
+ }
+
+ static int get_str_size(const void* string, const void* font, int& width, int& height)
+ {
+ return fontOperator->get_str_size(string, font, width, height);
+ }
+ static c_font_operator* fontOperator;
+};
+#define DEFAULT_MASK_COLOR 0xFF080408
+class c_surface;
+class c_image_operator
+{
+public:
+ virtual void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, unsigned int mask_rgb = DEFAULT_MASK_COLOR) = 0;
+ virtual void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, int src_x, int src_y, int width, int height, unsigned int mask_rgb = DEFAULT_MASK_COLOR) = 0;
+};
+class c_bitmap_operator : public c_image_operator
+{
+public:
+ virtual void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, unsigned int mask_rgb = DEFAULT_MASK_COLOR)
+ {
+ ASSERT(image_info);
+ BITMAP_INFO* pBitmap = (BITMAP_INFO*)image_info;
+ unsigned short* lower_fb_16 = 0;
+ unsigned int* lower_fb_32 = 0;
+ int lower_fb_width = 0;
+ c_rect lower_fb_rect;
+ if (z_order >= Z_ORDER_LEVEL_1)
+ {
+ lower_fb_16 = (unsigned short*)surface->m_layers[z_order - 1].fb;
+ lower_fb_32 = (unsigned int*)surface->m_layers[z_order - 1].fb;
+ lower_fb_rect = surface->m_layers[z_order - 1].rect;
+ lower_fb_width = lower_fb_rect.width();
+ }
+ unsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb);
+ int xsize = pBitmap->width;
+ int ysize = pBitmap->height;
+ const unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array;
+ int color_bytes = surface->m_color_bytes;
+ for (int y_ = y; y_ < y + ysize; y_++)
+ {
+ for (int x_ = x; x_ < x + xsize; x_++)
+ {
+ unsigned int rgb = *pData++;
+ if (mask_rgb_16 == rgb)
+ {
+ if (lower_fb_rect.pt_in_rect(x_, y_))
+ {//show lower layer
+ surface->draw_pixel(x_, y_, (color_bytes == 4) ? lower_fb_32[(y_ - lower_fb_rect.m_top) * lower_fb_width + (x_ - lower_fb_rect.m_left)] : GL_RGB_16_to_32(lower_fb_16[(y_ - lower_fb_rect.m_top) * lower_fb_width + (x_ - lower_fb_rect.m_left)]), z_order);
+ }
+ }
+ else
+ {
+ surface->draw_pixel(x_, y_, GL_RGB_16_to_32(rgb), z_order);
+ }
+ }
+ }
+ }
+ virtual void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, int src_x, int src_y, int width, int height, unsigned int mask_rgb = DEFAULT_MASK_COLOR)
+ {
+ ASSERT(image_info);
+ BITMAP_INFO* pBitmap = (BITMAP_INFO*)image_info;
+ if (0 == pBitmap || (src_x + width > pBitmap->width) || (src_y + height > pBitmap->height))
+ {
+ return;
+ }
+ unsigned short* lower_fb_16 = 0;
+ unsigned int* lower_fb_32 = 0;
+ int lower_fb_width = 0;
+ c_rect lower_fb_rect;
+ if (z_order >= Z_ORDER_LEVEL_1)
+ {
+ lower_fb_16 = (unsigned short*)surface->m_layers[z_order - 1].fb;
+ lower_fb_32 = (unsigned int*)surface->m_layers[z_order - 1].fb;
+ lower_fb_rect = surface->m_layers[z_order - 1].rect;
+ lower_fb_width = lower_fb_rect.width();
+ }
+ unsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb);
+ const unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array;
+ int color_bytes = surface->m_color_bytes;
+ for (int y_ = 0; y_ < height; y_++)
+ {
+ const unsigned short* p = &pData[src_x + (src_y + y_) * pBitmap->width];
+ for (int x_ = 0; x_ < width; x_++)
+ {
+ unsigned int rgb = *p++;
+ if (mask_rgb_16 == rgb)
+ {
+ if (lower_fb_rect.pt_in_rect(x + x_, y + y_))
+ {//show lower layer
+ surface->draw_pixel(x + x_, y + y_, (color_bytes == 4) ? lower_fb_32[(y + y_ - lower_fb_rect.m_top) * lower_fb_width + x + x_ - lower_fb_rect.m_left] : GL_RGB_16_to_32(lower_fb_16[(y + y_ - lower_fb_rect.m_top) * lower_fb_width + x + x_ - lower_fb_rect.m_left]), z_order);
+ }
+ }
+ else
+ {
+ surface->draw_pixel(x + x_, y + y_, GL_RGB_16_to_32(rgb), z_order);
+ }
+ }
+ }
+ }
+};
+class c_image
+{
+public:
+ static void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, unsigned int mask_rgb = DEFAULT_MASK_COLOR)
+ {
+ image_operator->draw_image(surface, z_order, image_info, x, y, mask_rgb);
+ }
+ static void draw_image(c_surface* surface, int z_order, const void* image_info, int x, int y, int src_x, int src_y, int width, int height, unsigned int mask_rgb = DEFAULT_MASK_COLOR)
+ {
+ image_operator->draw_image(surface, z_order, image_info, x, y, src_x, src_y, width, height, mask_rgb);
+ }
+
+ static c_image_operator* image_operator;
+};
+class c_wnd;
+class c_surface;
+typedef enum
+{
+ ATTR_VISIBLE = 0x40000000L,
+ ATTR_FOCUS = 0x20000000L,
+ ATTR_PRIORITY = 0x10000000L// Handle touch action at high priority
+}WND_ATTRIBUTION;
+typedef enum
+{
+ STATUS_NORMAL,
+ STATUS_PUSHED,
+ STATUS_FOCUSED,
+ STATUS_DISABLED
+}WND_STATUS;
+typedef enum
+{
+ NAV_FORWARD,
+ NAV_BACKWARD,
+ NAV_ENTER
+}NAVIGATION_KEY;
+typedef enum
+{
+ TOUCH_DOWN,
+ TOUCH_UP
+}TOUCH_ACTION;
+typedef struct struct_wnd_tree
+{
+ c_wnd* p_wnd;//window instance
+ unsigned int resource_id;//ID
+ const char* str;//caption
+ short x;//position x
+ short y;//position y
+ short width;
+ short height;
+ struct struct_wnd_tree* p_child_tree;//sub tree
+}WND_TREE;
+typedef void (c_wnd::*WND_CALLBACK)(int, int);
+class c_wnd
+{
+public:
+ c_wnd() : m_status(STATUS_NORMAL), m_attr((WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS)), m_parent(0), m_top_child(0), m_prev_sibling(0), m_next_sibling(0),
+ m_str(0), m_font_color(0), m_bg_color(0), m_id(0), m_z_order(Z_ORDER_LEVEL_0), m_focus_child(0), m_surface(0) {};
+ virtual ~c_wnd() {};
+ virtual int connect(c_wnd *parent, unsigned short resource_id, const char* str,
+ short x, short y, short width, short height, WND_TREE* p_child_tree = 0)
+ {
+ if (0 == resource_id)
+ {
+ ASSERT(false);
+ return -1;
+ }
+ m_id = resource_id;
+ set_str(str);
+ m_parent = parent;
+ m_status = STATUS_NORMAL;
+ if (parent)
+ {
+ m_z_order = parent->m_z_order;
+ m_surface = parent->m_surface;
+ }
+ if (0 == m_surface)
+ {
+ ASSERT(false);
+ return -2;
+ }
+ /* (cs.x = x * 1024 / 768) for 1027*768=>800*600 quickly*/
+ m_wnd_rect.m_left = x;
+ m_wnd_rect.m_top = y;
+ m_wnd_rect.m_right = (x + width - 1);
+ m_wnd_rect.m_bottom = (y + height - 1);
+ pre_create_wnd();
+ if (0 != parent)
+ {
+ parent->add_child_2_tail(this);
+ }
+ if (load_child_wnd(p_child_tree) >= 0)
+ {
+ on_init_children();
+ }
+ return 0;
+ }
+ void disconnect()
+ {
+ if (0 == m_id)
+ {
+ return;
+ }
+ if (0 != m_top_child)
+ {
+ c_wnd* child = m_top_child;
+ c_wnd* next_child = 0;
+ while (child)
+ {
+ next_child = child->m_next_sibling;
+ child->disconnect();
+ child = next_child;
+ }
+ }
+ if (0 != m_parent)
+ {
+ m_parent->unlink_child(this);
+ }
+ m_focus_child = 0;
+ m_id = 0;
+ }
+ virtual void on_init_children() {}
+ virtual void on_paint() {}
+ virtual void show_window()
+ {
+ if (ATTR_VISIBLE == (m_attr & ATTR_VISIBLE))
+ {
+ on_paint();
+ c_wnd* child = m_top_child;
+ if (0 != child)
+ {
+ while (child)
+ {
+ child->show_window();
+ child = child->m_next_sibling;
+ }
+ }
+ }
+ }
+ unsigned short get_id() const { return m_id; }
+ int get_z_order() { return m_z_order; }
+ c_wnd* get_wnd_ptr(unsigned short id) const
+ {
+ c_wnd* child = m_top_child;
+ while (child)
+ {
+ if (child->get_id() == id)
+ {
+ break;
+ }
+ child = child->m_next_sibling;
+ }
+ return child;
+ }
+ unsigned int get_attr() const { return m_attr; }
+ void set_str(const char* str) { m_str = str; }
+ void set_attr(WND_ATTRIBUTION attr) { m_attr = attr; }
+ bool is_focus_wnd() const
+ {
+ return ((m_attr & ATTR_VISIBLE) && (m_attr & ATTR_FOCUS)) ? true : false;
+ }
+ void set_font_color(unsigned int color) { m_font_color = color; }
+ unsigned int get_font_color() { return m_font_color; }
+ void set_bg_color(unsigned int color) { m_bg_color = color; }
+ unsigned int get_bg_color() { return m_bg_color; }
+ void set_font_type(const LATTICE_FONT_INFO *font_type) { m_font = font_type; }
+ const void* get_font_type() { return m_font; }
+ void set_wnd_pos(short x, short y, short width, short height)
+ {
+ m_wnd_rect.m_left = x;
+ m_wnd_rect.m_top = y;
+ m_wnd_rect.m_right = x + width - 1;
+ m_wnd_rect.m_bottom = y + height - 1;
+ }
+ void get_wnd_rect(c_rect &rect) const { rect = m_wnd_rect; }
+ void get_screen_rect(c_rect &rect) const
+ {
+ int l = 0;
+ int t = 0;
+ wnd2screen(l, t);
+ rect.set_rect(l, t, m_wnd_rect.width(), m_wnd_rect.height());
+ }
+ c_wnd* set_child_focus(c_wnd *focus_child)
+ {
+ ASSERT(0 != focus_child);
+ ASSERT(focus_child->m_parent == this);
+ c_wnd* old_focus_child = m_focus_child;
+ if (focus_child->is_focus_wnd())
+ {
+ if (focus_child != old_focus_child)
+ {
+ if (old_focus_child)
+ {
+ old_focus_child->on_kill_focus();
+ }
+ m_focus_child = focus_child;
+ m_focus_child->on_focus();
+ }
+ }
+ return m_focus_child;
+ }
+ c_wnd* get_parent() const { return m_parent; }
+ c_wnd* get_last_child() const
+ {
+ if (0 == m_top_child)
+ {
+ return 0;
+ }
+ c_wnd* child = m_top_child;
+ while (child->m_next_sibling)
+ {
+ child = child->m_next_sibling;
+ }
+ return child;
+ }
+ int unlink_child(c_wnd *child)
+ {
+ if ((0 == child)
+ || (this != child->m_parent))
+ {
+ return -1;
+ }
+ if (0 == m_top_child)
+ {
+ return -2;
+ }
+ bool find = false;
+ c_wnd* tmp_child = m_top_child;
+ if (tmp_child == child)
+ {
+ m_top_child = child->m_next_sibling;
+ if (0 != child->m_next_sibling)
+ {
+ child->m_next_sibling->m_prev_sibling = 0;
+ }
+ find = true;
+ }
+ else
+ {
+ while (tmp_child->m_next_sibling)
+ {
+ if (child == tmp_child->m_next_sibling)
+ {
+ tmp_child->m_next_sibling = child->m_next_sibling;
+ if (0 != child->m_next_sibling)
+ {
+ child->m_next_sibling->m_prev_sibling = tmp_child;
+ }
+ find = true;
+ break;
+ }
+ tmp_child = tmp_child->m_next_sibling;
+ }
+ }
+ if (true == find)
+ {
+ if (m_focus_child == child)
+ {
+ m_focus_child = 0;
+ }
+ child->m_next_sibling = 0;
+ child->m_prev_sibling = 0;
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ c_wnd* get_prev_sibling() const { return m_prev_sibling; }
+ c_wnd* get_next_sibling() const { return m_next_sibling; }
+ virtual void on_touch(int x, int y, TOUCH_ACTION action)
+ {
+ x -= m_wnd_rect.m_left;
+ y -= m_wnd_rect.m_top;
+ c_wnd* priority_wnd = 0;
+ c_wnd* tmp_child = m_top_child;
+ while (tmp_child)
+ {
+ if ((tmp_child->m_attr & ATTR_PRIORITY) && (tmp_child->m_attr & ATTR_VISIBLE))
+ {
+ priority_wnd = tmp_child;
+ break;
+ }
+ tmp_child = tmp_child->m_next_sibling;
+ }
+ if (priority_wnd)
+ {
+ return priority_wnd->on_touch(x, y, action);
+ }
+ c_wnd* child = m_top_child;
+ while (child)
+ {
+ if (child->is_focus_wnd())
+ {
+ c_rect rect;
+ child->get_wnd_rect(rect);
+ if (true == rect.pt_in_rect(x, y))
+ {
+ return child->on_touch(x, y, action);
+ }
+ }
+ child = child->m_next_sibling;
+ }
+ }
+ virtual void on_navigate(NAVIGATION_KEY key)
+ {
+ c_wnd* priority_wnd = 0;
+ c_wnd* tmp_child = m_top_child;
+ while (tmp_child)
+ {
+ if ((tmp_child->m_attr & ATTR_PRIORITY) && (tmp_child->m_attr & ATTR_VISIBLE))
+ {
+ priority_wnd = tmp_child;
+ break;
+ }
+ tmp_child = tmp_child->m_next_sibling;
+ }
+ if (priority_wnd)
+ {
+ return priority_wnd->on_navigate(key);
+ }
+ if (!is_focus_wnd())
+ {
+ return;
+ }
+ if (key != NAV_BACKWARD && key != NAV_FORWARD)
+ {
+ if (m_focus_child)
+ {
+ m_focus_child->on_navigate(key);
+ }
+ return;
+ }
+ // Move focus
+ c_wnd* old_focus_wnd = m_focus_child;
+ // No current focus wnd, new one.
+ if (!old_focus_wnd)
+ {
+ c_wnd* child = m_top_child;
+ c_wnd* new_focus_wnd = 0;
+ while (child)
+ {
+ if (child->is_focus_wnd())
+ {
+ new_focus_wnd = child;
+ new_focus_wnd->m_parent->set_child_focus(new_focus_wnd);
+ child = child->m_top_child;
+ continue;
+ }
+ child = child->m_next_sibling;
+ }
+ return;
+ }
+ // Move focus from old wnd to next wnd
+ c_wnd* next_focus_wnd = (key == NAV_FORWARD) ? old_focus_wnd->m_next_sibling : old_focus_wnd->m_prev_sibling;
+ while (next_focus_wnd && (!next_focus_wnd->is_focus_wnd()))
+ {// Search neighbor of old focus wnd
+ next_focus_wnd = (key == NAV_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling;
+ }
+ if (!next_focus_wnd)
+ {// Search whole brother wnd
+ next_focus_wnd = (key == NAV_FORWARD) ? old_focus_wnd->m_parent->m_top_child : old_focus_wnd->m_parent->get_last_child();
+ while (next_focus_wnd && (!next_focus_wnd->is_focus_wnd()))
+ {
+ next_focus_wnd = (key == NAV_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling;
+ }
+ }
+ if (next_focus_wnd)
+ {
+ next_focus_wnd->m_parent->set_child_focus(next_focus_wnd);
+ }
+ }
+ c_surface* get_surface() { return m_surface; }
+ void set_surface(c_surface* surface) { m_surface = surface; }
+protected:
+ virtual void pre_create_wnd() {};
+ void add_child_2_tail(c_wnd *child)
+ {
+ if (0 == child)return;
+ if (child == get_wnd_ptr(child->m_id))return;
+ if (0 == m_top_child)
+ {
+ m_top_child = child;
+ child->m_prev_sibling = 0;
+ child->m_next_sibling = 0;
+ }
+ else
+ {
+ c_wnd* last_child = get_last_child();
+ if (0 == last_child)
+ {
+ ASSERT(false);
+ }
+ last_child->m_next_sibling = child;
+ child->m_prev_sibling = last_child;
+ child->m_next_sibling = 0;
+ }
+ }
+ void wnd2screen(int &x, int &y) const
+ {
+ c_wnd* parent = m_parent;
+ c_rect rect;
+ x += m_wnd_rect.m_left;
+ y += m_wnd_rect.m_top;
+ while (0 != parent)
+ {
+ parent->get_wnd_rect(rect);
+ x += rect.m_left;
+ y += rect.m_top;
+ parent = parent->m_parent;
+ }
+ }
+ int load_child_wnd(WND_TREE *p_child_tree)
+ {
+ if (0 == p_child_tree)
+ {
+ return 0;
+ }
+ int sum = 0;
+ WND_TREE* p_cur = p_child_tree;
+ while (p_cur->p_wnd)
+ {
+ if (0 != p_cur->p_wnd->m_id)
+ {//This wnd has been used! Do not share!
+ ASSERT(false);
+ return -1;
+ }
+ else
+ {
+ p_cur->p_wnd->connect(this, p_cur->resource_id, p_cur->str,
+ p_cur->x, p_cur->y, p_cur->width, p_cur->height, p_cur->p_child_tree);
+ }
+ p_cur++;
+ sum++;
+ }
+ return sum;
+ }
+ void set_active_child(c_wnd* child) { m_focus_child = child; }
+ virtual void on_focus() {};
+ virtual void on_kill_focus() {};
+protected:
+ unsigned short m_id;
+ WND_STATUS m_status;
+ WND_ATTRIBUTION m_attr;
+ c_rect m_wnd_rect; //position relative to parent window.
+ c_wnd* m_parent; //parent window
+ c_wnd* m_top_child; //the first sub window would be navigated
+ c_wnd* m_prev_sibling; //previous brother
+ c_wnd* m_next_sibling; //next brother
+ c_wnd* m_focus_child; //current focused window
+ const char* m_str; //caption
+ const void* m_font; //font face
+ unsigned int m_font_color;
+ unsigned int m_bg_color;
+ int m_z_order; //the graphic level for rendering
+ c_surface* m_surface;
+};
+class c_button : public c_wnd
+{
+public:
+ void set_on_click(WND_CALLBACK on_click) { this->on_click = on_click; }
+protected:
+ virtual void on_paint()
+ {
+ c_rect rect;
+ get_screen_rect(rect);
+ switch (m_status)
+ {
+ case STATUS_NORMAL:
+ m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order);
+ if (m_str)
+ {
+ c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER);
+ }
+ break;
+ case STATUS_FOCUSED:
+ m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order);
+ if (m_str)
+ {
+ c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER);
+ }
+ break;
+ case STATUS_PUSHED:
+ m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order);
+ m_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order);
+ if (m_str)
+ {
+ c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER);
+ }
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+ }
+ virtual void on_focus()
+ {
+ m_status = STATUS_FOCUSED;
+ on_paint();
+ }
+ virtual void on_kill_focus()
+ {
+ m_status = STATUS_NORMAL;
+ on_paint();
+ }
+ virtual void pre_create_wnd()
+ {
+ on_click = 0;
+ m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);
+ m_font = c_theme::get_font(FONT_DEFAULT);
+ m_font_color = c_theme::get_color(COLOR_WND_FONT);
+ }
+ virtual void on_touch(int x, int y, TOUCH_ACTION action)
+ {
+ if (action == TOUCH_DOWN)
+ {
+ m_parent->set_child_focus(this);
+ m_status = STATUS_PUSHED;
+ on_paint();
+ }
+ else
+ {
+ m_status = STATUS_FOCUSED;
+ on_paint();
+ if(on_click)
+ {
+ (m_parent->*(on_click))(m_id, 0);
+ }
+ }
+ }
+ virtual void on_navigate(NAVIGATION_KEY key)
+ {
+ switch (key)
+ {
+ case NAV_ENTER:
+ on_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_DOWN);
+ on_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_UP);
+ break;
+ case NAV_FORWARD:
+ case NAV_BACKWARD:
+ break;
+ }
+ return c_wnd::on_navigate(key);
+ }
+ WND_CALLBACK on_click;
+};
+class c_surface;
+class c_dialog;
+typedef struct
+{
+ c_dialog* dialog;
+ c_surface* surface;
+} DIALOG_ARRAY;
+class c_dialog : public c_wnd
+{
+public:
+ static int open_dialog(c_dialog* p_dlg, bool modal_mode = true)
+ {
+ if (0 == p_dlg)
+ {
+ ASSERT(false);
+ return 0;
+ }
+ c_dialog* cur_dlg = get_the_dialog(p_dlg->get_surface());
+ if (cur_dlg == p_dlg)
+ {
+ return 1;
+ }
+ if (cur_dlg)
+ {
+ cur_dlg->set_attr(WND_ATTRIBUTION(0));
+ }
+ p_dlg->set_attr(modal_mode ? (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_PRIORITY) : (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS));
+ p_dlg->show_window();
+ p_dlg->set_me_the_dialog();
+ return 1;
+ }
+ static int close_dialog(c_surface* surface)
+ {
+ c_dialog* dlg = get_the_dialog(surface);
+ if (0 == dlg)
+ {
+ return 0;
+ }
+ c_rect rc;
+ dlg->get_screen_rect(rc);
+ dlg->set_attr(WND_ATTRIBUTION(0));
+ surface->show_layer(rc, dlg->m_z_order - 1);
+ //clear the dialog
+ for (int i = 0; i < SURFACE_CNT_MAX; i++)
+ {
+ if (ms_the_dialogs[i].surface == surface)
+ {
+ ms_the_dialogs[i].dialog = 0;
+ return 1;
+ }
+ }
+ ASSERT(false);
+ return -1;
+ }
+ static c_dialog* get_the_dialog(c_surface* surface)
+ {
+ for (int i = 0; i < SURFACE_CNT_MAX; i++)
+ {
+ if (ms_the_dialogs[i].surface == surface)
+ {
+ return ms_the_dialogs[i].dialog;
+ }
+ }
+ return 0;
+ }
+protected:
+ virtual void pre_create_wnd()
+ {
+ m_attr = WND_ATTRIBUTION(0);// no focus/visible
+ m_z_order = Z_ORDER_LEVEL_1;
+ m_bg_color = GL_RGB(33, 42, 53);
+ }
+ virtual void on_paint()
+ {
+ c_rect rect;
+ get_screen_rect(rect);
+ m_surface->fill_rect(rect, m_bg_color, m_z_order);
+ if (m_str)
+ {
+ c_word::draw_string(m_surface, m_z_order, m_str, rect.m_left + 35, rect.m_top, c_theme::get_font(FONT_DEFAULT), GL_RGB(255, 255, 255), GL_ARGB(0, 0, 0, 0));
+ }
+ }
+private:
+ int set_me_the_dialog()
+ {
+ c_surface* surface = get_surface();
+ for (int i = 0; i < SURFACE_CNT_MAX; i++)
+ {
+ if (ms_the_dialogs[i].surface == surface)
+ {
+ ms_the_dialogs[i].dialog = this;
+ return 0;
+ }
+ }
+ for (int i = 0; i < SURFACE_CNT_MAX; i++)
+ {
+ if (ms_the_dialogs[i].surface == 0)
+ {
+ ms_the_dialogs[i].dialog = this;
+ ms_the_dialogs[i].surface = surface;
+ return 1;
+ }
+ }
+ ASSERT(false);
+ return -2;
+ }
+ static DIALOG_ARRAY ms_the_dialogs[SURFACE_CNT_MAX];
+};
+#include
+//Changing key width/height will change the width/height of keyboard
+#define KEY_WIDTH 65
+#define KEY_HEIGHT 38
+#define KEYBOARD_WIDTH ((KEY_WIDTH + 2) * 10)
+#define KEYBOARD_HEIGHT ((KEY_HEIGHT + 2) * 4)
+#define NUM_BOARD_WIDTH ((KEY_WIDTH + 2) * 4)
+#define NUM_BOARD_HEIGHT ((KEY_HEIGHT + 2) * 4)
+#define CAPS_WIDTH (KEY_WIDTH * 3 / 2)
+#define DEL_WIDTH (KEY_WIDTH * 3 / 2 + 1)
+#define ESC_WIDTH (KEY_WIDTH * 2 + 2)
+#define SWITCH_WIDTH (KEY_WIDTH * 3 / 2 )
+#define SPACE_WIDTH (KEY_WIDTH * 3 + 2 * 2)
+#define DOT_WIDTH (KEY_WIDTH * 3 / 2 + 3)
+#define ENTER_WIDTH (KEY_WIDTH * 2 + 2)
+#define POS_X(c) ((KEY_WIDTH * c) + (c + 1) * 2)
+#define POS_Y(r) ((KEY_HEIGHT * r) + (r + 1) * 2)
+#define KEYBORAD_CLICK 0x5014
+#define ON_KEYBORAD_UPDATE(func) \
+{MSG_TYPE_WND, KEYBORAD_CLICK, 0, msgCallback(&func)},
+typedef enum
+{
+ STATUS_UPPERCASE,
+ STATUS_LOWERCASE
+}KEYBOARD_STATUS;
+typedef enum
+{
+ STYLE_ALL_BOARD,
+ STYLE_NUM_BOARD
+}KEYBOARD_STYLE;
+typedef enum
+{
+ CLICK_CHAR,
+ CLICK_ENTER,
+ CLICK_ESC
+}CLICK_STATUS;
+extern WND_TREE g_key_board_children[];
+extern WND_TREE g_number_board_children[];
+class c_keyboard: public c_wnd
+{
+public:
+ virtual int connect(c_wnd *user, unsigned short resource_id, KEYBOARD_STYLE style)
+ {
+ c_rect user_rect;
+ user->get_wnd_rect(user_rect);
+ if (style == STYLE_ALL_BOARD)
+ {//Place keyboard at the bottom of user's parent window.
+ c_rect user_parent_rect;
+ user->get_parent()->get_wnd_rect(user_parent_rect);
+ return c_wnd::connect(user, resource_id, 0, (0 - user_rect.m_left), (user_parent_rect.height() - user_rect.m_top - KEYBOARD_HEIGHT - 1), KEYBOARD_WIDTH, KEYBOARD_HEIGHT, g_key_board_children);
+ }
+ else if (style == STYLE_NUM_BOARD)
+ {//Place keyboard below the user window.
+ return c_wnd::connect(user, resource_id, 0, 0, user_rect.height(), NUM_BOARD_WIDTH, NUM_BOARD_HEIGHT, g_number_board_children);
+ }
+ else
+ {
+ ASSERT(false);
+ }
+ return -1;
+ }
+ virtual void on_init_children()
+ {
+ c_wnd* child = m_top_child;
+ if (0 != child)
+ {
+ while (child)
+ {
+ ((c_button*)child)->set_on_click(WND_CALLBACK(&c_keyboard::on_key_clicked));
+ child = child->get_next_sibling();
+ }
+ }
+ }
+ KEYBOARD_STATUS get_cap_status(){return m_cap_status;}
+ char* get_str() { return m_str; }
+ void set_on_click(WND_CALLBACK on_click) { this->on_click = on_click; }
+protected:
+ virtual void pre_create_wnd()
+ {
+ m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);
+ m_cap_status = STATUS_UPPERCASE;
+ memset(m_str, 0, sizeof(m_str));
+ m_str_len = 0;
+ }
+ virtual void on_paint()
+ {
+ c_rect rect;
+ get_screen_rect(rect);
+ m_surface->fill_rect(rect, GL_RGB(0, 0, 0), m_z_order);
+ }
+ void on_key_clicked(int id, int param)
+ {
+ switch (id)
+ {
+ case 0x14:
+ on_caps_clicked(id, param);
+ break;
+ case '\n':
+ on_enter_clicked(id, param);
+ break;
+ case 0x1B:
+ on_esc_clicked(id, param);
+ break;
+ case 0x7F:
+ on_del_clicked(id, param);
+ break;
+ default:
+ on_char_clicked(id, param);
+ break;
+ }
+ }
+ void on_char_clicked(int id, int param)
+ {//id = char ascii code.
+ if (m_str_len >= sizeof(m_str))
+ {
+ return;
+ }
+ if ((id >= '0' && id <= '9') || id == ' ' || id == '.')
+ {
+ goto InputChar;
+ }
+ if (id >= 'A' && id <= 'Z')
+ {
+ if (STATUS_LOWERCASE == m_cap_status)
+ {
+ id += 0x20;
+ }
+ goto InputChar;
+ }
+ ASSERT(false);
+ InputChar:
+ m_str[m_str_len++] = id;
+ (m_parent->*(on_click))(m_id, CLICK_CHAR);
+ }
+ void on_del_clicked(int id, int param)
+ {
+ if (m_str_len <= 0)
+ {
+ return;
+ }
+ m_str[--m_str_len] = 0;
+ (m_parent->*(on_click))(m_id, CLICK_CHAR);
+ }
+ void on_caps_clicked(int id, int param)
+ {
+ m_cap_status = (m_cap_status == STATUS_LOWERCASE) ? STATUS_UPPERCASE : STATUS_LOWERCASE;
+ show_window();
+ }
+ void on_enter_clicked(int id, int param)
+ {
+ memset(m_str, 0, sizeof(m_str));
+ (m_parent->*(on_click))(m_id, CLICK_ENTER);
+ }
+ void on_esc_clicked(int id, int param)
+ {
+ memset(m_str, 0, sizeof(m_str));
+ (m_parent->*(on_click))(m_id, CLICK_ESC);
+ }
+private:
+ char m_str[32];
+ int m_str_len;
+ KEYBOARD_STATUS m_cap_status;
+ WND_CALLBACK on_click;
+};
+class c_keyboard_button : public c_button
+{
+protected:
+ virtual void on_paint()
+ {
+ c_rect rect;
+ get_screen_rect(rect);
+ switch (m_status)
+ {
+ case STATUS_NORMAL:
+ m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order);
+ break;
+ case STATUS_FOCUSED:
+ m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order);
+ break;
+ case STATUS_PUSHED:
+ m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order);
+ m_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order);
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+ if (m_id == 0x14)
+ {
+ return c_word::draw_string_in_rect(m_surface, m_z_order, "Caps", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr);
+ }
+ else if (m_id == 0x1B)
+ {
+ return c_word::draw_string_in_rect(m_surface, m_z_order, "Esc", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr);
+ }
+ else if (m_id == ' ')
+ {
+ return c_word::draw_string_in_rect(m_surface, m_z_order, "Space", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr);
+ }
+ else if (m_id == '\n')
+ {
+ return c_word::draw_string_in_rect(m_surface, m_z_order, "Enter", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr);
+ }
+ else if (m_id == '.')
+ {
+ return c_word::draw_string_in_rect(m_surface, m_z_order, ".", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr);
+ }
+ else if (m_id == 0x7F)
+ {
+ return c_word::draw_string_in_rect(m_surface, m_z_order, "Back", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr);
+ }
+ else if (m_id == 0x90)
+ {
+ return c_word::draw_string_in_rect(m_surface, m_z_order, "?123", rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr);
+ }
+ char letter[] = { 0, 0 };
+ if (m_id >= 'A' && m_id <= 'Z')
+ {
+ letter[0] = (((c_keyboard*)m_parent)->get_cap_status() == STATUS_UPPERCASE) ? m_id : (m_id + 0x20);
+ }
+ else if (m_id >= '0' && m_id <= '9')
+ {
+ letter[0] = (char)m_id;
+ }
+ c_word::draw_string_in_rect(m_surface, m_z_order, letter, rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), m_attr);
+ }
+};
+#include
+#define MAX_EDIT_STRLEN 32
+#define IDD_KEY_BOARD 0x1
+class c_edit : public c_wnd
+{
+ friend class c_keyboard;
+public:
+ const char* get_text(){return m_str;}
+ void set_text(const char* str)
+ {
+ if (str != 0 && strlen(str) < sizeof(m_str))
+ {
+ strcpy(m_str, str);
+ }
+ }
+ void set_keyboard_style(KEYBOARD_STYLE kb_sytle) { m_kb_style = kb_sytle; }
+
+protected:
+ virtual void pre_create_wnd()
+ {
+ m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);
+ m_kb_style = STYLE_ALL_BOARD;
+ m_font = c_theme::get_font(FONT_DEFAULT);
+ m_font_color = c_theme::get_color(COLOR_WND_FONT);
+ memset(m_str_input, 0, sizeof(m_str_input));
+ memset(m_str, 0, sizeof(m_str));
+ set_text(c_wnd::m_str);
+ }
+ virtual void on_paint()
+ {
+ c_rect rect, kb_rect;
+ get_screen_rect(rect);
+ s_keyboard.get_screen_rect(kb_rect);
+ switch (m_status)
+ {
+ case STATUS_NORMAL:
+ if (m_z_order > m_parent->get_z_order())
+ {
+ s_keyboard.disconnect();
+ m_z_order = m_parent->get_z_order();
+ m_surface->show_layer(kb_rect, m_z_order);
+ m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);
+ }
+ m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order);
+ c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER);
+ break;
+ case STATUS_FOCUSED:
+ if (m_z_order > m_parent->get_z_order())
+ {
+ s_keyboard.disconnect();
+ m_z_order = m_parent->get_z_order();
+ m_surface->show_layer(kb_rect, m_z_order);
+ m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);
+ }
+ m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order);
+ c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER);
+ break;
+ case STATUS_PUSHED:
+ if (m_z_order == m_parent->get_z_order())
+ {
+ m_z_order++;
+ m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_PRIORITY);
+ show_keyboard();
+ }
+ m_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, c_theme::get_color(COLOR_WND_PUSHED), m_parent->get_z_order());
+ m_surface->draw_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, c_theme::get_color(COLOR_WND_BORDER), m_parent->get_z_order(), 2);
+ strlen(m_str_input) ? c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str_input, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER) :
+ c_word::draw_string_in_rect(m_surface, m_parent->get_z_order(), m_str, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_PUSHED), ALIGN_HCENTER | ALIGN_VCENTER);
+ break;
+ default:
+ ASSERT(false);
+ }
+ }
+ virtual void on_focus()
+ {
+ m_status = STATUS_FOCUSED;
+ on_paint();
+ }
+ virtual void on_kill_focus()
+ {
+ m_status = STATUS_NORMAL;
+ on_paint();
+ }
+ virtual void on_navigate(NAVIGATION_KEY key)
+ {
+ switch (key)
+ {
+ case NAV_ENTER:
+ (m_status == STATUS_PUSHED) ? s_keyboard.on_navigate(key) : (on_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_DOWN), on_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_UP));
+ return;
+ case NAV_BACKWARD:
+ case NAV_FORWARD:
+ return (m_status == STATUS_PUSHED) ? s_keyboard.on_navigate(key) : c_wnd::on_navigate(key);
+ }
+ }
+ virtual void on_touch(int x, int y, TOUCH_ACTION action)
+ {
+ (action == TOUCH_DOWN) ? on_touch_down(x, y) : on_touch_up(x, y);
+ }
+ void on_key_board_click(int id, int param)
+ {
+ switch (param)
+ {
+ case CLICK_CHAR:
+ strcpy(m_str_input, s_keyboard.get_str());
+ on_paint();
+ break;
+ case CLICK_ENTER:
+ if (strlen(m_str_input))
+ {
+ memcpy(m_str, m_str_input, sizeof(m_str_input));
+ }
+ m_status = STATUS_FOCUSED;
+ on_paint();
+ break;
+ case CLICK_ESC:
+ memset(m_str_input, 0, sizeof(m_str_input));
+ m_status = STATUS_FOCUSED;
+ on_paint();
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+ }
+private:
+ void show_keyboard()
+ {
+ s_keyboard.connect(this, IDD_KEY_BOARD, m_kb_style);
+ s_keyboard.set_on_click(WND_CALLBACK(&c_edit::on_key_board_click));
+ s_keyboard.show_window();
+ }
+ void on_touch_down(int x, int y)
+ {
+ c_rect kb_rect_relate_2_edit_parent;
+ s_keyboard.get_wnd_rect(kb_rect_relate_2_edit_parent);
+ kb_rect_relate_2_edit_parent.m_left += m_wnd_rect.m_left;
+ kb_rect_relate_2_edit_parent.m_right += m_wnd_rect.m_left;
+ kb_rect_relate_2_edit_parent.m_top += m_wnd_rect.m_top;
+ kb_rect_relate_2_edit_parent.m_bottom += m_wnd_rect.m_top;
+ if (m_wnd_rect.pt_in_rect(x, y))
+ {//click edit box
+ if (STATUS_NORMAL == m_status)
+ {
+ m_parent->set_child_focus(this);
+ }
+ }
+ else if (kb_rect_relate_2_edit_parent.pt_in_rect(x, y))
+ {//click key board
+ c_wnd::on_touch(x, y, TOUCH_DOWN);
+ }
+ else
+ {
+ if (STATUS_PUSHED == m_status)
+ {
+ m_status = STATUS_FOCUSED;
+ on_paint();
+ }
+ }
+ }
+ void on_touch_up(int x, int y)
+ {
+ if (STATUS_FOCUSED == m_status)
+ {
+ m_status = STATUS_PUSHED;
+ on_paint();
+ }
+ else if (STATUS_PUSHED == m_status)
+ {
+ if (m_wnd_rect.pt_in_rect(x, y))
+ {//click edit box
+ m_status = STATUS_FOCUSED;
+ on_paint();
+ }
+ else
+ {
+ c_wnd::on_touch(x, y, TOUCH_UP);
+ }
+ }
+ }
+ static c_keyboard s_keyboard;
+ KEYBOARD_STYLE m_kb_style;
+ char m_str_input[MAX_EDIT_STRLEN];
+ char m_str[MAX_EDIT_STRLEN];
+};
+class c_label : public c_wnd
+{
+public:
+ virtual void on_paint()
+ {
+ c_rect rect;
+ unsigned int bg_color = m_bg_color ? m_bg_color : m_parent->get_bg_color();
+ get_screen_rect(rect);
+ if (m_str)
+ {
+ m_surface->fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, bg_color, m_z_order);
+ c_word::draw_string_in_rect(m_surface, m_z_order, m_str, rect, m_font, m_font_color, bg_color, ALIGN_LEFT | ALIGN_VCENTER);
+ }
+ }
+protected:
+ virtual void pre_create_wnd()
+ {
+ m_attr = ATTR_VISIBLE;
+ m_font_color = c_theme::get_color(COLOR_WND_FONT);
+ m_font = c_theme::get_font(FONT_DEFAULT);
+ }
+};
+#include
+#define MAX_ITEM_NUM 4
+#define ITEM_HEIGHT 45
+class c_list_box : public c_wnd
+{
+public:
+ void set_on_change(WND_CALLBACK on_change) { this->on_change = on_change; }
+ short get_item_count() { return m_item_total; }
+ int add_item(char* str)
+ {
+ if (m_item_total >= MAX_ITEM_NUM)
+ {
+ ASSERT(false);
+ return -1;
+ }
+ m_item_array[m_item_total++] = str;
+ update_list_size();
+ return 0;
+ }
+ void clear_item()
+ {
+ m_selected_item = m_item_total = 0;
+ memset(m_item_array, 0, sizeof(m_item_array));
+ update_list_size();
+ }
+ void select_item(short index)
+ {
+ if (index < 0 || index >= m_item_total)
+ {
+ ASSERT(false);
+ }
+ m_selected_item = index;
+ }
+
+protected:
+ virtual void pre_create_wnd()
+ {
+ m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);
+ memset(m_item_array, 0, sizeof(m_item_array));
+ m_item_total = 0;
+ m_selected_item = 0;
+ m_font = c_theme::get_font(FONT_DEFAULT);
+ m_font_color = c_theme::get_color(COLOR_WND_FONT);
+ }
+ virtual void on_paint()
+ {
+ c_rect rect;
+ get_screen_rect(rect);
+ switch (m_status)
+ {
+ case STATUS_NORMAL:
+ if (m_z_order > m_parent->get_z_order())
+ {
+ m_z_order = m_parent->get_z_order();
+ m_surface->show_layer(m_list_screen_rect, m_z_order);
+ m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);
+ }
+ m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order);
+ c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER);
+ break;
+ case STATUS_FOCUSED:
+ if (m_z_order > m_parent->get_z_order())
+ {
+ m_z_order = m_parent->get_z_order();
+ m_surface->show_layer(m_list_screen_rect, m_z_order);
+ m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS);
+ }
+ m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order);
+ c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER);
+ break;
+ case STATUS_PUSHED:
+ m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_PUSHED), m_z_order);
+ m_surface->draw_rect(rect, c_theme::get_color(COLOR_WND_BORDER), 2, m_z_order);
+ c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[m_selected_item], rect, m_font, GL_RGB(2, 124, 165), GL_ARGB(0, 0, 0, 0), ALIGN_HCENTER | ALIGN_VCENTER);
+ //draw list
+ if (m_item_total > 0)
+ {
+ if (m_z_order == m_parent->get_z_order())
+ {
+ m_z_order++;
+ }
+ m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_PRIORITY);
+ show_list();
+ }
+ break;
+ default:
+ ASSERT(false);
+ }
+ }
+ virtual void on_focus()
+ {
+ m_status = STATUS_FOCUSED;
+ on_paint();
+ }
+ virtual void on_kill_focus()
+ {
+ m_status = STATUS_NORMAL;
+ on_paint();
+ }
+ virtual void on_navigate(NAVIGATION_KEY key)
+ {
+ switch (key)
+ {
+ case NAV_ENTER:
+ on_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_DOWN);
+ on_touch(m_wnd_rect.m_left, m_wnd_rect.m_top, TOUCH_UP);
+ return;
+ case NAV_BACKWARD:
+ if (m_status != STATUS_PUSHED)
+ {
+ return c_wnd::on_navigate(key);
+ }
+ m_selected_item = (m_selected_item > 0) ? (m_selected_item - 1) : m_selected_item;
+ return show_list();
+ case NAV_FORWARD:
+ if (m_status != STATUS_PUSHED)
+ {
+ return c_wnd::on_navigate(key);
+ }
+ m_selected_item = (m_selected_item < (m_item_total - 1)) ? (m_selected_item + 1) : m_selected_item;
+ return show_list();
+ }
+ }
+ virtual void on_touch(int x, int y, TOUCH_ACTION action)
+ {
+ (action == TOUCH_DOWN) ? on_touch_down(x, y) : on_touch_up(x, y);
+ }
+
+private:
+ void update_list_size()
+ {
+ m_list_wnd_rect = m_wnd_rect;
+ m_list_wnd_rect.m_top = m_wnd_rect.m_bottom + 1;
+ m_list_wnd_rect.m_bottom = m_list_wnd_rect.m_top + m_item_total * ITEM_HEIGHT;
+ get_screen_rect(m_list_screen_rect);
+ m_list_screen_rect.m_top = m_list_screen_rect.m_bottom + 1;
+ m_list_screen_rect.m_bottom = m_list_screen_rect.m_top + m_item_total * ITEM_HEIGHT;
+ }
+ void show_list()
+ {
+ //draw all items
+ c_rect tmp_rect;
+ for (int i = 0; i < m_item_total; i++)
+ {
+ tmp_rect.m_left = m_list_screen_rect.m_left;
+ tmp_rect.m_right = m_list_screen_rect.m_right;
+ tmp_rect.m_top = m_list_screen_rect.m_top + i * ITEM_HEIGHT;
+ tmp_rect.m_bottom = tmp_rect.m_top + ITEM_HEIGHT;
+ if (m_selected_item == i)
+ {
+ m_surface->fill_rect(tmp_rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order);
+ c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[i], tmp_rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_FOCUS), ALIGN_HCENTER | ALIGN_VCENTER);
+ }
+ else
+ {
+ m_surface->fill_rect(tmp_rect, GL_RGB(17, 17, 17), m_z_order);
+ c_word::draw_string_in_rect(m_surface, m_z_order, m_item_array[i], tmp_rect, m_font, m_font_color, GL_RGB(17, 17, 17), ALIGN_HCENTER | ALIGN_VCENTER);
+ }
+ }
+ }
+ void on_touch_down(int x, int y)
+ {
+ if (m_wnd_rect.pt_in_rect(x, y))
+ {//click base
+ if (STATUS_NORMAL == m_status)
+ {
+ m_parent->set_child_focus(this);
+ }
+ }
+ else if (m_list_wnd_rect.pt_in_rect(x, y))
+ {//click extend list
+ c_wnd::on_touch(x, y, TOUCH_DOWN);
+ }
+ else
+ {
+ if (STATUS_PUSHED == m_status)
+ {
+ m_status = STATUS_FOCUSED;
+ on_paint();
+ if(on_change)
+ {
+ (m_parent->*(on_change))(m_id, m_selected_item);
+ }
+ }
+ }
+ }
+ void on_touch_up(int x, int y)
+ {
+ if (STATUS_FOCUSED == m_status)
+ {
+ m_status = STATUS_PUSHED;
+ on_paint();
+ }
+ else if (STATUS_PUSHED == m_status)
+ {
+ if (m_wnd_rect.pt_in_rect(x, y))
+ {//click base
+ m_status = STATUS_FOCUSED;
+ on_paint();
+ }
+ else if (m_list_wnd_rect.pt_in_rect(x, y))
+ {//click extend list
+ m_status = STATUS_FOCUSED;
+ select_item((y - m_list_wnd_rect.m_top) / ITEM_HEIGHT);
+ on_paint();
+ if(on_change)
+ {
+ (m_parent->*(on_change))(m_id, m_selected_item);
+ }
+ }
+ else
+ {
+ c_wnd::on_touch(x, y, TOUCH_UP);
+ }
+ }
+ }
+ short m_selected_item;
+ short m_item_total;
+ char* m_item_array[MAX_ITEM_NUM];
+ c_rect m_list_wnd_rect; //rect relative to parent wnd.
+ c_rect m_list_screen_rect; //rect relative to physical screen(frame buffer)
+ WND_CALLBACK on_change;
+};
+#include
+#define MAX_PAGES 5
+class c_gesture;
+class c_slide_group : public c_wnd {
+public:
+ inline c_slide_group();
+ int set_active_slide(int index, bool is_redraw = true)
+ {
+ if (index >= MAX_PAGES || index < 0)
+ {
+ return -1;
+ }
+ if (0 == m_slides[index])
+ {
+ return -2;
+ }
+ m_active_slide_index = index;
+ for (int i = 0; i < MAX_PAGES; i++)
+ {
+ if (m_slides[i] == 0)
+ {
+ continue;
+ }
+ if (i == index)
+ {
+ m_slides[i]->get_surface()->set_active(true);
+ add_child_2_tail(m_slides[i]);
+ if (is_redraw)
+ {
+ c_rect rc;
+ get_screen_rect(rc);
+ m_slides[i]->get_surface()->flush_screen(rc.m_left, rc.m_top, rc.m_right, rc.m_bottom);
+ }
+ }
+ else
+ {
+ m_slides[i]->get_surface()->set_active(false);
+ }
+ }
+ return 0;
+ }
+ c_wnd* get_slide(int index){return m_slides[index];}
+ c_wnd* get_active_slide(){return m_slides[m_active_slide_index];}
+ int get_active_slide_index(){return m_active_slide_index;}
+ int add_slide(c_wnd* slide, unsigned short resource_id, short x, short y, short width, short height, WND_TREE* p_child_tree = 0, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0)
+ {
+ if (0 == slide)
+ {
+ return -1;
+ }
+ c_surface* old_surface = get_surface();
+ c_surface* new_surface = old_surface->get_display()->alloc_surface(max_zorder);
+ new_surface->set_active(false);
+ set_surface(new_surface);
+ slide->connect(this, resource_id, 0, x, y, width, height, p_child_tree);
+ set_surface(old_surface);
+ int i = 0;
+ while (i < MAX_PAGES)
+ {
+ if (m_slides[i] == slide)
+ {//slide has lived
+ ASSERT(false);
+ return -2;
+ }
+ i++;
+ }
+ //new slide
+ i = 0;
+ while (i < MAX_PAGES)
+ {
+ if (m_slides[i] == 0)
+ {
+ m_slides[i] = slide;
+ slide->show_window();
+ return 0;
+ }
+ i++;
+ }
+ //no more slide can be add
+ ASSERT(false);
+ return -3;
+ }
+ void disabel_all_slide()
+ {
+ for (int i = 0; i < MAX_PAGES; i++)
+ {
+ if (m_slides[i])
+ {
+ m_slides[i]->get_surface()->set_active(false);
+ }
+ }
+ }
+ inline virtual void on_touch(int x, int y, TOUCH_ACTION action);
+ virtual void on_navigate(NAVIGATION_KEY key)
+ {
+ if (m_slides[m_active_slide_index])
+ {
+ m_slides[m_active_slide_index]->on_navigate(key);
+ }
+ }
+protected:
+ c_wnd* m_slides[MAX_PAGES];
+ int m_active_slide_index;
+ c_gesture* m_gesture;
+};
+//#define SWIPE_STEP 300//for arm
+#define SWIPE_STEP 10//for PC & ANDROID
+#define MOVE_THRESHOLD 10
+typedef enum {
+ TOUCH_MOVE,
+ TOUCH_IDLE
+}TOUCH_STATE;
+class c_slide_group;
+class c_gesture {
+public:
+ c_gesture(c_slide_group* group)
+ {
+ m_slide_group = group;
+ m_state = TOUCH_IDLE;
+ m_down_x = m_down_y = m_move_x = m_move_y = 0;
+ }
+ bool handle_swipe(int x, int y, TOUCH_ACTION action)
+ {
+ if (action == TOUCH_DOWN)//MOUSE_LBUTTONDOWN
+ {
+ if (m_state == TOUCH_IDLE)
+ {
+ m_state = TOUCH_MOVE;
+ m_move_x = m_down_x = x;
+ return true;
+ }
+ else//TOUCH_MOVE
+ {
+ return on_move(x);
+ }
+ }
+ else if (action == TOUCH_UP)//MOUSE_LBUTTONUP
+ {
+ if (m_state == TOUCH_MOVE)
+ {
+ m_state = TOUCH_IDLE;
+ return on_swipe(x);
+ }
+ else
+ {
+ return false;
+ //ASSERT(false);
+ }
+ }
+ return true;
+ }
+private:
+ bool on_move(int x)
+ {
+ if (m_slide_group == 0)
+ {
+ return true;
+ }
+ if (abs(x - m_move_x) < MOVE_THRESHOLD)
+ {
+ return false;
+ }
+ m_slide_group->disabel_all_slide();
+ m_move_x = x;
+ if ((m_move_x - m_down_x) > 0)
+ {
+ move_right();
+ }
+ else
+ {
+ move_left();
+ }
+ return false;
+ }
+ bool on_swipe(int x)
+ {
+ if (m_slide_group == 0)
+ {
+ return true;
+ }
+ if ((m_down_x == m_move_x) && (abs(x - m_down_x) < MOVE_THRESHOLD))
+ {
+ return true;
+ }
+ m_slide_group->disabel_all_slide();
+ int page = -1;
+ m_move_x = x;
+ if ((m_move_x - m_down_x) > 0)
+ {
+ page = swipe_right();
+ }
+ else
+ {
+ page = swipe_left();
+ }
+ if (page >= 0)
+ {
+ m_slide_group->set_active_slide(page);
+ }
+ else
+ {
+ m_slide_group->set_active_slide(m_slide_group->get_active_slide_index(), false);
+ }
+ return false;
+ }
+ int swipe_left()
+ {
+ if (m_slide_group == 0)
+ {
+ return -1;
+ }
+ int index = m_slide_group->get_active_slide_index();
+ if ((index + 1) >= MAX_PAGES ||
+ m_slide_group->get_slide(index + 1) == 0 ||
+ m_slide_group->get_slide(index) == 0)
+ {
+ return -2;
+ }
+ c_surface* s1 = m_slide_group->get_slide(index + 1)->get_surface();
+ c_surface * s2 = m_slide_group->get_slide(index)->get_surface();
+ if (s1->get_display() != s2->get_display())
+ {
+ return -3;
+ }
+ int step = m_down_x - m_move_x;
+ c_rect rc;
+ m_slide_group->get_screen_rect(rc);
+ while (step < rc.width())
+ {
+ s1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, step);
+ step += SWIPE_STEP;
+ }
+ if (step != rc.width())
+ {
+ s1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, rc.width());
+ }
+ return (index + 1);
+ }
+ int swipe_right()
+ {
+ if (m_slide_group == 0)
+ {
+ return -1;
+ }
+ int index = m_slide_group->get_active_slide_index();
+ if (index <= 0 ||
+ m_slide_group->get_slide(index - 1) == 0 ||
+ m_slide_group->get_slide(index) == 0)
+ {
+ return -2;
+ }
+ c_surface* s1 = m_slide_group->get_slide(index - 1)->get_surface();
+ c_surface * s2 = m_slide_group->get_slide(index)->get_surface();
+ if (s1->get_display() != s2->get_display())
+ {
+ return -3;
+ }
+ c_rect rc;
+ m_slide_group->get_screen_rect(rc);
+ int step = rc.width() - (m_move_x - m_down_x);
+ while (step > 0)
+ {
+ s1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, step);
+ step -= SWIPE_STEP;
+ }
+ if (step != 0)
+ {
+ s1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, 0);
+ }
+ return (index - 1);
+ }
+ void move_left()
+ {
+ int index = m_slide_group->get_active_slide_index();
+ if ((index + 1) >= MAX_PAGES ||
+ m_slide_group->get_slide(index + 1) == 0 ||
+ m_slide_group->get_slide(index) == 0)
+ {
+ return;
+ }
+ c_surface* s1 = m_slide_group->get_slide(index + 1)->get_surface();
+ c_surface * s2 = m_slide_group->get_slide(index)->get_surface();
+ c_rect rc;
+ m_slide_group->get_screen_rect(rc);
+ if (s1->get_display() == s2->get_display())
+ {
+ s1->get_display()->swipe_surface(s2, s1, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, (m_down_x - m_move_x));
+ }
+ }
+ void move_right()
+ {
+ int index = m_slide_group->get_active_slide_index();
+ if (index <= 0 ||
+ m_slide_group->get_slide(index - 1) == 0 ||
+ m_slide_group->get_slide(index) == 0)
+ {
+ return;
+ }
+ c_surface* s1 = m_slide_group->get_slide(index - 1)->get_surface();
+ c_surface * s2 = m_slide_group->get_slide(index)->get_surface();
+ c_rect rc;
+ m_slide_group->get_screen_rect(rc);
+ if (s1->get_display() == s2->get_display())
+ {
+ s1->get_display()->swipe_surface(s1, s2, rc.m_left, rc.m_right, rc.m_top, rc.m_bottom, (rc.width() - (m_move_x - m_down_x)));
+ }
+ }
+ int m_down_x;
+ int m_down_y;
+ int m_move_x;
+ int m_move_y;
+ TOUCH_STATE m_state;
+ c_slide_group* m_slide_group;
+};
+inline c_slide_group::c_slide_group()
+{
+ m_gesture = new c_gesture(this);
+ for (int i = 0; i < MAX_PAGES; i++)
+ {
+ m_slides[i] = 0;
+ }
+ m_active_slide_index = 0;
+}
+inline void c_slide_group::on_touch(int x, int y, TOUCH_ACTION action)
+{
+ x -= m_wnd_rect.m_left;
+ y -= m_wnd_rect.m_top;
+ if (m_gesture->handle_swipe(x, y, action))
+ {
+ if (m_slides[m_active_slide_index])
+ {
+ m_slides[m_active_slide_index]->on_touch(x, y, action);
+ }
+ }
+}
+#define ID_BT_ARROW_UP 0x1111
+#define ID_BT_ARROW_DOWN 0x2222
+class c_spin_box;
+class c_spin_button : public c_button
+{
+ friend class c_spin_box;
+ inline virtual void on_touch(int x, int y, TOUCH_ACTION action);
+ c_spin_box* m_spin_box;
+};
+class c_spin_box : public c_wnd
+{
+ friend class c_spin_button;
+public:
+ short get_value() { return m_value; }
+ void set_value(unsigned short value) { m_value = m_cur_value = value; }
+ void set_max_min(short max, short min) { m_max = max; m_min = min; }
+ void set_step(short step) { m_step = step; }
+ short get_min() { return m_min; }
+ short get_max() { return m_max; }
+ short get_step() { return m_step; }
+ void set_value_digit(short digit) { m_digit = digit; }
+ short get_value_digit() { return m_digit; }
+ void set_on_change(WND_CALLBACK on_change) { this->on_change = on_change; }
+protected:
+ virtual void on_paint()
+ {
+ c_rect rect;
+ get_screen_rect(rect);
+ rect.m_right = rect.m_left + (rect.width() * 2 / 3);
+ m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order);
+ c_word::draw_value_in_rect(m_surface, m_parent->get_z_order(), m_cur_value, m_digit, rect, m_font, m_font_color, c_theme::get_color(COLOR_WND_NORMAL), ALIGN_HCENTER | ALIGN_VCENTER);
+ }
+ virtual void pre_create_wnd()
+ {
+ m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE);
+ m_font = c_theme::get_font(FONT_DEFAULT);
+ m_font_color = c_theme::get_color(COLOR_WND_FONT);
+ m_max = 6;
+ m_min = 1;
+ m_digit = 0;
+ m_step = 1;
+ //link arrow button position.
+ c_rect rect;
+ get_wnd_rect(rect);
+ m_bt_down.m_spin_box = m_bt_up.m_spin_box = this;
+ m_bt_up.connect(m_parent, ID_BT_ARROW_UP, "+", (rect.m_left + rect.width() * 2 / 3), rect.m_top, (rect.width() / 3), (rect.height() / 2));
+ m_bt_down.connect(m_parent, ID_BT_ARROW_DOWN, "-", (rect.m_left + rect.width() * 2 / 3), (rect.m_top + rect.height() / 2), (rect.width() / 3), (rect.height() / 2));
+ }
+ void on_arrow_up_bt_click()
+ {
+ if (m_cur_value + m_step > m_max)
+ {
+ return;
+ }
+ m_cur_value += m_step;
+ if(on_change)
+ {
+ (m_parent->*(on_change))(m_id, m_cur_value);
+ }
+ on_paint();
+ }
+ void on_arrow_down_bt_click()
+ {
+ if (m_cur_value - m_step < m_min)
+ {
+ return;
+ }
+ m_cur_value -= m_step;
+ if(on_change)
+ {
+ (m_parent->*(on_change))(m_id, m_cur_value);
+ }
+ on_paint();
+ }
+ short m_cur_value;
+ short m_value;
+ short m_step;
+ short m_max;
+ short m_min;
+ short m_digit;
+ c_spin_button m_bt_up;
+ c_spin_button m_bt_down;
+ WND_CALLBACK on_change;
+};
+inline void c_spin_button::on_touch(int x, int y, TOUCH_ACTION action)
+{
+ if (action == TOUCH_UP)
+ {
+ (m_id == ID_BT_ARROW_UP) ? m_spin_box->on_arrow_up_bt_click() : m_spin_box->on_arrow_down_bt_click();
+ }
+ c_button::on_touch(x, y, action);
+}
+#define MAX_COL_NUM 30
+#define MAX_ROW_NUM 30
+class c_table: public c_wnd
+{
+public:
+ void set_sheet_align(unsigned int align_type){ m_align_type = align_type;}
+ void set_row_num(unsigned int row_num){ m_row_num = row_num;}
+ void set_col_num(unsigned int col_num){ m_col_num = col_num;}
+ void set_row_height(unsigned int height)
+ {
+ for (unsigned int i = 0; i < m_row_num; i++)
+ {
+ m_row_height[i] = height;
+ }
+ }
+ void set_col_width(unsigned int width)
+ {
+ for (unsigned int i = 0; i < m_col_num; i++)
+ {
+ m_col_width[i] = width;
+ }
+ }
+ int set_row_height(unsigned int index, unsigned int height)
+ {
+ if (m_row_num > index)
+ {
+ m_row_height[index] = height;
+ return index;
+ }
+ return -1;
+ }
+ int set_col_width(unsigned int index, unsigned int width)
+ {
+ if (m_col_num > index)
+ {
+ m_col_width[index] = width;
+ return index;
+ }
+ return -1;
+ }
+ void set_item(int row, int col, char* str, unsigned int color)
+ {
+ draw_item(row, col, str, color);
+ }
+ unsigned int get_row_num(){ return m_row_num;}
+ unsigned int get_col_num(){ return m_col_num;}
+ c_rect get_item_rect(int row, int col)
+ {
+ static c_rect rect;
+ if (row >= MAX_ROW_NUM || col >= MAX_COL_NUM)
+ {
+ return rect;
+ }
+ unsigned int width = 0;
+ unsigned int height = 0;
+ for (int i = 0; i < col; i++)
+ {
+ width += m_col_width[i];
+ }
+ for (int j = 0; j < row; j++)
+ {
+ height += m_row_height[j];
+ }
+ c_rect wRect;
+ get_screen_rect(wRect);
+ rect.m_left = wRect.m_left + width;
+ rect.m_right = rect.m_left + m_col_width[col];
+ if (rect.m_right > wRect.m_right)
+ {
+ rect.m_right = wRect.m_right;
+ }
+ rect.m_top = wRect.m_top + height;
+ rect.m_bottom = rect.m_top + m_row_height[row];
+ if (rect.m_bottom > wRect.m_bottom)
+ {
+ rect.m_bottom = wRect.m_bottom;
+ }
+ return rect;
+ }
+protected:
+ virtual void pre_create_wnd()
+ {
+ m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE);
+ m_font = c_theme::get_font(FONT_DEFAULT);
+ m_font_color = c_theme::get_color(COLOR_WND_FONT);
+ }
+ void draw_item(int row, int col, const char* str, unsigned int color)
+ {
+ c_rect rect = get_item_rect(row, col);
+ m_surface->fill_rect(rect.m_left + 1, rect.m_top + 1, rect.m_right - 1, rect.m_bottom - 1, color, m_z_order);
+ c_word::draw_string_in_rect(m_surface, m_z_order, str, rect, m_font, m_font_color, GL_ARGB(0, 0, 0, 0), m_align_type);
+ }
+ unsigned int m_align_type;
+ unsigned int m_row_num;
+ unsigned int m_col_num;
+ unsigned int m_row_height[MAX_ROW_NUM];
+ unsigned int m_col_width[MAX_COL_NUM];
+};
+#include
+#include
+#define WAVE_BUFFER_LEN 1024
+#define WAVE_READ_CACHE_LEN 8
+#define BUFFER_EMPTY -1111
+#define BUFFER_FULL -2222;
+class c_wave_buffer
+{
+public:
+ c_wave_buffer()
+ {
+ m_head = m_tail = m_min_old = m_max_old =
+ m_min_older = m_max_older = m_last_data = m_read_cache_sum = m_refresh_sequence = 0;
+ memset(m_wave_buf, 0, sizeof(m_wave_buf));
+ memset(m_read_cache_min, 0, sizeof(m_read_cache_min));
+ memset(m_read_cache_mid, 0, sizeof(m_read_cache_mid));
+ memset(m_read_cache_max, 0, sizeof(m_read_cache_max));
+ }
+ int write_wave_data(short data)
+ {
+ if ((m_tail + 1) % WAVE_BUFFER_LEN == m_head)
+ {//full
+ //log_out("wave buf full\n");
+ return BUFFER_FULL;
+ }
+ m_wave_buf[m_tail] = data;
+ m_tail = (m_tail + 1) % WAVE_BUFFER_LEN;
+ return 1;
+ }
+ int read_wave_data_by_frame(short &max, short &min, short frame_len, unsigned int sequence, short offset)
+ {
+ if (m_refresh_sequence != sequence)
+ {
+ m_refresh_sequence = sequence;
+ m_read_cache_sum = 0;
+ }
+ else if (offset < m_read_cache_sum)//(m_refresh_sequence == sequence && offset < m_fb_sum)
+ {
+ max = m_read_cache_max[offset];
+ min = m_read_cache_min[offset];
+ return m_read_cache_mid[offset];
+ }
+ m_read_cache_sum++;
+ ASSERT(m_read_cache_sum <= WAVE_READ_CACHE_LEN);
+ int i, data;
+ int tmp_min = m_last_data;
+ int tmp_max = m_last_data;
+ int mid = (m_min_old + m_max_old) >> 1;
+ i = 0;
+ while (i++ < frame_len)
+ {
+ data = read_data();
+ if (BUFFER_EMPTY == data)
+ {
+ break;
+ }
+ m_last_data = data;
+ if (data < tmp_min) { tmp_min = data; }
+ if (data > tmp_max) { tmp_max = data; }
+ }
+ min = m_read_cache_min[offset] = MIN(m_min_old, MIN(tmp_min, m_min_older));
+ max = m_read_cache_max[offset] = MAX(m_max_old, MAX(tmp_max, m_max_older));
+ m_min_older = m_min_old;
+ m_max_older = m_max_old;
+ m_min_old = tmp_min;
+ m_max_old = tmp_max;
+ return (m_read_cache_mid[offset] = mid);
+ }
+ void reset()
+ {
+ m_head = m_tail;
+ }
+ void clear_data()
+ {
+ m_head = m_tail = 0;
+ memset(m_wave_buf, 0, sizeof(m_wave_buf));
+ }
+ short get_cnt()
+ {
+ return (m_tail >= m_head) ? (m_tail - m_head) : (m_tail - m_head + WAVE_BUFFER_LEN);
+ }
+private:
+ int read_data()
+ {
+ if (m_head == m_tail)
+ {//empty
+ //log_out("wave buf empty\n");
+ return BUFFER_EMPTY;
+ }
+ int ret = m_wave_buf[m_head];
+ m_head = (m_head + 1) % WAVE_BUFFER_LEN;
+ return ret;
+ }
+ short m_wave_buf[WAVE_BUFFER_LEN];
+ short m_head;
+ short m_tail;
+ int m_min_old;
+ int m_max_old;
+ int m_min_older;
+ int m_max_older;
+ int m_last_data;
+ short m_read_cache_min[WAVE_READ_CACHE_LEN];
+ short m_read_cache_mid[WAVE_READ_CACHE_LEN];
+ short m_read_cache_max[WAVE_READ_CACHE_LEN];
+ short m_read_cache_sum;
+ unsigned int m_refresh_sequence;
+};
+#include
+#include
+#define CORRECT(x, high_limit, low_limit) {\
+ x = (x > high_limit) ? high_limit : x;\
+ x = (x < low_limit) ? low_limit : x;\
+}while(0)
+#define WAVE_CURSOR_WIDTH 8
+#define WAVE_LINE_WIDTH 1
+#define WAVE_MARGIN 5
+typedef enum
+{
+ FILL_MODE,
+ SCAN_MODE
+}E_WAVE_DRAW_MODE;
+class c_wave_buffer;
+class c_wave_ctrl : public c_wnd
+{
+public:
+ c_wave_ctrl()
+ {
+ m_wave = 0;
+ m_bg_fb = 0;
+ m_wave_name_font = m_wave_unit_font = 0;
+ m_wave_name = m_wave_unit = 0;
+ m_max_data = 500;
+ m_min_data = 0;
+ m_wave_speed = 1;
+ m_wave_data_rate = 0;
+ m_wave_refresh_rate = 1000;
+ m_frame_len_map_index = 0;
+ m_wave_name_color = m_wave_unit_color = m_wave_color = GL_RGB(255, 0, 0);
+ m_back_color = GL_RGB(0, 0, 0);
+ }
+ virtual void on_init_children()//should be pre_create
+ {
+ c_rect rect;
+ get_screen_rect(rect);
+ m_wave_left = rect.m_left + WAVE_MARGIN;
+ m_wave_right = rect.m_right - WAVE_MARGIN;
+ m_wave_top = rect.m_top + WAVE_MARGIN;
+ m_wave_bottom = rect.m_bottom - WAVE_MARGIN;
+ m_wave_cursor = m_wave_left;
+ m_bg_fb = (unsigned int*)calloc(rect.width() * rect.height(), 4);
+ }
+ virtual void on_paint()
+ {
+ c_rect rect;
+ get_screen_rect(rect);
+ m_surface->fill_rect(rect, m_back_color, m_z_order);
+ //show name
+ c_word::draw_string(m_surface, m_z_order, m_wave_name, m_wave_left + 10, rect.m_top, m_wave_name_font, m_wave_name_color, GL_ARGB(0, 0, 0, 0));
+ //show unit
+ c_word::draw_string(m_surface, m_z_order, m_wave_unit, m_wave_left + 60, rect.m_top, m_wave_unit_font, m_wave_unit_color, GL_ARGB(0, 0, 0, 0));
+ save_background();
+ }
+ void set_wave_name(char* wave_name){ m_wave_name = wave_name;}
+ void set_wave_unit(char* wave_unit){ m_wave_unit = wave_unit;}
+ void set_wave_name_font(const LATTICE_FONT_INFO* wave_name_font_type){ m_wave_name_font = wave_name_font_type;}
+ void set_wave_unit_font(const LATTICE_FONT_INFO* wave_unit_font_type){ m_wave_unit_font = wave_unit_font_type;}
+ void set_wave_name_color(unsigned int wave_name_color){ m_wave_name_color = wave_name_color;}
+ void set_wave_unit_color(unsigned int wave_unit_color){ m_wave_unit_color = wave_unit_color;}
+ void set_wave_color(unsigned int color){ m_wave_color = color;}
+ void set_wave_in_out_rate(unsigned int data_rate, unsigned int refresh_rate)
+ {
+ m_wave_data_rate = data_rate;
+ m_wave_refresh_rate = refresh_rate;
+ int read_times_per_second = m_wave_speed * 1000 / m_wave_refresh_rate;
+ memset(m_frame_len_map, 0, sizeof(m_frame_len_map));
+ for (unsigned int i = 1; i < sizeof(m_frame_len_map) + 1; i++)
+ {
+ m_frame_len_map[i - 1] = data_rate * i / read_times_per_second - data_rate * (i - 1) / read_times_per_second;
+ }
+ m_frame_len_map_index = 0;
+ }
+ void set_wave_speed(unsigned int speed)
+ {
+ m_wave_speed = speed;
+ set_wave_in_out_rate(m_wave_data_rate, m_wave_refresh_rate);
+ }
+ void set_max_min(short max_data, short min_data)
+ {
+ m_max_data = max_data;
+ m_min_data = min_data;
+ }
+ void set_wave(c_wave_buffer* wave){m_wave = wave;}
+ c_wave_buffer* get_wave(){return m_wave;}
+ void clear_data()
+ {
+ if (m_wave == 0)
+ {
+ ASSERT(false);
+ return;
+ }
+ m_wave->clear_data();
+ }
+ bool is_data_enough()
+ {
+ if (m_wave == 0)
+ {
+ ASSERT(false);
+ return false;
+ }
+ return (m_wave->get_cnt() - m_frame_len_map[m_frame_len_map_index] * m_wave_speed);
+ }
+ void refresh_wave(unsigned char frame)
+ {
+ if (m_wave == 0)
+ {
+ ASSERT(false);
+ return;
+ }
+ short max, min, mid;
+ for (short offset = 0; offset < m_wave_speed; offset++)
+ {
+ //get wave value
+ mid = m_wave->read_wave_data_by_frame(max, min,
+ m_frame_len_map[m_frame_len_map_index++],
+ frame, offset);
+ m_frame_len_map_index %= sizeof(m_frame_len_map);
+ //map to wave ctrl
+ int y_min, y_max;
+ if (m_max_data == m_min_data)
+ {
+ ASSERT(false);
+ }
+ y_max = m_wave_bottom + WAVE_LINE_WIDTH - (m_wave_bottom - m_wave_top) * (min - m_min_data) / (m_max_data - m_min_data);
+ y_min = m_wave_bottom - WAVE_LINE_WIDTH - (m_wave_bottom - m_wave_top) * (max - m_min_data) / (m_max_data - m_min_data);
+ mid = m_wave_bottom - (m_wave_bottom - m_wave_top) * (mid - m_min_data) / (m_max_data - m_min_data);
+ CORRECT(y_min, m_wave_bottom, m_wave_top);
+ CORRECT(y_max, m_wave_bottom, m_wave_top);
+ CORRECT(mid, m_wave_bottom, m_wave_top);
+ if (m_wave_cursor > m_wave_right)
+ {
+ m_wave_cursor = m_wave_left;
+ }
+ draw_smooth_vline(y_min, y_max, mid, m_wave_color);
+ restore_background();
+ m_wave_cursor++;
+ }
+ }
+ void clear_wave()
+ {
+ m_surface->fill_rect(m_wave_left, m_wave_top, m_wave_right, m_wave_bottom, m_back_color, m_z_order);
+ m_wave_cursor = m_wave_left;
+ }
+protected:
+ void draw_smooth_vline(int y_min, int y_max, int mid, unsigned int rgb)
+ {
+ int dy = y_max - y_min;
+ short r = GL_RGB_R(rgb);
+ short g = GL_RGB_G(rgb);
+ short b = GL_RGB_B(rgb);
+ int index = (dy >> 1) + 2;
+ int y;
+ m_surface->draw_pixel(m_wave_cursor, mid, rgb, m_z_order);
+ if (dy < 1)
+ {
+ return;
+ }
+ unsigned char cur_r, cur_g, cur_b;
+ unsigned int cur_rgb;
+ for (int i = 1; i <= (dy >> 1) + 1; ++i)
+ {
+ if ((mid + i) <= y_max)
+ {
+ y = mid + i;
+ cur_r = r * (index - i) / index;
+ cur_g = g * (index - i) / index;
+ cur_b = b * (index - i) / index;
+ cur_rgb = GL_RGB(cur_r, cur_g, cur_b);
+ m_surface->draw_pixel(m_wave_cursor, y, cur_rgb, m_z_order);
+ }
+ if ((mid - i) >= y_min)
+ {
+ y = mid - i;
+ cur_r = r * (index - i) / index;
+ cur_g = g * (index - i) / index;
+ cur_b = b * (index - i) / index;
+ cur_rgb = GL_RGB(cur_r, cur_g, cur_b);
+ m_surface->draw_pixel(m_wave_cursor, y, cur_rgb, m_z_order);
+ }
+ }
+ }
+ void restore_background()
+ {
+ int x = m_wave_cursor + WAVE_CURSOR_WIDTH;
+ if (x > m_wave_right)
+ {
+ x -= (m_wave_right - m_wave_left + 1);
+ }
+ c_rect rect;
+ get_screen_rect(rect);
+ register int width = rect.width();
+ register int top = rect.m_top;
+ register int left = rect.m_left;
+ for (int y_pos = (m_wave_top - 1); y_pos <= (m_wave_bottom + 1); y_pos++)
+ {
+ (m_bg_fb) ? m_surface->draw_pixel(x, y_pos, m_bg_fb[(y_pos - top) * width + (x - left)], m_z_order) : m_surface->draw_pixel(x, y_pos, 0, m_z_order);
+ }
+ }
+ void save_background()
+ {
+ if (!m_bg_fb)
+ {
+ return;
+ }
+ c_rect rect;
+ get_screen_rect(rect);
+ register unsigned int* p_des = m_bg_fb;
+ for (int y = rect.m_top; y <= rect.m_bottom; y++)
+ {
+ for (int x = rect.m_left; x <= rect.m_right; x++)
+ {
+ *p_des++ = m_surface->get_pixel(x, y, m_z_order);
+ }
+ }
+ }
+ char* m_wave_name;
+ char* m_wave_unit;
+ const LATTICE_FONT_INFO* m_wave_name_font;
+ const LATTICE_FONT_INFO* m_wave_unit_font;
+ unsigned int m_wave_name_color;
+ unsigned int m_wave_unit_color;
+ unsigned int m_wave_color;
+ unsigned int m_back_color;
+ int m_wave_left;
+ int m_wave_right;
+ int m_wave_top;
+ int m_wave_bottom;
+ short m_max_data;
+ short m_min_data;
+
+private:
+ c_wave_buffer* m_wave;
+ unsigned int* m_bg_fb; //background frame buffer, could be used to draw scale line.
+ int m_wave_cursor;
+ int m_wave_speed; //pixels per refresh
+ unsigned int m_wave_data_rate; //data sample rate
+ unsigned int m_wave_refresh_rate;//refresh cycle in millisecond
+ unsigned char m_frame_len_map[64];
+ unsigned char m_frame_len_map_index;
+};
+#ifdef GUILITE_ON
+c_bitmap_operator the_bitmap_op = c_bitmap_operator();
+c_image_operator* c_image::image_operator = &the_bitmap_op;
+#endif
+
+#ifdef GUILITE_ON
+
+const void* c_theme::s_font_map[FONT_MAX];
+const void* c_theme::s_image_map[IMAGE_MAX];
+unsigned int c_theme::s_color_map[COLOR_MAX];
+
+#endif
+
+#ifdef GUILITE_ON
+
+c_lattice_font_op the_lattice_font_op = c_lattice_font_op();
+c_font_operator* c_word::fontOperator = &the_lattice_font_op;
+
+#endif
+#ifdef GUILITE_ON
+#if (defined __linux__) || (defined __APPLE__)
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#define MAX_TIMER_CNT 10
+#define TIMER_UNIT 50//ms
+static void(*do_assert)(const char* file, int line);
+static void(*do_log_out)(const char* log);
+void register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log))
+{
+ do_assert = my_assert;
+ do_log_out = my_log_out;
+}
+void _assert(const char* file, int line)
+{
+ if(do_assert)
+ {
+ do_assert(file, line);
+ }
+ else
+ {
+ printf("assert@ file:%s, line:%d, error no: %d\n", file, line, errno);
+ }
+}
+void log_out(const char* log)
+{
+ if (do_log_out)
+ {
+ do_log_out(log);
+ }
+ else
+ {
+ printf("%s", log);
+ fflush(stdout);
+ }
+}
+typedef struct _timer_manage
+{
+ struct _timer_info
+ {
+ int state; /* on or off */
+ int interval;
+ int elapse; /* 0~interval */
+ void (* timer_proc) (void* param);
+ void* param;
+ }timer_info[MAX_TIMER_CNT];
+ void (* old_sigfunc)(int);
+ void (* new_sigfunc)(int);
+}_timer_manage_t;
+static struct _timer_manage timer_manage;
+static void* timer_routine(void*)
+{
+ int i;
+ while(true)
+ {
+ for(i = 0; i < MAX_TIMER_CNT; i++)
+ {
+ if(timer_manage.timer_info[i].state == 0)
+ {
+ continue;
+ }
+ timer_manage.timer_info[i].elapse++;
+ if(timer_manage.timer_info[i].elapse == timer_manage.timer_info[i].interval)
+ {
+ timer_manage.timer_info[i].elapse = 0;
+ timer_manage.timer_info[i].timer_proc(timer_manage.timer_info[i].param);
+ }
+ }
+ usleep(1000 * TIMER_UNIT);
+ }
+ return NULL;
+}
+static int init_mul_timer()
+{
+ static bool s_is_init = false;
+ if(s_is_init == true)
+ {
+ return 0;
+ }
+ memset(&timer_manage, 0, sizeof(struct _timer_manage));
+ pthread_t pid;
+ pthread_create(&pid, NULL, timer_routine, NULL);
+ s_is_init = true;
+ return 1;
+}
+static int set_a_timer(int interval, void (* timer_proc)(void* param), void* param)
+{
+ init_mul_timer();
+ int i;
+ if(timer_proc == NULL || interval <= 0)
+ {
+ return (-1);
+ }
+ for(i = 0; i < MAX_TIMER_CNT; i++)
+ {
+ if(timer_manage.timer_info[i].state == 1)
+ {
+ continue;
+ }
+ memset(&timer_manage.timer_info[i], 0, sizeof(timer_manage.timer_info[i]));
+ timer_manage.timer_info[i].timer_proc = timer_proc;
+ timer_manage.timer_info[i].param = param;
+ timer_manage.timer_info[i].interval = interval;
+ timer_manage.timer_info[i].elapse = 0;
+ timer_manage.timer_info[i].state = 1;
+ break;
+ }
+ if(i >= MAX_TIMER_CNT)
+ {
+ ASSERT(false);
+ return (-1);
+ }
+ return (i);
+}
+typedef void (*EXPIRE_ROUTINE)(void* arg);
+EXPIRE_ROUTINE s_expire_function;
+static c_fifo s_real_timer_fifo;
+static void* real_timer_routine(void*)
+{
+ char dummy;
+ while(1)
+ {
+ if(s_real_timer_fifo.read(&dummy, 1) > 0)
+ {
+ if(s_expire_function)s_expire_function(0);
+ }
+ else
+ {
+ ASSERT(false);
+ }
+ }
+ return 0;
+}
+static void expire_real_timer(int sigo)
+{
+ char dummy = 0x33;
+ if(s_real_timer_fifo.write(&dummy, 1) <= 0)
+ {
+ ASSERT(false);
+ }
+}
+void start_real_timer(void (*func)(void* arg))
+{
+ if(NULL == func)
+ {
+ return;
+ }
+ s_expire_function = func;
+ signal(SIGALRM, expire_real_timer);
+ struct itimerval value, ovalue;
+ value.it_value.tv_sec = 0;
+ value.it_value.tv_usec = REAL_TIME_TASK_CYCLE_MS * 1000;
+ value.it_interval.tv_sec = 0;
+ value.it_interval.tv_usec = REAL_TIME_TASK_CYCLE_MS * 1000;
+ setitimer(ITIMER_REAL, &value, &ovalue);
+ static pthread_t s_pid;
+ if(s_pid == 0)
+ {
+ pthread_create(&s_pid, NULL, real_timer_routine, NULL);
+ }
+}
+unsigned int get_cur_thread_id()
+{
+ return (unsigned long)pthread_self();
+}
+void register_timer(int milli_second,void func(void* param), void* param)
+{
+ set_a_timer(milli_second/TIMER_UNIT,func, param);
+}
+long get_time_in_second()
+{
+ return time(NULL); /* + 8*60*60*/
+}
+T_TIME get_time()
+{
+ T_TIME ret = {0};
+ struct tm *fmt;
+ time_t timer;
+ timer = get_time_in_second();
+ fmt = localtime(&timer);
+ ret.year = fmt->tm_year + 1900;
+ ret.month = fmt->tm_mon + 1;
+ ret.day = fmt->tm_mday;
+ ret.hour = fmt->tm_hour;
+ ret.minute = fmt->tm_min;
+ ret.second = fmt->tm_sec;
+ return ret;
+}
+T_TIME second_to_day(long second)
+{
+ T_TIME ret = {0};
+ struct tm *fmt;
+ fmt = localtime(&second);
+ ret.year = fmt->tm_year + 1900;
+ ret.month = fmt->tm_mon + 1;
+ ret.day = fmt->tm_mday;
+ ret.hour = fmt->tm_hour;
+ ret.minute = fmt->tm_min;
+ ret.second = fmt->tm_sec;
+ return ret;
+}
+void create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg)
+{
+ pthread_create((pthread_t*)thread_id, (pthread_attr_t const*)attr, start_routine, arg);
+}
+void thread_sleep(unsigned int milli_seconds)
+{
+ usleep(milli_seconds * 1000);
+}
+typedef struct {
+ unsigned short bfType;
+ unsigned int bfSize;
+ unsigned short bfReserved1;
+ unsigned short bfReserved2;
+ unsigned int bfOffBits;
+}__attribute__((packed))FileHead;
+typedef struct{
+ unsigned int biSize;
+ int biWidth;
+ int biHeight;
+ unsigned short biPlanes;
+ unsigned short biBitCount;
+ unsigned int biCompress;
+ unsigned int biSizeImage;
+ int biXPelsPerMeter;
+ int biYPelsPerMeter;
+ unsigned int biClrUsed;
+ unsigned int biClrImportant;
+ unsigned int biRedMask;
+ unsigned int biGreenMask;
+ unsigned int biBlueMask;
+}__attribute__((packed))Infohead;
+int build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data)
+{
+ FileHead bmp_head;
+ Infohead bmp_info;
+ int size = width * height * 2;
+ //initialize bmp head.
+ bmp_head.bfType = 0x4d42;
+ bmp_head.bfSize = size + sizeof(FileHead) + sizeof(Infohead);
+ bmp_head.bfReserved1 = bmp_head.bfReserved2 = 0;
+ bmp_head.bfOffBits = bmp_head.bfSize - size;
+ //initialize bmp info.
+ bmp_info.biSize = 40;
+ bmp_info.biWidth = width;
+ bmp_info.biHeight = height;
+ bmp_info.biPlanes = 1;
+ bmp_info.biBitCount = 16;
+ bmp_info.biCompress = 3;
+ bmp_info.biSizeImage = size;
+ bmp_info.biXPelsPerMeter = 0;
+ bmp_info.biYPelsPerMeter = 0;
+ bmp_info.biClrUsed = 0;
+ bmp_info.biClrImportant = 0;
+ //RGB565
+ bmp_info.biRedMask = 0xF800;
+ bmp_info.biGreenMask = 0x07E0;
+ bmp_info.biBlueMask = 0x001F;
+ //copy the data
+ FILE *fp;
+ if(!(fp=fopen(filename,"wb")))
+ {
+ return -1;
+ }
+ fwrite(&bmp_head, 1, sizeof(FileHead),fp);
+ fwrite(&bmp_info, 1, sizeof(Infohead),fp);
+ //fwrite(data, 1, size, fp);//top <-> bottom
+ for (int i = (height - 1); i >= 0; --i)
+ {
+ fwrite(&data[i * width * 2], 1, width * 2, fp);
+ }
+
+ fclose(fp);
+ return 0;
+}
+c_fifo::c_fifo()
+{
+ m_head = m_tail = 0;
+ m_read_sem = malloc(sizeof(sem_t));
+ m_write_mutex = malloc(sizeof(pthread_mutex_t));
+
+ sem_init((sem_t*)m_read_sem, 0, 0);
+ pthread_mutex_init((pthread_mutex_t*)m_write_mutex, 0);
+}
+int c_fifo::read(void* buf, int len)
+{
+ unsigned char* pbuf = (unsigned char*)buf;
+ int i = 0;
+ while(i < len)
+ {
+ if (m_tail == m_head)
+ {//empty
+ sem_wait((sem_t*)m_read_sem);
+ continue;
+ }
+ *pbuf++ = m_buf[m_head];
+ m_head = (m_head + 1) % FIFO_BUFFER_LEN;
+ i++;
+ }
+ if(i != len)
+ {
+ ASSERT(false);
+ }
+ return i;
+}
+int c_fifo::write(void* buf, int len)
+{
+ unsigned char* pbuf = (unsigned char*)buf;
+ int i = 0;
+ int tail = m_tail;
+ pthread_mutex_lock((pthread_mutex_t*)m_write_mutex);
+ while(i < len)
+ {
+ if ((m_tail + 1) % FIFO_BUFFER_LEN == m_head)
+ {//full, clear data has been written;
+ m_tail = tail;
+ log_out("Warning: fifo full\n");
+ pthread_mutex_unlock((pthread_mutex_t*)m_write_mutex);
+ return 0;
+ }
+ m_buf[m_tail] = *pbuf++;
+ m_tail = (m_tail + 1) % FIFO_BUFFER_LEN;
+ i++;
+ }
+ pthread_mutex_unlock((pthread_mutex_t*)m_write_mutex);
+ if(i != len)
+ {
+ ASSERT(false);
+ }
+ else
+ {
+ sem_post((sem_t*)m_read_sem);
+ }
+ return i;
+}
+#endif
+#endif
+#ifdef GUILITE_ON
+#if (!defined _WIN32) && (!defined WIN32) && (!defined _WIN64) && (!defined WIN64) && (!defined __linux__) && (!defined __APPLE__)
+
+#include
+
+static void(*do_assert)(const char* file, int line);
+static void(*do_log_out)(const char* log);
+void register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log))
+{
+ do_assert = my_assert;
+ do_log_out = my_log_out;
+}
+
+void _assert(const char* file, int line)
+{
+ if(do_assert)
+ {
+ do_assert(file, line);
+ }
+ while(1);
+}
+
+void log_out(const char* log)
+{
+ if (do_log_out)
+ {
+ do_log_out(log);
+ }
+}
+
+long get_time_in_second()
+{
+ return 0;
+}
+
+T_TIME second_to_day(long second)
+{
+ T_TIME ret = {0};
+ return ret;
+}
+
+T_TIME get_time()
+{
+ T_TIME ret = {0};
+ return ret;
+}
+
+void start_real_timer(void (*func)(void* arg))
+{
+ log_out("Not support now");
+}
+
+void register_timer(int milli_second, void func(void* ptmr, void* parg))
+{
+ log_out("Not support now");
+}
+
+unsigned int get_cur_thread_id()
+{
+ log_out("Not support now");
+ return 0;
+}
+
+void create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg)
+{
+ log_out("Not support now");
+}
+
+extern "C" void delay_ms(unsigned short nms);
+void thread_sleep(unsigned int milli_seconds)
+{//MCU alway implemnet driver code in APP.
+ delay_ms(milli_seconds);
+}
+
+int build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data)
+{
+ log_out("Not support now");
+ return 0;
+}
+
+c_fifo::c_fifo()
+{
+ m_head = m_tail = 0;
+ m_read_sem = m_write_mutex = 0;
+}
+
+int c_fifo::read(void* buf, int len)
+{
+ unsigned char* pbuf = (unsigned char*)buf;
+ int i = 0;
+ while(i < len)
+ {
+ if (m_tail == m_head)
+ {//empty
+ continue;
+ }
+ *pbuf++ = m_buf[m_head];
+ m_head = (m_head + 1) % FIFO_BUFFER_LEN;
+ i++;
+ }
+ if(i != len)
+ {
+ ASSERT(false);
+ }
+ return i;
+}
+
+int c_fifo::write(void* buf, int len)
+{
+ unsigned char* pbuf = (unsigned char*)buf;
+ int i = 0;
+ int tail = m_tail;
+
+ while(i < len)
+ {
+ if ((m_tail + 1) % FIFO_BUFFER_LEN == m_head)
+ {//full, clear data has been written;
+ m_tail = tail;
+ log_out("Warning: fifo full\n");
+ return 0;
+ }
+ m_buf[m_tail] = *pbuf++;
+ m_tail = (m_tail + 1) % FIFO_BUFFER_LEN;
+ i++;
+ }
+
+ if(i != len)
+ {
+ ASSERT(false);
+ }
+ return i;
+}
+
+#endif
+#endif
+#ifdef GUILITE_ON
+#if (defined _WIN32) || (defined WIN32) || (defined _WIN64) || (defined WIN64)
+#include
+#include
+#include
+#include
+#include
+#include
+#define MAX_TIMER_CNT 10
+#define TIMER_UNIT 50//ms
+static void(*do_assert)(const char* file, int line);
+static void(*do_log_out)(const char* log);
+void register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log))
+{
+ do_assert = my_assert;
+ do_log_out = my_log_out;
+}
+void _assert(const char* file, int line)
+{
+ static char s_buf[192];
+ if (do_assert)
+ {
+ do_assert(file, line);
+ }
+ else
+ {
+ memset(s_buf, 0, sizeof(s_buf));
+ sprintf_s(s_buf, sizeof(s_buf), "vvvvvvvvvvvvvvvvvvvvvvvvvvvv\n\nAssert@ file = %s, line = %d\n\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", file, line);
+ OutputDebugStringA(s_buf);
+ printf("%s", s_buf);
+ fflush(stdout);
+ assert(false);
+ }
+}
+void log_out(const char* log)
+{
+ if (do_log_out)
+ {
+ do_log_out(log);
+ }
+ else
+ {
+ printf("%s", log);
+ fflush(stdout);
+ OutputDebugStringA(log);
+ }
+}
+typedef struct _timer_manage
+{
+ struct _timer_info
+ {
+ int state; /* on or off */
+ int interval;
+ int elapse; /* 0~interval */
+ void (* timer_proc) (void* param);
+ void* param;
+ }timer_info[MAX_TIMER_CNT];
+ void (* old_sigfunc)(int);
+ void (* new_sigfunc)(int);
+}_timer_manage_t;
+static struct _timer_manage timer_manage;
+DWORD WINAPI timer_routine(LPVOID lpParam)
+{
+ int i;
+ while(true)
+ {
+ for(i = 0; i < MAX_TIMER_CNT; i++)
+ {
+ if(timer_manage.timer_info[i].state == 0)
+ {
+ continue;
+ }
+ timer_manage.timer_info[i].elapse++;
+ if(timer_manage.timer_info[i].elapse == timer_manage.timer_info[i].interval)
+ {
+ timer_manage.timer_info[i].elapse = 0;
+ timer_manage.timer_info[i].timer_proc(timer_manage.timer_info[i].param);
+ }
+ }
+ Sleep(TIMER_UNIT);
+ }
+ return 0;
+}
+static int init_mul_timer()
+{
+ static bool s_is_init = false;
+ if(s_is_init == true)
+ {
+ return 0;
+ }
+ memset(&timer_manage, 0, sizeof(struct _timer_manage));
+ DWORD pid;
+ CreateThread(0, 0, timer_routine, 0, 0, &pid);
+ s_is_init = true;
+ return 1;
+}
+static int set_a_timer(int interval, void (* timer_proc) (void* param), void* param)
+{
+ init_mul_timer();
+ int i;
+ if(timer_proc == 0 || interval <= 0)
+ {
+ return (-1);
+ }
+ for(i = 0; i < MAX_TIMER_CNT; i++)
+ {
+ if(timer_manage.timer_info[i].state == 1)
+ {
+ continue;
+ }
+ memset(&timer_manage.timer_info[i], 0, sizeof(timer_manage.timer_info[i]));
+ timer_manage.timer_info[i].timer_proc = timer_proc;
+ timer_manage.timer_info[i].param = param;
+ timer_manage.timer_info[i].interval = interval;
+ timer_manage.timer_info[i].elapse = 0;
+ timer_manage.timer_info[i].state = 1;
+ break;
+ }
+ if(i >= MAX_TIMER_CNT)
+ {
+ ASSERT(false);
+ return (-1);
+ }
+ return (i);
+}
+typedef void (*EXPIRE_ROUTINE)(void* arg);
+EXPIRE_ROUTINE s_expire_function;
+static c_fifo s_real_timer_fifo;
+static DWORD WINAPI fire_real_timer(LPVOID lpParam)
+{
+ char dummy;
+ while(1)
+ {
+ if(s_real_timer_fifo.read(&dummy, 1) > 0)
+ {
+ if(s_expire_function)s_expire_function(0);
+ }
+ else
+ {
+ ASSERT(false);
+ }
+ }
+ return 0;
+}
+/*Win32 desktop only
+static void CALLBACK trigger_real_timer(UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR)
+{
+ char dummy = 0x33;
+ s_real_timer_fifo.write(&dummy, 1);
+}
+*/
+static DWORD WINAPI trigger_real_timer(LPVOID lpParam)
+{
+ char dummy = 0x33;
+ while (1)
+ {
+ s_real_timer_fifo.write(&dummy, 1);
+ Sleep(REAL_TIME_TASK_CYCLE_MS);
+ }
+ return 0;
+}
+void start_real_timer(void (*func)(void* arg))
+{
+ if(0 == func)
+ {
+ return;
+ }
+ s_expire_function = func;
+ //timeSetEvent(REAL_TIME_TASK_CYCLE_MS, 0, trigger_real_timer, 0, TIME_PERIODIC);//Win32 desktop only
+ static DWORD s_pid;
+ if(s_pid == 0)
+ {
+ CreateThread(0, 0, trigger_real_timer, 0, 0, &s_pid);
+ CreateThread(0, 0, fire_real_timer, 0, 0, &s_pid);
+ }
+}
+unsigned int get_cur_thread_id()
+{
+ return GetCurrentThreadId();
+}
+void register_timer(int milli_second,void func(void* param), void* param)
+{
+ set_a_timer(milli_second/TIMER_UNIT,func, param);
+}
+long get_time_in_second()
+{
+ return (long)time(0);
+}
+T_TIME get_time()
+{
+ T_TIME ret = {0};
+
+ SYSTEMTIME time;
+ GetLocalTime(&time);
+ ret.year = time.wYear;
+ ret.month = time.wMonth;
+ ret.day = time.wDay;
+ ret.hour = time.wHour;
+ ret.minute = time.wMinute;
+ ret.second = time.wSecond;
+ return ret;
+}
+T_TIME second_to_day(long second)
+{
+ T_TIME ret;
+ ret.year = 1999;
+ ret.month = 10;
+ ret.date = 1;
+ ret.second = second % 60;
+ second /= 60;
+ ret.minute = second % 60;
+ second /= 60;
+ ret.hour = (second + 8) % 24;//China time zone.
+ return ret;
+}
+void create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg)
+{
+ DWORD pid = 0;
+ CreateThread(0, 0, LPTHREAD_START_ROUTINE(start_routine), arg, 0, &pid);
+ *thread_id = pid;
+}
+void thread_sleep(unsigned int milli_seconds)
+{
+ Sleep(milli_seconds);
+}
+#pragma pack(push,1)
+typedef struct {
+ unsigned short bfType;
+ unsigned int bfSize;
+ unsigned short bfReserved1;
+ unsigned short bfReserved2;
+ unsigned int bfOffBits;
+}FileHead;
+typedef struct {
+ unsigned int biSize;
+ int biWidth;
+ int biHeight;
+ unsigned short biPlanes;
+ unsigned short biBitCount;
+ unsigned int biCompress;
+ unsigned int biSizeImage;
+ int biXPelsPerMeter;
+ int biYPelsPerMeter;
+ unsigned int biClrUsed;
+ unsigned int biClrImportant;
+ unsigned int biRedMask;
+ unsigned int biGreenMask;
+ unsigned int biBlueMask;
+}Infohead;
+#pragma pack(pop)
+int build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data)
+{
+ FileHead bmp_head;
+ Infohead bmp_info;
+ int size = width * height * 2;
+ //initialize bmp head.
+ bmp_head.bfType = 0x4d42;
+ bmp_head.bfSize = size + sizeof(FileHead) + sizeof(Infohead);
+ bmp_head.bfReserved1 = bmp_head.bfReserved2 = 0;
+ bmp_head.bfOffBits = bmp_head.bfSize - size;
+ //initialize bmp info.
+ bmp_info.biSize = 40;
+ bmp_info.biWidth = width;
+ bmp_info.biHeight = height;
+ bmp_info.biPlanes = 1;
+ bmp_info.biBitCount = 16;
+ bmp_info.biCompress = 3;
+ bmp_info.biSizeImage = size;
+ bmp_info.biXPelsPerMeter = 0;
+ bmp_info.biYPelsPerMeter = 0;
+ bmp_info.biClrUsed = 0;
+ bmp_info.biClrImportant = 0;
+ //RGB565
+ bmp_info.biRedMask = 0xF800;
+ bmp_info.biGreenMask = 0x07E0;
+ bmp_info.biBlueMask = 0x001F;
+ //copy the data
+ FILE *fp;
+ if (!(fp = fopen(filename, "wb")))
+ {
+ return -1;
+ }
+ fwrite(&bmp_head, 1, sizeof(FileHead), fp);
+ fwrite(&bmp_info, 1, sizeof(Infohead), fp);
+ //fwrite(data, 1, size, fp);//top <-> bottom
+ for (int i = (height - 1); i >= 0; --i)
+ {
+ fwrite(&data[i * width * 2], 1, width * 2, fp);
+ }
+ fclose(fp);
+ return 0;
+}
+c_fifo::c_fifo()
+{
+ m_head = m_tail = 0;
+ m_read_sem = CreateSemaphore(0, // default security attributes
+ 0, // initial count
+ 1, // maximum count
+ 0); // unnamed semaphore
+ m_write_mutex = CreateMutex(0, false, 0);
+}
+int c_fifo::read(void* buf, int len)
+{
+ unsigned char* pbuf = (unsigned char*)buf;
+ int i = 0;
+ while (i < len)
+ {
+ if (m_tail == m_head)
+ {//empty
+ WaitForSingleObject(m_read_sem, INFINITE);
+ continue;
+ }
+ *pbuf++ = m_buf[m_head];
+ m_head = (m_head + 1) % FIFO_BUFFER_LEN;
+ i++;
+ }
+ if (i != len)
+ {
+ ASSERT(false);
+ }
+ return i;
+}
+int c_fifo::write(void* buf, int len)
+{
+ unsigned char* pbuf = (unsigned char*)buf;
+ int i = 0;
+ int tail = m_tail;
+ WaitForSingleObject(m_write_mutex, INFINITE);
+ while (i < len)
+ {
+ if ((m_tail + 1) % FIFO_BUFFER_LEN == m_head)
+ {//full, clear data has been written;
+ m_tail = tail;
+ log_out("Warning: fifo full\n");
+ ReleaseMutex(m_write_mutex);
+ return 0;
+ }
+ m_buf[m_tail] = *pbuf++;
+ m_tail = (m_tail + 1) % FIFO_BUFFER_LEN;
+ i++;
+ }
+ ReleaseMutex(m_write_mutex);
+ if (i != len)
+ {
+ ASSERT(false);
+ }
+ else
+ {
+ ReleaseSemaphore(m_read_sem, 1, 0);
+ }
+ return i;
+}
+#endif
+#endif
+#ifdef GUILITE_ON
+DIALOG_ARRAY c_dialog::ms_the_dialogs[SURFACE_CNT_MAX];
+#endif
+#ifdef GUILITE_ON
+c_keyboard c_edit::s_keyboard;
+#endif
+#ifdef GUILITE_ON
+static c_keyboard_button s_key_0, s_key_1, s_key_2, s_key_3, s_key_4, s_key_5, s_key_6, s_key_7, s_key_8, s_key_9;
+static c_keyboard_button s_key_A, s_key_B, s_key_C, s_key_D, s_key_E, s_key_F, s_key_G, s_key_H, s_key_I, s_key_J;
+static c_keyboard_button s_key_K, s_key_L, s_key_M, s_key_N, s_key_O, s_key_P, s_key_Q, s_key_R, s_key_S, s_key_T;
+static c_keyboard_button s_key_U, s_key_V, s_key_W, s_key_X, s_key_Y, s_key_Z;
+static c_keyboard_button s_key_dot, s_key_caps, s_key_space, s_key_enter, s_key_del, s_key_esc, s_key_num_switch;
+WND_TREE g_key_board_children[] =
+{
+ //Row 1
+ {&s_key_Q, 'Q', 0, POS_X(0), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_W, 'W', 0, POS_X(1), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_E, 'E', 0, POS_X(2), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_R, 'R', 0, POS_X(3), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_T, 'T', 0, POS_X(4), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_Y, 'Y', 0, POS_X(5), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_U, 'U', 0, POS_X(6), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_I, 'I', 0, POS_X(7), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_O, 'O', 0, POS_X(8), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_P, 'P', 0, POS_X(9), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},
+ //Row 2
+ {&s_key_A, 'A', 0, ((KEY_WIDTH / 2) + POS_X(0)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_S, 'S', 0, ((KEY_WIDTH / 2) + POS_X(1)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_D, 'D', 0, ((KEY_WIDTH / 2) + POS_X(2)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_F, 'F', 0, ((KEY_WIDTH / 2) + POS_X(3)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_G, 'G', 0, ((KEY_WIDTH / 2) + POS_X(4)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_H, 'H', 0, ((KEY_WIDTH / 2) + POS_X(5)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_J, 'J', 0, ((KEY_WIDTH / 2) + POS_X(6)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_K, 'K', 0, ((KEY_WIDTH / 2) + POS_X(7)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_L, 'L', 0, ((KEY_WIDTH / 2) + POS_X(8)), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},
+ //Row 3
+ {&s_key_caps, 0x14, 0, POS_X(0), POS_Y(2), CAPS_WIDTH, KEY_HEIGHT},
+ {&s_key_Z, 'Z', 0, ((KEY_WIDTH / 2) + POS_X(1)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_X, 'X', 0, ((KEY_WIDTH / 2) + POS_X(2)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_C, 'C', 0, ((KEY_WIDTH / 2) + POS_X(3)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_V, 'V', 0, ((KEY_WIDTH / 2) + POS_X(4)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_B, 'B', 0, ((KEY_WIDTH / 2) + POS_X(5)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_N, 'N', 0, ((KEY_WIDTH / 2) + POS_X(6)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_M, 'M', 0, ((KEY_WIDTH / 2) + POS_X(7)), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_del, 0x7F, 0, ((KEY_WIDTH / 2) + POS_X(8)), POS_Y(2), DEL_WIDTH, KEY_HEIGHT},
+ //Row 4
+ {&s_key_esc, 0x1B, 0, POS_X(0), POS_Y(3), ESC_WIDTH, KEY_HEIGHT},
+ {&s_key_num_switch, 0x90, 0, POS_X(2), POS_Y(3), SWITCH_WIDTH, KEY_HEIGHT},
+ {&s_key_space, ' ', 0, ((KEY_WIDTH / 2) + POS_X(3)), POS_Y(3), SPACE_WIDTH, KEY_HEIGHT},
+ {&s_key_dot, '.', 0, ((KEY_WIDTH / 2) + POS_X(6)), POS_Y(3), DOT_WIDTH, KEY_HEIGHT},
+ {&s_key_enter, '\n', 0, POS_X(8), POS_Y(3), ENTER_WIDTH, KEY_HEIGHT},
+ {0,0,0,0,0,0,0}
+};
+WND_TREE g_number_board_children[] =
+{
+ {&s_key_1, '1', 0, POS_X(0), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_2, '2', 0, POS_X(1), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_3, '3', 0, POS_X(2), POS_Y(0), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_4, '4', 0, POS_X(0), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_5, '5', 0, POS_X(1), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_6, '6', 0, POS_X(2), POS_Y(1), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_7, '7', 0, POS_X(0), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_8, '8', 0, POS_X(1), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_9, '9', 0, POS_X(2), POS_Y(2), KEY_WIDTH, KEY_HEIGHT},
+
+ {&s_key_esc, 0x1B, 0, POS_X(0), POS_Y(3), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_0, '0', 0, POS_X(1), POS_Y(3), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_dot, '.', 0, POS_X(2), POS_Y(3), KEY_WIDTH, KEY_HEIGHT},
+ {&s_key_del, 0x7F, 0, POS_X(3), POS_Y(0), KEY_WIDTH, KEY_HEIGHT * 2 + 2},
+ {&s_key_enter,'\n', 0, POS_X(3), POS_Y(2), KEY_WIDTH, KEY_HEIGHT * 2 + 2},
+ {0,0,0,0,0,0,0}
+};
+#endif
+#pragma GCC diagnostic pop
diff --git a/src/lib/printf/LICENSE b/src/lib/printf/LICENSE
new file mode 100644
index 00000000..8f7ebd0b
--- /dev/null
+++ b/src/lib/printf/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Marco Paland
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/src/lib/printf/README.md b/src/lib/printf/README.md
new file mode 100644
index 00000000..2122653e
--- /dev/null
+++ b/src/lib/printf/README.md
@@ -0,0 +1,212 @@
+# A printf / sprintf Implementation for Embedded Systems
+
+[](https://travis-ci.org/mpaland/printf)
+[](https://codecov.io/gh/mpaland/printf)
+[](https://scan.coverity.com/projects/mpaland-printf)
+[](http://github.com/mpaland/printf/issues)
+[](https://github.com/mpaland/printf/releases)
+[](https://raw.githubusercontent.com/mpaland/avl_array/master/LICENSE)
+
+This is a tiny but **fully loaded** printf, sprintf and (v)snprintf implementation.
+Primarily designed for usage in embedded systems, where printf is not available due to memory issues or in avoidance of linking against libc.
+Using the standard libc printf may pull **a lot** of unwanted library stuff and can bloat code size about 20k or is not 100% thread safe. In this cases the following implementation can be used.
+Absolutely **NO dependencies** are required, *printf.c* brings all necessary routines, even its own fast `ftoa` (floating point), `ntoa` (decimal) conversion.
+
+If memory footprint is really a critical issue, floating point, exponential and 'long long' support and can be turned off via the `PRINTF_DISABLE_SUPPORT_FLOAT`, `PRINTF_DISABLE_SUPPORT_EXPONENTIAL` and `PRINTF_DISABLE_SUPPORT_LONG_LONG` compiler switches.
+When using printf (instead of sprintf/snprintf) you have to provide your own `_putchar()` low level function as console/serial output.
+
+
+## 2020 announcement
+This project is not dead! I just had no time in 2019 for sufficient support, sorry.
+Within the next weeks, I will have a look to all PRs and open issues.
+Thank you all for supporting this project.
+
+
+## Highlights and Design Goals
+
+There is a boatload of so called 'tiny' printf implementations around. So why this one?
+I've tested many implementations, but most of them have very limited flag/specifier support, a lot of other dependencies or are just not standard compliant and failing most of the test suite.
+Therefore I decided to write an own, final implementation which meets the following items:
+
+ - Very small implementation (around 600 code lines)
+ - NO dependencies, no libs, just one module file
+ - Support of all important flags, width and precision sub-specifiers (see below)
+ - Support of decimal/floating number representation (with an own fast itoa/ftoa)
+ - Reentrant and thread-safe, malloc free, no static vars/buffers
+ - LINT and compiler L4 warning free, mature, coverity clean, automotive ready
+ - Extensive test suite (> 400 test cases) passing
+ - Simply the best *printf* around the net
+ - MIT license
+
+
+## Usage
+
+Add/link *printf.c* to your project and include *printf.h*. That's it.
+Implement your low level output function needed for `printf()`:
+```C
+void _putchar(char character)
+{
+ // send char to console etc.
+}
+```
+
+Usage is 1:1 like the according stdio.h library version:
+```C
+int printf(const char* format, ...);
+int sprintf(char* buffer, const char* format, ...);
+int snprintf(char* buffer, size_t count, const char* format, ...);
+int vsnprintf(char* buffer, size_t count, const char* format, va_list va);
+
+// use output function (instead of buffer) for streamlike interface
+int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...);
+```
+
+**Due to general security reasons it is highly recommended to prefer and use `snprintf` (with the max buffer size as `count` parameter) instead of `sprintf`.**
+`sprintf` has no buffer limitation, so when needed - use it really with care!
+
+### Streamlike Usage
+Besides the regular standard `printf()` functions, this module also provides `fctprintf()`, which takes an output function as first parameter to build a streamlike output like `fprintf()`:
+```C
+// define the output function
+void my_stream_output(char character, void* arg)
+{
+ // opt. evaluate the argument and send the char somewhere
+}
+
+{
+ // in your code
+ void* arg = (void*)100; // this argument is passed to the output function
+ fctprintf(&my_stream_output, arg, "This is a test: %X", 0xAA);
+ fctprintf(&my_stream_output, nullptr, "Send to null dev");
+}
+```
+
+## Format Specifiers
+
+A format specifier follows this prototype: `%[flags][width][.precision][length]type`
+The following format specifiers are supported:
+
+
+### Supported Types
+
+| Type | Output |
+|--------|--------|
+| d or i | Signed decimal integer |
+| u | Unsigned decimal integer |
+| b | Unsigned binary |
+| o | Unsigned octal |
+| x | Unsigned hexadecimal integer (lowercase) |
+| X | Unsigned hexadecimal integer (uppercase) |
+| f or F | Decimal floating point |
+| e or E | Scientific-notation (exponential) floating point |
+| g or G | Scientific or decimal floating point |
+| c | Single character |
+| s | String of characters |
+| p | Pointer address |
+| % | A % followed by another % character will write a single % |
+
+
+### Supported Flags
+
+| Flags | Description |
+|-------|-------------|
+| - | Left-justify within the given field width; Right justification is the default. |
+| + | Forces to precede the result with a plus or minus sign (+ or -) even for positive numbers. By default, only negative numbers are preceded with a - sign. |
+| (space) | If no sign is going to be written, a blank space is inserted before the value. |
+| # | Used with o, b, x or X specifiers the value is preceded with 0, 0b, 0x or 0X respectively for values different than zero. Used with f, F it forces the written output to contain a decimal point even if no more digits follow. By default, if no digits follow, no decimal point is written. |
+| 0 | Left-pads the number with zeros (0) instead of spaces when padding is specified (see width sub-specifier). |
+
+
+### Supported Width
+
+| Width | Description |
+|----------|-------------|
+| (number) | Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger. |
+| * | The width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted. |
+
+
+### Supported Precision
+
+| Precision | Description |
+|-----------|-------------|
+| .number | For integer specifiers (d, i, o, u, x, X): precision specifies the minimum number of digits to be written. If the value to be written is shorter than this number, the result is padded with leading zeros. The value is not truncated even if the result is longer. A precision of 0 means that no character is written for the value 0. For f and F specifiers: this is the number of digits to be printed after the decimal point. **By default, this is 6, maximum is 9**. For s: this is the maximum number of characters to be printed. By default all characters are printed until the ending null character is encountered. If the period is specified without an explicit value for precision, 0 is assumed. |
+| .* | The precision is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted. |
+
+
+### Supported Length
+
+The length sub-specifier modifies the length of the data type.
+
+| Length | d i | u o x X |
+|--------|------|---------|
+| (none) | int | unsigned int |
+| hh | char | unsigned char |
+| h | short int | unsigned short int |
+| l | long int | unsigned long int |
+| ll | long long int | unsigned long long int (if PRINTF_SUPPORT_LONG_LONG is defined) |
+| j | intmax_t | uintmax_t |
+| z | size_t | size_t |
+| t | ptrdiff_t | ptrdiff_t (if PRINTF_SUPPORT_PTRDIFF_T is defined) |
+
+
+### Return Value
+
+Upon successful return, all functions return the number of characters written, _excluding_ the terminating null character used to end the string.
+Functions `snprintf()` and `vsnprintf()` don't write more than `count` bytes, _including_ the terminating null byte ('\0').
+Anyway, if the output was truncated due to this limit, the return value is the number of characters that _could_ have been written.
+Notice that a value equal or larger than `count` indicates a truncation. Only when the returned value is non-negative and less than `count`,
+the string has been completely written.
+If any error is encountered, `-1` is returned.
+
+If `buffer` is set to `NULL` (`nullptr`) nothing is written and just the formatted length is returned.
+```C
+int length = sprintf(NULL, "Hello, world"); // length is set to 12
+```
+
+
+## Compiler Switches/Defines
+
+| Name | Default value | Description |
+|------|---------------|-------------|
+| PRINTF_INCLUDE_CONFIG_H | undefined | Define this as compiler switch (e.g. `gcc -DPRINTF_INCLUDE_CONFIG_H`) to include a "printf_config.h" definition file |
+| PRINTF_NTOA_BUFFER_SIZE | 32 | ntoa (integer) conversion buffer size. This must be big enough to hold one converted numeric number _including_ leading zeros, normally 32 is a sufficient value. Created on the stack |
+| PRINTF_FTOA_BUFFER_SIZE | 32 | ftoa (float) conversion buffer size. This must be big enough to hold one converted float number _including_ leading zeros, normally 32 is a sufficient value. Created on the stack |
+| PRINTF_DEFAULT_FLOAT_PRECISION | 6 | Define the default floating point precision |
+| PRINTF_MAX_FLOAT | 1e9 | Define the largest suitable value to be printed with %f, before using exponential representation |
+| PRINTF_DISABLE_SUPPORT_FLOAT | undefined | Define this to disable floating point (%f) support |
+| PRINTF_DISABLE_SUPPORT_EXPONENTIAL | undefined | Define this to disable exponential floating point (%e) support |
+| PRINTF_DISABLE_SUPPORT_LONG_LONG | undefined | Define this to disable long long (%ll) support |
+| PRINTF_DISABLE_SUPPORT_PTRDIFF_T | undefined | Define this to disable ptrdiff_t (%t) support |
+
+
+## Caveats
+None anymore (finally).
+
+
+## Test Suite
+For testing just compile, build and run the test suite located in `test/test_suite.cpp`. This uses the [catch](https://github.com/catchorg/Catch2) framework for unit-tests, which is auto-adding main().
+Running with the `--wait-for-keypress exit` option waits for the enter key after test end.
+
+
+## Projects Using printf
+- [turnkeyboard](https://github.com/mpaland/turnkeyboard) uses printf as log and generic tty (formatting) output.
+- printf is part of [embeddedartistry/libc](https://github.com/embeddedartistry/libc), a libc targeted for embedded systems usage.
+- The [Hatchling Platform]( https://github.com/adrian3git/HatchlingPlatform) uses printf.
+
+(Just send me a mail/issue/PR to get *your* project listed here)
+
+
+## Contributing
+
+0. Give this project a :star:
+1. Create an issue and describe your idea
+2. [Fork it](https://github.com/mpaland/printf/fork)
+3. Create your feature branch (`git checkout -b my-new-feature`)
+4. Commit your changes (`git commit -am 'Add some feature'`)
+5. Publish the branch (`git push origin my-new-feature`)
+6. Create a new pull request
+7. Profit! :heavy_check_mark:
+
+
+## License
+printf is written under the [MIT license](http://www.opensource.org/licenses/MIT).
diff --git a/src/lib/printf/printf.c b/src/lib/printf/printf.c
new file mode 100644
index 00000000..406dca99
--- /dev/null
+++ b/src/lib/printf/printf.c
@@ -0,0 +1,914 @@
+///////////////////////////////////////////////////////////////////////////////
+// \author (c) Marco Paland (info@paland.com)
+// 2014-2019, PALANDesign Hannover, Germany
+//
+// \license The MIT License (MIT)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on
+// embedded systems with a very limited resources. These routines are thread
+// safe and reentrant!
+// Use this instead of the bloated standard/newlib printf cause these use
+// malloc for printf (and may not be thread safe).
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include
+#include
+
+#include "printf.h"
+
+
+// define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the
+// printf_config.h header file
+// default: undefined
+#ifdef PRINTF_INCLUDE_CONFIG_H
+#include "printf_config.h"
+#endif
+
+
+// 'ntoa' conversion buffer size, this must be big enough to hold one converted
+// numeric number including padded zeros (dynamically created on stack)
+// default: 32 byte
+#ifndef PRINTF_NTOA_BUFFER_SIZE
+#define PRINTF_NTOA_BUFFER_SIZE 32U
+#endif
+
+// 'ftoa' conversion buffer size, this must be big enough to hold one converted
+// float number including padded zeros (dynamically created on stack)
+// default: 32 byte
+#ifndef PRINTF_FTOA_BUFFER_SIZE
+#define PRINTF_FTOA_BUFFER_SIZE 32U
+#endif
+
+// support for the floating point type (%f)
+// default: activated
+#ifndef PRINTF_DISABLE_SUPPORT_FLOAT
+#define PRINTF_SUPPORT_FLOAT
+#endif
+
+// support for exponential floating point notation (%e/%g)
+// default: activated
+#ifndef PRINTF_DISABLE_SUPPORT_EXPONENTIAL
+#define PRINTF_SUPPORT_EXPONENTIAL
+#endif
+
+// define the default floating point precision
+// default: 6 digits
+#ifndef PRINTF_DEFAULT_FLOAT_PRECISION
+#define PRINTF_DEFAULT_FLOAT_PRECISION 6U
+#endif
+
+// define the largest float suitable to print with %f
+// default: 1e9
+#ifndef PRINTF_MAX_FLOAT
+#define PRINTF_MAX_FLOAT 1e9
+#endif
+
+// support for the long long types (%llu or %p)
+// default: activated
+#ifndef PRINTF_DISABLE_SUPPORT_LONG_LONG
+#define PRINTF_SUPPORT_LONG_LONG
+#endif
+
+// support for the ptrdiff_t type (%t)
+// ptrdiff_t is normally defined in as long or long long type
+// default: activated
+#ifndef PRINTF_DISABLE_SUPPORT_PTRDIFF_T
+#define PRINTF_SUPPORT_PTRDIFF_T
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+// internal flag definitions
+#define FLAGS_ZEROPAD (1U << 0U)
+#define FLAGS_LEFT (1U << 1U)
+#define FLAGS_PLUS (1U << 2U)
+#define FLAGS_SPACE (1U << 3U)
+#define FLAGS_HASH (1U << 4U)
+#define FLAGS_UPPERCASE (1U << 5U)
+#define FLAGS_CHAR (1U << 6U)
+#define FLAGS_SHORT (1U << 7U)
+#define FLAGS_LONG (1U << 8U)
+#define FLAGS_LONG_LONG (1U << 9U)
+#define FLAGS_PRECISION (1U << 10U)
+#define FLAGS_ADAPT_EXP (1U << 11U)
+
+
+// import float.h for DBL_MAX
+#if defined(PRINTF_SUPPORT_FLOAT)
+#include
+#endif
+
+
+// output function type
+typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen);
+
+
+// wrapper (used as buffer) for output function type
+typedef struct {
+ void (*fct)(char character, void* arg);
+ void* arg;
+} out_fct_wrap_type;
+
+
+// internal buffer output
+static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen)
+{
+ if (idx < maxlen) {
+ ((char*)buffer)[idx] = character;
+ }
+}
+
+
+// internal null output
+static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen)
+{
+ (void)character; (void)buffer; (void)idx; (void)maxlen;
+}
+
+
+// internal _putchar wrapper
+static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen)
+{
+ (void)buffer; (void)idx; (void)maxlen;
+ if (character) {
+ _putchar(character);
+ }
+}
+
+
+// internal output function wrapper
+static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen)
+{
+ (void)idx; (void)maxlen;
+ if (character) {
+ // buffer is the output fct pointer
+ ((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg);
+ }
+}
+
+
+// internal secure strlen
+// \return The length of the string (excluding the terminating 0) limited by 'maxsize'
+static inline unsigned int _strnlen_s(const char* str, size_t maxsize)
+{
+ const char* s;
+ for (s = str; *s && maxsize--; ++s);
+ return (unsigned int)(s - str);
+}
+
+
+// internal test if char is a digit (0-9)
+// \return true if char is a digit
+static inline bool _is_digit(char ch)
+{
+ return (ch >= '0') && (ch <= '9');
+}
+
+
+// internal ASCII string to unsigned int conversion
+static unsigned int _atoi(const char** str)
+{
+ unsigned int i = 0U;
+ while (_is_digit(**str)) {
+ i = i * 10U + (unsigned int)(*((*str)++) - '0');
+ }
+ return i;
+}
+
+
+// output the specified string in reverse, taking care of any zero-padding
+static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags)
+{
+ const size_t start_idx = idx;
+
+ // pad spaces up to given width
+ if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) {
+ for (size_t i = len; i < width; i++) {
+ out(' ', buffer, idx++, maxlen);
+ }
+ }
+
+ // reverse string
+ while (len) {
+ out(buf[--len], buffer, idx++, maxlen);
+ }
+
+ // append pad spaces up to given width
+ if (flags & FLAGS_LEFT) {
+ while (idx - start_idx < width) {
+ out(' ', buffer, idx++, maxlen);
+ }
+ }
+
+ return idx;
+}
+
+
+// internal itoa format
+static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags)
+{
+ // pad leading zeros
+ if (!(flags & FLAGS_LEFT)) {
+ if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
+ width--;
+ }
+ while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
+ buf[len++] = '0';
+ }
+ while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
+ buf[len++] = '0';
+ }
+ }
+
+ // handle hash
+ if (flags & FLAGS_HASH) {
+ if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) {
+ len--;
+ if (len && (base == 16U)) {
+ len--;
+ }
+ }
+ if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
+ buf[len++] = 'x';
+ }
+ else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
+ buf[len++] = 'X';
+ }
+ else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
+ buf[len++] = 'b';
+ }
+ if (len < PRINTF_NTOA_BUFFER_SIZE) {
+ buf[len++] = '0';
+ }
+ }
+
+ if (len < PRINTF_NTOA_BUFFER_SIZE) {
+ if (negative) {
+ buf[len++] = '-';
+ }
+ else if (flags & FLAGS_PLUS) {
+ buf[len++] = '+'; // ignore the space if the '+' exists
+ }
+ else if (flags & FLAGS_SPACE) {
+ buf[len++] = ' ';
+ }
+ }
+
+ return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
+}
+
+
+// internal itoa for 'long' type
+static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags)
+{
+ char buf[PRINTF_NTOA_BUFFER_SIZE];
+ size_t len = 0U;
+
+ // no hash for 0 values
+ if (!value) {
+ flags &= ~FLAGS_HASH;
+ }
+
+ // write if precision != 0 and value is != 0
+ if (!(flags & FLAGS_PRECISION) || value) {
+ do {
+ const char digit = (char)(value % base);
+ buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
+ value /= base;
+ } while (value && (len < PRINTF_NTOA_BUFFER_SIZE));
+ }
+
+ return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags);
+}
+
+
+// internal itoa for 'long long' type
+#if defined(PRINTF_SUPPORT_LONG_LONG)
+static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags)
+{
+ char buf[PRINTF_NTOA_BUFFER_SIZE];
+ size_t len = 0U;
+
+ // no hash for 0 values
+ if (!value) {
+ flags &= ~FLAGS_HASH;
+ }
+
+ // write if precision != 0 and value is != 0
+ if (!(flags & FLAGS_PRECISION) || value) {
+ do {
+ const char digit = (char)(value % base);
+ buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
+ value /= base;
+ } while (value && (len < PRINTF_NTOA_BUFFER_SIZE));
+ }
+
+ return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags);
+}
+#endif // PRINTF_SUPPORT_LONG_LONG
+
+
+#if defined(PRINTF_SUPPORT_FLOAT)
+
+#if defined(PRINTF_SUPPORT_EXPONENTIAL)
+// forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT
+static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags);
+#endif
+
+
+// internal ftoa for fixed decimal floating point
+static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
+{
+ char buf[PRINTF_FTOA_BUFFER_SIZE];
+ size_t len = 0U;
+ double diff = 0.0;
+
+ // powers of 10
+ static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
+
+ // test for special values
+ if (value != value)
+ return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags);
+ if (value < -DBL_MAX)
+ return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags);
+ if (value > DBL_MAX)
+ return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags);
+
+ // test for very large values
+ // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad
+ if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) {
+#if defined(PRINTF_SUPPORT_EXPONENTIAL)
+ return _etoa(out, buffer, idx, maxlen, value, prec, width, flags);
+#else
+ return 0U;
+#endif
+ }
+
+ // test for negative
+ bool negative = false;
+ if (value < 0) {
+ negative = true;
+ value = 0 - value;
+ }
+
+ // set default precision, if not set explicitly
+ if (!(flags & FLAGS_PRECISION)) {
+ prec = PRINTF_DEFAULT_FLOAT_PRECISION;
+ }
+ // limit precision to 9, cause a prec >= 10 can lead to overflow errors
+ while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) {
+ buf[len++] = '0';
+ prec--;
+ }
+
+ int whole = (int)value;
+ double tmp = (value - whole) * pow10[prec];
+ unsigned long frac = (unsigned long)tmp;
+ diff = tmp - frac;
+
+ if (diff > 0.5) {
+ ++frac;
+ // handle rollover, e.g. case 0.99 with prec 1 is 1.0
+ if (frac >= pow10[prec]) {
+ frac = 0;
+ ++whole;
+ }
+ }
+ else if (diff < 0.5) {
+ }
+ else if ((frac == 0U) || (frac & 1U)) {
+ // if halfway, round up if odd OR if last digit is 0
+ ++frac;
+ }
+
+ if (prec == 0U) {
+ diff = value - (double)whole;
+ if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) {
+ // exactly 0.5 and ODD, then round up
+ // 1.5 -> 2, but 2.5 -> 2
+ ++whole;
+ }
+ }
+ else {
+ unsigned int count = prec;
+ // now do fractional part, as an unsigned number
+ while (len < PRINTF_FTOA_BUFFER_SIZE) {
+ --count;
+ buf[len++] = (char)(48U + (frac % 10U));
+ if (!(frac /= 10U)) {
+ break;
+ }
+ }
+ // add extra 0s
+ while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) {
+ buf[len++] = '0';
+ }
+ if (len < PRINTF_FTOA_BUFFER_SIZE) {
+ // add decimal
+ buf[len++] = '.';
+ }
+ }
+
+ // do whole part, number is reversed
+ while (len < PRINTF_FTOA_BUFFER_SIZE) {
+ buf[len++] = (char)(48 + (whole % 10));
+ if (!(whole /= 10)) {
+ break;
+ }
+ }
+
+ // pad leading zeros
+ if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) {
+ if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
+ width--;
+ }
+ while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) {
+ buf[len++] = '0';
+ }
+ }
+
+ if (len < PRINTF_FTOA_BUFFER_SIZE) {
+ if (negative) {
+ buf[len++] = '-';
+ }
+ else if (flags & FLAGS_PLUS) {
+ buf[len++] = '+'; // ignore the space if the '+' exists
+ }
+ else if (flags & FLAGS_SPACE) {
+ buf[len++] = ' ';
+ }
+ }
+
+ return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
+}
+
+
+#if defined(PRINTF_SUPPORT_EXPONENTIAL)
+// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse
+static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
+{
+ // check for NaN and special values
+ if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) {
+ return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags);
+ }
+
+ // determine the sign
+ const bool negative = value < 0;
+ if (negative) {
+ value = -value;
+ }
+
+ // default precision
+ if (!(flags & FLAGS_PRECISION)) {
+ prec = PRINTF_DEFAULT_FLOAT_PRECISION;
+ }
+
+ // determine the decimal exponent
+ // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c)
+ union {
+ uint64_t U;
+ double F;
+ } conv;
+
+ conv.F = value;
+ int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2
+ conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2)
+ // now approximate log10 from the log2 integer part and an expansion of ln around 1.5
+ int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168);
+ // now we want to compute 10^expval but we want to be sure it won't overflow
+ exp2 = (int)(expval * 3.321928094887362 + 0.5);
+ const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453;
+ const double z2 = z * z;
+ conv.U = (uint64_t)(exp2 + 1023) << 52U;
+ // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex
+ conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14)))));
+ // correct for rounding errors
+ if (value < conv.F) {
+ expval--;
+ conv.F /= 10;
+ }
+
+ // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters
+ unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U;
+
+ // in "%g" mode, "prec" is the number of *significant figures* not decimals
+ if (flags & FLAGS_ADAPT_EXP) {
+ // do we want to fall-back to "%f" mode?
+ if ((value >= 1e-4) && (value < 1e6)) {
+ if ((int)prec > expval) {
+ prec = (unsigned)((int)prec - expval - 1);
+ }
+ else {
+ prec = 0;
+ }
+ flags |= FLAGS_PRECISION; // make sure _ftoa respects precision
+ // no characters in exponent
+ minwidth = 0U;
+ expval = 0;
+ }
+ else {
+ // we use one sigfig for the whole part
+ if ((prec > 0) && (flags & FLAGS_PRECISION)) {
+ --prec;
+ }
+ }
+ }
+
+ // will everything fit?
+ unsigned int fwidth = width;
+ if (width > minwidth) {
+ // we didn't fall-back so subtract the characters required for the exponent
+ fwidth -= minwidth;
+ } else {
+ // not enough characters, so go back to default sizing
+ fwidth = 0U;
+ }
+ if ((flags & FLAGS_LEFT) && minwidth) {
+ // if we're padding on the right, DON'T pad the floating part
+ fwidth = 0U;
+ }
+
+ // rescale the float value
+ if (expval) {
+ value /= conv.F;
+ }
+
+ // output the floating part
+ const size_t start_idx = idx;
+ idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP);
+
+ // output the exponent part
+ if (minwidth) {
+ // output the exponential symbol
+ out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen);
+ // output the exponent value
+ idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS);
+ // might need to right-pad spaces
+ if (flags & FLAGS_LEFT) {
+ while (idx - start_idx < width) out(' ', buffer, idx++, maxlen);
+ }
+ }
+ return idx;
+}
+#endif // PRINTF_SUPPORT_EXPONENTIAL
+#endif // PRINTF_SUPPORT_FLOAT
+
+
+// internal vsnprintf
+static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va)
+{
+ unsigned int flags, width, precision, n;
+ size_t idx = 0U;
+
+ if (!buffer) {
+ // use null output function
+ out = _out_null;
+ }
+
+ while (*format)
+ {
+ // format specifier? %[flags][width][.precision][length]
+ if (*format != '%') {
+ // no
+ out(*format, buffer, idx++, maxlen);
+ format++;
+ continue;
+ }
+ else {
+ // yes, evaluate it
+ format++;
+ }
+
+ // evaluate flags
+ flags = 0U;
+ do {
+ switch (*format) {
+ case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break;
+ case '-': flags |= FLAGS_LEFT; format++; n = 1U; break;
+ case '+': flags |= FLAGS_PLUS; format++; n = 1U; break;
+ case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break;
+ case '#': flags |= FLAGS_HASH; format++; n = 1U; break;
+ default : n = 0U; break;
+ }
+ } while (n);
+
+ // evaluate width field
+ width = 0U;
+ if (_is_digit(*format)) {
+ width = _atoi(&format);
+ }
+ else if (*format == '*') {
+ const int w = va_arg(va, int);
+ if (w < 0) {
+ flags |= FLAGS_LEFT; // reverse padding
+ width = (unsigned int)-w;
+ }
+ else {
+ width = (unsigned int)w;
+ }
+ format++;
+ }
+
+ // evaluate precision field
+ precision = 0U;
+ if (*format == '.') {
+ flags |= FLAGS_PRECISION;
+ format++;
+ if (_is_digit(*format)) {
+ precision = _atoi(&format);
+ }
+ else if (*format == '*') {
+ const int prec = (int)va_arg(va, int);
+ precision = prec > 0 ? (unsigned int)prec : 0U;
+ format++;
+ }
+ }
+
+ // evaluate length field
+ switch (*format) {
+ case 'l' :
+ flags |= FLAGS_LONG;
+ format++;
+ if (*format == 'l') {
+ flags |= FLAGS_LONG_LONG;
+ format++;
+ }
+ break;
+ case 'h' :
+ flags |= FLAGS_SHORT;
+ format++;
+ if (*format == 'h') {
+ flags |= FLAGS_CHAR;
+ format++;
+ }
+ break;
+#if defined(PRINTF_SUPPORT_PTRDIFF_T)
+ case 't' :
+ flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
+ format++;
+ break;
+#endif
+ case 'j' :
+ flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
+ format++;
+ break;
+ case 'z' :
+ flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
+ format++;
+ break;
+ default :
+ break;
+ }
+
+ // evaluate specifier
+ switch (*format) {
+ case 'd' :
+ case 'i' :
+ case 'u' :
+ case 'x' :
+ case 'X' :
+ case 'o' :
+ case 'b' : {
+ // set the base
+ unsigned int base;
+ if (*format == 'x' || *format == 'X') {
+ base = 16U;
+ }
+ else if (*format == 'o') {
+ base = 8U;
+ }
+ else if (*format == 'b') {
+ base = 2U;
+ }
+ else {
+ base = 10U;
+ flags &= ~FLAGS_HASH; // no hash for dec format
+ }
+ // uppercase
+ if (*format == 'X') {
+ flags |= FLAGS_UPPERCASE;
+ }
+
+ // no plus or space flag for u, x, X, o, b
+ if ((*format != 'i') && (*format != 'd')) {
+ flags &= ~(FLAGS_PLUS | FLAGS_SPACE);
+ }
+
+ // ignore '0' flag when precision is given
+ if (flags & FLAGS_PRECISION) {
+ flags &= ~FLAGS_ZEROPAD;
+ }
+
+ // convert the integer
+ if ((*format == 'i') || (*format == 'd')) {
+ // signed
+ if (flags & FLAGS_LONG_LONG) {
+#if defined(PRINTF_SUPPORT_LONG_LONG)
+ const long long value = va_arg(va, long long);
+ idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
+#endif
+ }
+ else if (flags & FLAGS_LONG) {
+ const long value = va_arg(va, long);
+ idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
+ }
+ else {
+ const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int);
+ idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
+ }
+ }
+ else {
+ // unsigned
+ if (flags & FLAGS_LONG_LONG) {
+#if defined(PRINTF_SUPPORT_LONG_LONG)
+ idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags);
+#endif
+ }
+ else if (flags & FLAGS_LONG) {
+ idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags);
+ }
+ else {
+ const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int);
+ idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags);
+ }
+ }
+ format++;
+ break;
+ }
+#if defined(PRINTF_SUPPORT_FLOAT)
+ case 'f' :
+ case 'F' :
+ if (*format == 'F') flags |= FLAGS_UPPERCASE;
+ idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
+ format++;
+ break;
+#if defined(PRINTF_SUPPORT_EXPONENTIAL)
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP;
+ if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE;
+ idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
+ format++;
+ break;
+#endif // PRINTF_SUPPORT_EXPONENTIAL
+#endif // PRINTF_SUPPORT_FLOAT
+ case 'c' : {
+ unsigned int l = 1U;
+ // pre padding
+ if (!(flags & FLAGS_LEFT)) {
+ while (l++ < width) {
+ out(' ', buffer, idx++, maxlen);
+ }
+ }
+ // char output
+ out((char)va_arg(va, int), buffer, idx++, maxlen);
+ // post padding
+ if (flags & FLAGS_LEFT) {
+ while (l++ < width) {
+ out(' ', buffer, idx++, maxlen);
+ }
+ }
+ format++;
+ break;
+ }
+
+ case 's' : {
+ const char* p = va_arg(va, char*);
+ unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1);
+ // pre padding
+ if (flags & FLAGS_PRECISION) {
+ l = (l < precision ? l : precision);
+ }
+ if (!(flags & FLAGS_LEFT)) {
+ while (l++ < width) {
+ out(' ', buffer, idx++, maxlen);
+ }
+ }
+ // string output
+ while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) {
+ out(*(p++), buffer, idx++, maxlen);
+ }
+ // post padding
+ if (flags & FLAGS_LEFT) {
+ while (l++ < width) {
+ out(' ', buffer, idx++, maxlen);
+ }
+ }
+ format++;
+ break;
+ }
+
+ case 'p' : {
+ width = sizeof(void*) * 2U;
+ flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE;
+#if defined(PRINTF_SUPPORT_LONG_LONG)
+ const bool is_ll = sizeof(uintptr_t) == sizeof(long long);
+ if (is_ll) {
+ idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags);
+ }
+ else {
+#endif
+ idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags);
+#if defined(PRINTF_SUPPORT_LONG_LONG)
+ }
+#endif
+ format++;
+ break;
+ }
+
+ case '%' :
+ out('%', buffer, idx++, maxlen);
+ format++;
+ break;
+
+ default :
+ out(*format, buffer, idx++, maxlen);
+ format++;
+ break;
+ }
+ }
+
+ // termination
+ out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen);
+
+ // return written chars without terminating \0
+ return (int)idx;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+int usb64_printf(const char* format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ char buffer[1];
+ const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va);
+ va_end(va);
+ return ret;
+}
+
+
+int usb64_sprintf(char* buffer, const char* format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ const int ret = _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va);
+ va_end(va);
+ return ret;
+}
+
+
+int usb64_snprintf(char* buffer, size_t count, const char* format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ const int ret = _vsnprintf(_out_buffer, buffer, count, format, va);
+ va_end(va);
+ return ret;
+}
+
+
+int usb64_vprintf(const char* format, va_list va)
+{
+ char buffer[1];
+ return _vsnprintf(_out_char, buffer, (size_t)-1, format, va);
+}
+
+
+int usb64_vsnprintf(char* buffer, size_t count, const char* format, va_list va)
+{
+ return _vsnprintf(_out_buffer, buffer, count, format, va);
+}
+
+
+int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ const out_fct_wrap_type out_fct_wrap = { out, arg };
+ const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va);
+ va_end(va);
+ return ret;
+}
diff --git a/src/lib/printf/printf.h b/src/lib/printf/printf.h
new file mode 100644
index 00000000..18cca76c
--- /dev/null
+++ b/src/lib/printf/printf.h
@@ -0,0 +1,112 @@
+///////////////////////////////////////////////////////////////////////////////
+// \author (c) Marco Paland (info@paland.com)
+// 2014-2019, PALANDesign Hannover, Germany
+//
+// \license The MIT License (MIT)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on
+// embedded systems with a very limited resources.
+// Use this instead of bloated standard/newlib printf.
+// These routines are thread safe and reentrant.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _PRINTF_H_
+#define _PRINTF_H_
+
+#include
+#include
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * Output a character to a custom device like UART, used by the printf() function
+ * This function is declared here only. You have to write your custom implementation somewhere
+ * \param character Character to output
+ */
+void _putchar(char character);
+
+
+/**
+ * Tiny printf implementation
+ * You have to implement _putchar if you use printf()
+ * To avoid conflicts with the regular printf() API it is overridden by macro defines
+ * and internal underscore-appended functions like usb64_printf() are used
+ * \param format A string that specifies the format of the output
+ * \return The number of characters that are written into the array, not counting the terminating null character
+ */
+int usb64_printf(const char* format, ...);
+
+
+/**
+ * Tiny sprintf implementation
+ * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD!
+ * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output!
+ * \param format A string that specifies the format of the output
+ * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
+ */
+int usb64_sprintf(char* buffer, const char* format, ...);
+
+
+/**
+ * Tiny snprintf/vsnprintf implementation
+ * \param buffer A pointer to the buffer where to store the formatted string
+ * \param count The maximum number of characters to store in the buffer, including a terminating null character
+ * \param format A string that specifies the format of the output
+ * \param va A value identifying a variable arguments list
+ * \return The number of characters that COULD have been written into the buffer, not counting the terminating
+ * null character. A value equal or larger than count indicates truncation. Only when the returned value
+ * is non-negative and less than count, the string has been completely written.
+ */
+int usb64_snprintf(char* buffer, size_t count, const char* format, ...);
+int usb64_vsnprintf(char* buffer, size_t count, const char* format, va_list va);
+
+
+/**
+ * Tiny vprintf implementation
+ * \param format A string that specifies the format of the output
+ * \param va A value identifying a variable arguments list
+ * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
+ */
+int usb64_vprintf(const char* format, va_list va);
+
+
+/**
+ * printf with output function
+ * You may use this as dynamic alternative to printf() with its fixed _putchar() output
+ * \param out An output function which takes one character and an argument pointer
+ * \param arg An argument pointer for user data passed to output function
+ * \param format A string that specifies the format of the output
+ * \return The number of characters that are sent to the output function, not counting the terminating null character
+ */
+int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // _PRINTF_H_
diff --git a/src/lib/tinyalloc b/src/lib/tinyalloc
new file mode 160000
index 00000000..b60fcd7a
--- /dev/null
+++ b/src/lib/tinyalloc
@@ -0,0 +1 @@
+Subproject commit b60fcd7a351dea8a51f3ec95b19fc0d0d2e4dcd9
diff --git a/src/lib/tinyusb b/src/lib/tinyusb
new file mode 160000
index 00000000..4343d1a3
--- /dev/null
+++ b/src/lib/tinyusb
@@ -0,0 +1 @@
+Subproject commit 4343d1a3961e3f92e2aa65f84b59616b51a4eb04
diff --git a/src/lib/tusb_config.h b/src/lib/tusb_config.h
new file mode 100644
index 00000000..1f71dd09
--- /dev/null
+++ b/src/lib/tusb_config.h
@@ -0,0 +1,102 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef _TUSB_CONFIG_H_
+#define _TUSB_CONFIG_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------
+// COMMON CONFIGURATION
+//--------------------------------------------------------------------
+
+// defined by compiler flags for flexibility
+#ifndef CFG_TUSB_MCU
+ #error CFG_TUSB_MCU must be defined
+#endif
+
+#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX
+ #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_HOST | OPT_MODE_FULL_SPEED)
+#elif CFG_TUSB_MCU == OPT_MCU_STM32F7
+#ifdef USB_USB_HS
+ #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED)
+#else
+ #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_FULL_SPEED)
+#endif
+#else
+ #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_HOST | OPT_MODE_FULL_SPEED)
+#endif
+
+#ifndef CFG_TUSB_OS
+#define CFG_TUSB_OS OPT_OS_NONE
+#endif
+
+// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
+// #define CFG_TUSB_DEBUG 0
+
+/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
+ * Tinyusb use follows macros to declare transferring memory so that they can be put
+ * into those specific section.
+ * e.g
+ * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
+ * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
+ */
+#ifndef CFG_TUSB_MEM_SECTION
+#define CFG_TUSB_MEM_SECTION
+#endif
+
+#ifndef CFG_TUSB_MEM_ALIGN
+#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(32)))
+#endif
+
+//--------------------------------------------------------------------
+// CONFIGURATION
+//--------------------------------------------------------------------
+
+// Size of buffer to hold descriptors and other data used for enumeration
+#define CFG_TUH_ENUMERATION_BUFSIZE 512
+
+#define CFG_TUH_HUB 4
+#define CFG_TUH_CDC 0
+#define CFG_TUH_HID 4 // typical keyboard + mouse device can have 3-4 HID interfaces
+#define CFG_TUH_MSC 0
+#define CFG_TUH_VENDOR 0
+#define CFG_TUH_XINPUT 4
+
+// max device support (excluding hub device)
+// 1 hub typically has 4 ports
+#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1)
+
+//------------- HID -------------//
+
+#define CFG_TUH_HID_EP_BUFSIZE 64
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_CONFIG_H_ */
diff --git a/src/lib/xinput_host.c b/src/lib/xinput_host.c
new file mode 100644
index 00000000..304d909a
--- /dev/null
+++ b/src/lib/xinput_host.c
@@ -0,0 +1,488 @@
+// Copyright 2020, Ryan Wendland, usb64
+// SPDX-License-Identifier: MIT
+
+#include "tusb_option.h"
+
+#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_XINPUT)
+
+#include "host/usbh.h"
+#include "host/usbh_classdriver.h"
+#include "xinput_host.h"
+
+typedef struct
+{
+ uint8_t inst_count;
+ xinputh_interface_t instances[CFG_TUH_XINPUT];
+} xinputh_device_t;
+
+static xinputh_device_t _xinputh_dev[CFG_TUH_DEVICE_MAX];
+
+TU_ATTR_ALWAYS_INLINE static inline xinputh_device_t *get_dev(uint8_t dev_addr)
+{
+ return &_xinputh_dev[dev_addr - 1];
+}
+
+TU_ATTR_ALWAYS_INLINE static inline xinputh_interface_t *get_instance(uint8_t dev_addr, uint8_t instance)
+{
+ return &_xinputh_dev[dev_addr - 1].instances[instance];
+}
+
+static uint8_t get_instance_id_by_epaddr(uint8_t dev_addr, uint8_t ep_addr)
+{
+ for (uint8_t inst = 0; inst < CFG_TUH_XINPUT; inst++)
+ {
+ xinputh_interface_t *hid = get_instance(dev_addr, inst);
+
+ if ((ep_addr == hid->ep_in) || (ep_addr == hid->ep_out))
+ return inst;
+ }
+
+ return 0xff;
+}
+
+static uint8_t get_instance_id_by_itfnum(uint8_t dev_addr, uint8_t itf)
+{
+ for (uint8_t inst = 0; inst < CFG_TUH_XINPUT; inst++)
+ {
+ xinputh_interface_t *hid = get_instance(dev_addr, inst);
+
+ if ((hid->itf_num == itf) && (hid->ep_in || hid->ep_out))
+ return inst;
+ }
+
+ return 0xff;
+}
+
+static void wait_for_tx_complete(uint8_t dev_addr, uint8_t ep_out)
+{
+ while (usbh_edpt_busy(dev_addr, ep_out))
+ tuh_task();
+}
+
+bool tuh_xinput_receive_report(uint8_t dev_addr, uint8_t instance)
+{
+ xinputh_interface_t *xid_itf = get_instance(dev_addr, instance);
+ TU_VERIFY(usbh_edpt_claim(dev_addr, xid_itf->ep_in));
+ return usbh_edpt_xfer(dev_addr, xid_itf->ep_in, xid_itf->epin_buf, xid_itf->epin_size);
+}
+
+bool tuh_xinput_send_report(uint8_t dev_addr, uint8_t instance, const uint8_t *txbuf, uint16_t len)
+{
+ xinputh_interface_t *xid_itf = get_instance(dev_addr, instance);
+
+ TU_ASSERT(len <= xid_itf->epout_size);
+ TU_VERIFY(usbh_edpt_claim(dev_addr, xid_itf->ep_out));
+
+ memcpy(xid_itf->epout_buf, txbuf, len);
+ return usbh_edpt_xfer(dev_addr, xid_itf->ep_out, xid_itf->epout_buf, len);
+}
+
+bool tuh_xinput_set_led(uint8_t dev_addr, uint8_t instance, uint8_t quadrant, bool block)
+{
+ xinputh_interface_t *xid_itf = get_instance(dev_addr, instance);
+ uint8_t txbuf[32];
+ uint16_t len;
+ switch (xid_itf->type)
+ {
+ case XBOX360_WIRELESS:
+ memcpy(txbuf, xbox360w_led, sizeof(xbox360w_led));
+ txbuf[3] = (quadrant == 0) ? 0x40 : (0x40 | (quadrant + 5));
+ len = sizeof(xbox360w_led);
+ break;
+ case XBOX360_WIRED:
+ memcpy(txbuf, xbox360_wired_led, sizeof(xbox360_wired_led));
+ txbuf[2] = (quadrant == 0) ? 0 : (quadrant + 5);
+ len = sizeof(xbox360_wired_led);
+ break;
+ default:
+ return true;
+ }
+ bool ret = tuh_xinput_send_report(dev_addr, instance, txbuf, len);
+ if (block && ret)
+ {
+ wait_for_tx_complete(dev_addr, xid_itf->ep_out);
+ }
+ return ret;
+}
+
+bool tuh_xinput_set_rumble(uint8_t dev_addr, uint8_t instance, uint8_t lValue, uint8_t rValue, bool block)
+{
+ xinputh_interface_t *xid_itf = get_instance(dev_addr, instance);
+ uint8_t txbuf[32];
+ uint16_t len;
+
+ switch (xid_itf->type)
+ {
+ case XBOX360_WIRELESS:
+ memcpy(txbuf, xbox360w_rumble, sizeof(xbox360w_rumble));
+ txbuf[5] = lValue;
+ txbuf[6] = rValue;
+ len = sizeof(xbox360w_rumble);
+ break;
+ case XBOX360_WIRED:
+ memcpy(txbuf, xbox360_wired_rumble, sizeof(xbox360_wired_rumble));
+ txbuf[3] = lValue;
+ txbuf[4] = rValue;
+ len = sizeof(xbox360_wired_rumble);
+ break;
+ case XBOXONE:
+ memcpy(txbuf, xboxone_rumble, sizeof(xboxone_rumble));
+ txbuf[8] = lValue / 2.6f; //Scale is 0 to 100
+ txbuf[9] = rValue / 2.6f; //Scale is 0 to 100
+ len = sizeof(xboxone_rumble);
+ break;
+ case XBOXOG:
+ memcpy(txbuf, xboxog_rumble, sizeof(xboxog_rumble));
+ txbuf[2] = lValue;
+ txbuf[3] = lValue;
+ txbuf[4] = rValue;
+ txbuf[5] = rValue;
+ len = sizeof(xboxog_rumble);
+ break;
+ default:
+ return true;
+ }
+ bool ret = tuh_xinput_send_report(dev_addr, instance, txbuf, len);
+ if (block && ret)
+ {
+ wait_for_tx_complete(dev_addr, xid_itf->ep_out);
+ }
+ return true;
+}
+
+//--------------------------------------------------------------------+
+// USBH API
+//--------------------------------------------------------------------+
+void xinputh_init(void)
+{
+ tu_memclr(_xinputh_dev, sizeof(_xinputh_dev));
+}
+
+bool xinputh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len)
+{
+ TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX);
+
+ xinput_type_t type = XINPUT_UNKNOWN;
+ if (desc_itf->bNumEndpoints < 2)
+ type = XINPUT_UNKNOWN;
+ else if (desc_itf->bInterfaceSubClass == 0x5D && //Xbox360 wireless bInterfaceSubClass
+ desc_itf->bInterfaceProtocol == 0x81) //Xbox360 wireless bInterfaceProtocol
+ type = XBOX360_WIRELESS;
+ else if (desc_itf->bInterfaceSubClass == 0x5D && //Xbox360 wired bInterfaceSubClass
+ desc_itf->bInterfaceProtocol == 0x01) //Xbox360 wired bInterfaceProtocol
+ type = XBOX360_WIRED;
+ else if (desc_itf->bInterfaceSubClass == 0x47 && //Xbone and SX bInterfaceSubClass
+ desc_itf->bInterfaceProtocol == 0xD0) //Xbone and SX bInterfaceProtocol
+ type = XBOXONE;
+ else if (desc_itf->bInterfaceClass == 0x58 && //XboxOG bInterfaceClass
+ desc_itf->bInterfaceSubClass == 0x42) //XboxOG bInterfaceSubClass
+ type = XBOXOG;
+
+ if (type == XINPUT_UNKNOWN)
+ {
+ TU_LOG2("XINPUT: Not a valid interface\n");
+ return false;
+ }
+
+ TU_LOG2("XINPUT opening Interface %u (addr = %u)\r\n", desc_itf->bInterfaceNumber, dev_addr);
+
+ xinputh_device_t *xinput_dev = get_dev(dev_addr);
+ TU_ASSERT(xinput_dev->inst_count < CFG_TUH_XINPUT, 0);
+
+ xinputh_interface_t *xid_itf = get_instance(dev_addr, xinput_dev->inst_count);
+ xid_itf->itf_num = desc_itf->bInterfaceNumber;
+ xid_itf->type = type;
+
+ //Parse descriptor for all endpoints and open them
+ uint8_t const *p_desc = (uint8_t const *)desc_itf;
+ int endpoint = 0;
+ int pos = 0;
+ while (endpoint < desc_itf->bNumEndpoints && pos < max_len)
+ {
+ if (tu_desc_type(p_desc) != TUSB_DESC_ENDPOINT)
+ {
+ pos += tu_desc_len(p_desc);
+ p_desc = tu_desc_next(p_desc);
+ continue;
+ }
+ tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *)p_desc;
+ TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType);
+ TU_ASSERT(usbh_edpt_open(rhport, dev_addr, desc_ep));
+ if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_OUT)
+ {
+ xid_itf->ep_out = desc_ep->bEndpointAddress;
+ xid_itf->epout_size = tu_edpt_packet_size(desc_ep);
+ }
+ else
+ {
+ xid_itf->ep_in = desc_ep->bEndpointAddress;
+ xid_itf->epin_size = tu_edpt_packet_size(desc_ep);
+ }
+ endpoint++;
+ pos += tu_desc_len(p_desc);
+ p_desc = tu_desc_next(p_desc);
+ }
+
+ xinput_dev->inst_count++;
+ return true;
+}
+
+bool xinputh_set_config(uint8_t dev_addr, uint8_t itf_num)
+{
+ uint8_t instance = get_instance_id_by_itfnum(dev_addr, itf_num);
+ xinputh_interface_t *xid_itf = get_instance(dev_addr, instance);
+ xid_itf->connected = true;
+
+ if (xid_itf->type == XBOX360_WIRELESS)
+ {
+ //Wireless controllers may not be connected yet.
+ xid_itf->connected = false;
+ tuh_xinput_send_report(dev_addr, instance, xbox360w_inquire_present, sizeof(xbox360w_inquire_present));
+ wait_for_tx_complete(dev_addr, xid_itf->ep_out);
+ }
+ else if (xid_itf->type == XBOX360_WIRED)
+ {
+ }
+ else if (xid_itf->type == XBOXONE)
+ {
+ uint16_t PID, VID;
+ tuh_vid_pid_get(dev_addr, &VID, &PID);
+
+ tuh_xinput_send_report(dev_addr, instance, xboxone_start_input, sizeof(xboxone_start_input));
+ wait_for_tx_complete(dev_addr, xid_itf->ep_out);
+
+ //Init packet for XBONE S/Elite controllers (return from bluetooth mode)
+ if (VID == 0x045e && (PID == 0x02ea || PID == 0x0b00))
+ {
+ tuh_xinput_send_report(dev_addr, instance, xboxone_s_init, sizeof(xboxone_s_init));
+ wait_for_tx_complete(dev_addr, xid_itf->ep_out);
+ }
+
+ //Required for PDP aftermarket controllers
+ if (VID == 0x0e6f)
+ {
+ tuh_xinput_send_report(dev_addr, instance, xboxone_pdp_init1, sizeof(xboxone_pdp_init1));
+ wait_for_tx_complete(dev_addr, xid_itf->ep_out);
+ tuh_xinput_send_report(dev_addr, instance, xboxone_pdp_init2, sizeof(xboxone_pdp_init2));
+ wait_for_tx_complete(dev_addr, xid_itf->ep_out);
+ tuh_xinput_send_report(dev_addr, instance, xboxone_pdp_init3, sizeof(xboxone_pdp_init3));
+ wait_for_tx_complete(dev_addr, xid_itf->ep_out);
+ }
+ }
+
+ if (tuh_xinput_mount_cb)
+ {
+ tuh_xinput_mount_cb(dev_addr, instance, xid_itf);
+ }
+ return true;
+}
+
+bool xinputh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
+{
+ if (result != XFER_RESULT_SUCCESS)
+ {
+ return false;
+ }
+
+ uint8_t const dir = tu_edpt_dir(ep_addr);
+ uint8_t const instance = get_instance_id_by_epaddr(dev_addr, ep_addr);
+ xinputh_interface_t *xid_itf = get_instance(dev_addr, instance);
+ xinput_gamepad_t *pad = &xid_itf->pad;
+ uint8_t *rdata = xid_itf->epin_buf;
+
+ if (dir == TUSB_DIR_IN)
+ {
+ TU_LOG2("Get Report callback (%u, %u, %u bytes)\r\n", dev_addr, instance, xferred_bytes);
+ TU_LOG2_MEM(xid_itf->epin_buf, xferred_bytes, 2);
+ if (xid_itf->type == XBOX360_WIRED)
+ {
+ #define GET_USHORT(a) (uint16_t)((a)[1] << 8 | (a)[0])
+ #define GET_SHORT(a) ((int16_t)GET_USHORT(a))
+ if (rdata[1] == 0x14)
+ {
+ tu_memclr(pad, sizeof(xinput_gamepad_t));
+ uint16_t wButtons = rdata[3] << 8 | rdata[2];
+
+ //Map digital buttons
+ if (wButtons & (1 << 0)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_UP;
+ if (wButtons & (1 << 1)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_DOWN;
+ if (wButtons & (1 << 2)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_LEFT;
+ if (wButtons & (1 << 3)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_RIGHT;
+ if (wButtons & (1 << 4)) pad->wButtons |= XINPUT_GAMEPAD_START;
+ if (wButtons & (1 << 5)) pad->wButtons |= XINPUT_GAMEPAD_BACK;
+ if (wButtons & (1 << 6)) pad->wButtons |= XINPUT_GAMEPAD_LEFT_THUMB;
+ if (wButtons & (1 << 7)) pad->wButtons |= XINPUT_GAMEPAD_RIGHT_THUMB;
+ if (wButtons & (1 << 8)) pad->wButtons |= XINPUT_GAMEPAD_LEFT_SHOULDER;
+ if (wButtons & (1 << 9)) pad->wButtons |= XINPUT_GAMEPAD_RIGHT_SHOULDER;
+ if (wButtons & (1 << 12)) pad->wButtons |= XINPUT_GAMEPAD_A;
+ if (wButtons & (1 << 13)) pad->wButtons |= XINPUT_GAMEPAD_B;
+ if (wButtons & (1 << 14)) pad->wButtons |= XINPUT_GAMEPAD_X;
+ if (wButtons & (1 << 15)) pad->wButtons |= XINPUT_GAMEPAD_Y;
+
+ //Map the left and right triggers
+ pad->bLeftTrigger = rdata[4];
+ pad->bRightTrigger = rdata[5];
+
+ //Map analog sticks
+ pad->sThumbLX = rdata[7] << 8 | rdata[6];
+ pad->sThumbLY = rdata[9] << 8 | rdata[8];
+ pad->sThumbRX = rdata[11] << 8 | rdata[10];
+ pad->sThumbRY = rdata[13] << 8 | rdata[12];
+
+ xid_itf->new_pad_data = true;
+ }
+ }
+ else if (xid_itf->type == XBOX360_WIRELESS)
+ {
+ //Connect/Disconnect packet
+ if (rdata[0] & 0x08)
+ {
+ if (rdata[1] != 0x00 && xid_itf->connected == false)
+ {
+ TU_LOG2("XINPUT: WIRELESS CONTROLLER CONNECTED\n");
+ xid_itf->connected = true;
+ }
+ else if (rdata[1] == 0x00 && xid_itf->connected == true)
+ {
+ TU_LOG2("XINPUT: WIRELESS CONTROLLER DISCONNECTED\n");
+ xid_itf->connected = false;
+ }
+ }
+
+ //Button status packet
+ if ((rdata[1] & 1) && rdata[5] == 0x13)
+ {
+ tu_memclr(pad, sizeof(xinput_gamepad_t));
+ uint16_t wButtons = rdata[7] << 8 | rdata[6];
+
+ //Map digital buttons
+ if (wButtons & (1 << 0)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_UP;
+ if (wButtons & (1 << 1)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_DOWN;
+ if (wButtons & (1 << 2)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_LEFT;
+ if (wButtons & (1 << 3)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_RIGHT;
+ if (wButtons & (1 << 4)) pad->wButtons |= XINPUT_GAMEPAD_START;
+ if (wButtons & (1 << 5)) pad->wButtons |= XINPUT_GAMEPAD_BACK;
+ if (wButtons & (1 << 6)) pad->wButtons |= XINPUT_GAMEPAD_LEFT_THUMB;
+ if (wButtons & (1 << 7)) pad->wButtons |= XINPUT_GAMEPAD_RIGHT_THUMB;
+ if (wButtons & (1 << 8)) pad->wButtons |= XINPUT_GAMEPAD_LEFT_SHOULDER;
+ if (wButtons & (1 << 9)) pad->wButtons |= XINPUT_GAMEPAD_RIGHT_SHOULDER;
+ if (wButtons & (1 << 12)) pad->wButtons |= XINPUT_GAMEPAD_A;
+ if (wButtons & (1 << 13)) pad->wButtons |= XINPUT_GAMEPAD_B;
+ if (wButtons & (1 << 14)) pad->wButtons |= XINPUT_GAMEPAD_X;
+ if (wButtons & (1 << 15)) pad->wButtons |= XINPUT_GAMEPAD_Y;
+
+ //Map the left and right triggers
+ pad->bLeftTrigger = rdata[8];
+ pad->bRightTrigger = rdata[9];
+
+ //Map analog sticks
+ pad->sThumbLX = rdata[11] << 8 | rdata[10];
+ pad->sThumbLY = rdata[13] << 8 | rdata[12];
+ pad->sThumbRX = rdata[15] << 8 | rdata[14];
+ pad->sThumbRY = rdata[17] << 8 | rdata[16];
+
+ xid_itf->new_pad_data = true;
+ }
+ }
+ else if (xid_itf->type == XBOXONE)
+ {
+ if (rdata[0] == 0x20)
+ {
+ tu_memclr(pad, sizeof(xinput_gamepad_t));
+ uint16_t wButtons = rdata[5] << 8 | rdata[4];
+
+ //Map digital buttons
+ if (wButtons & (1 << 8)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_UP;
+ if (wButtons & (1 << 9)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_DOWN;
+ if (wButtons & (1 << 10)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_LEFT;
+ if (wButtons & (1 << 11)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_RIGHT;
+ if (wButtons & (1 << 2)) pad->wButtons |= XINPUT_GAMEPAD_START;
+ if (wButtons & (1 << 3)) pad->wButtons |= XINPUT_GAMEPAD_BACK;
+ if (wButtons & (1 << 14)) pad->wButtons |= XINPUT_GAMEPAD_LEFT_THUMB;
+ if (wButtons & (1 << 15)) pad->wButtons |= XINPUT_GAMEPAD_RIGHT_THUMB;
+ if (wButtons & (1 << 12)) pad->wButtons |= XINPUT_GAMEPAD_LEFT_SHOULDER;
+ if (wButtons & (1 << 13)) pad->wButtons |= XINPUT_GAMEPAD_RIGHT_SHOULDER;
+ if (wButtons & (1 << 4)) pad->wButtons |= XINPUT_GAMEPAD_A;
+ if (wButtons & (1 << 5)) pad->wButtons |= XINPUT_GAMEPAD_B;
+ if (wButtons & (1 << 6)) pad->wButtons |= XINPUT_GAMEPAD_X;
+ if (wButtons & (1 << 7)) pad->wButtons |= XINPUT_GAMEPAD_Y;
+
+ //Map the left and right triggers
+ pad->bLeftTrigger = (rdata[7] << 8 | rdata[6]) >> 2;
+ pad->bRightTrigger = (rdata[9] << 8 | rdata[8]) >> 2;
+
+ //Map analog sticks
+ pad->sThumbLX = rdata[11] << 8 | rdata[10];
+ pad->sThumbLY = rdata[13] << 8 | rdata[12];
+ pad->sThumbRX = rdata[15] << 8 | rdata[14];
+ pad->sThumbRY = rdata[17] << 8 | rdata[16];
+
+ xid_itf->new_pad_data = true;
+ }
+ }
+ else if (xid_itf->type == XBOXOG)
+ {
+ if (rdata[1] == 0x14)
+ {
+ tu_memclr(pad, sizeof(xinput_gamepad_t));
+ uint16_t wButtons = rdata[3] << 8 | rdata[2];
+
+ //Map digital buttons
+ if (wButtons & (1 << 0)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_UP;
+ if (wButtons & (1 << 1)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_DOWN;
+ if (wButtons & (1 << 2)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_LEFT;
+ if (wButtons & (1 << 3)) pad->wButtons |= XINPUT_GAMEPAD_DPAD_RIGHT;
+ if (wButtons & (1 << 4)) pad->wButtons |= XINPUT_GAMEPAD_START;
+ if (wButtons & (1 << 5)) pad->wButtons |= XINPUT_GAMEPAD_BACK;
+ if (wButtons & (1 << 6)) pad->wButtons |= XINPUT_GAMEPAD_LEFT_THUMB;
+ if (wButtons & (1 << 7)) pad->wButtons |= XINPUT_GAMEPAD_RIGHT_THUMB;
+
+ if (rdata[4] > 0x20) pad->wButtons |= XINPUT_GAMEPAD_A;
+ if (rdata[5] > 0x20) pad->wButtons |= XINPUT_GAMEPAD_B;
+ if (rdata[6] > 0x20) pad->wButtons |= XINPUT_GAMEPAD_X;
+ if (rdata[7] > 0x20) pad->wButtons |= XINPUT_GAMEPAD_Y;
+ if (rdata[8] > 0x20) pad->wButtons |= XINPUT_GAMEPAD_RIGHT_SHOULDER;
+ if (rdata[9] > 0x20) pad->wButtons |= XINPUT_GAMEPAD_LEFT_SHOULDER;
+
+ //Map the left and right triggers
+ pad->bLeftTrigger = rdata[10];
+ pad->bRightTrigger = rdata[11];
+
+ //Map analog sticks
+ pad->sThumbLX = rdata[13] << 8 | rdata[12];
+ pad->sThumbLY = rdata[15] << 8 | rdata[14];
+ pad->sThumbRX = rdata[17] << 8 | rdata[16];
+ pad->sThumbRY = rdata[19] << 8 | rdata[18];
+
+ xid_itf->new_pad_data = true;
+ }
+ }
+ tuh_xinput_report_received_cb(dev_addr, instance, (const uint8_t *)xid_itf, sizeof(xinputh_interface_t));
+ xid_itf->new_pad_data = false;
+ }
+ else
+ {
+ if (tuh_xinput_report_sent_cb)
+ {
+ tuh_xinput_report_sent_cb(dev_addr, instance, xid_itf->epout_buf, xferred_bytes);
+ }
+ }
+
+ return true;
+}
+
+void xinputh_close(uint8_t dev_addr)
+{
+ xinputh_device_t *xinput_dev = get_dev(dev_addr);
+
+ for (uint8_t inst = 0; inst < xinput_dev->inst_count; inst++)
+ {
+ if (tuh_xinput_umount_cb)
+ {
+ tuh_xinput_umount_cb(dev_addr, inst);
+ }
+ }
+ tu_memclr(xinput_dev, sizeof(xinputh_device_t));
+}
+
+#endif
diff --git a/src/lib/xinput_host.h b/src/lib/xinput_host.h
new file mode 100644
index 00000000..489b10f1
--- /dev/null
+++ b/src/lib/xinput_host.h
@@ -0,0 +1,128 @@
+// Copyright 2020, Ryan Wendland, usb64
+// SPDX-License-Identifier: MIT
+
+#ifndef _TUSB_XINPUT_HOST_H_
+#define _TUSB_XINPUT_HOST_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+// Class Driver Configuration
+//--------------------------------------------------------------------+
+
+#ifndef CFG_TUH_XINPUT_EPIN_BUFSIZE
+#define CFG_TUH_XINPUT_EPIN_BUFSIZE 64
+#endif
+
+#ifndef CFG_TUH_XINPUT_EPOUT_BUFSIZE
+#define CFG_TUH_XINPUT_EPOUT_BUFSIZE 64
+#endif
+
+//XINPUT defines and struct format from
+//https://docs.microsoft.com/en-us/windows/win32/api/xinput/ns-xinput-xinput_gamepad
+#define XINPUT_GAMEPAD_DPAD_UP 0x0001
+#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002
+#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004
+#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
+#define XINPUT_GAMEPAD_START 0x0010
+#define XINPUT_GAMEPAD_BACK 0x0020
+#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040
+#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
+#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
+#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
+#define XINPUT_GAMEPAD_A 0x1000
+#define XINPUT_GAMEPAD_B 0x2000
+#define XINPUT_GAMEPAD_X 0x4000
+#define XINPUT_GAMEPAD_Y 0x8000
+#define MAX_PACKET_SIZE 32
+
+typedef struct xinput_gamepad
+{
+ uint16_t wButtons;
+ uint8_t bLeftTrigger;
+ uint8_t bRightTrigger;
+ int16_t sThumbLX;
+ int16_t sThumbLY;
+ int16_t sThumbRX;
+ int16_t sThumbRY;
+} xinput_gamepad_t;
+
+typedef enum
+{
+ XINPUT_UNKNOWN = 0,
+ XBOXONE,
+ XBOX360_WIRELESS,
+ XBOX360_WIRED,
+ XBOXOG
+} xinput_type_t;
+
+typedef struct
+{
+ xinput_type_t type;
+ xinput_gamepad_t pad;
+ uint8_t connected;
+ uint8_t new_pad_data;
+ uint8_t itf_num;
+ uint8_t ep_in;
+ uint8_t ep_out;
+
+ uint16_t epin_size;
+ uint16_t epout_size;
+
+ uint8_t epin_buf[CFG_TUH_XINPUT_EPIN_BUFSIZE];
+ uint8_t epout_buf[CFG_TUH_XINPUT_EPOUT_BUFSIZE];
+} xinputh_interface_t;
+
+void tuh_xinput_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len);
+TU_ATTR_WEAK void tuh_xinput_report_sent_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len);
+TU_ATTR_WEAK void tuh_xinput_umount_cb(uint8_t dev_addr, uint8_t instance);
+TU_ATTR_WEAK void tuh_xinput_mount_cb(uint8_t dev_addr, uint8_t instance, const xinputh_interface_t *xinput_itf);
+bool tuh_xinput_receive_report(uint8_t dev_addr, uint8_t instance);
+bool tuh_xinput_send_report(uint8_t dev_addr, uint8_t instance, const uint8_t *txbuf, uint16_t len);
+bool tuh_xinput_set_led(uint8_t dev_addr, uint8_t instance, uint8_t quadrant, bool block);
+bool tuh_xinput_set_rumble(uint8_t dev_addr, uint8_t instance, uint8_t lValue, uint8_t rValue, bool block);
+
+//--------------------------------------------------------------------+
+// Internal Class Driver API
+//--------------------------------------------------------------------+
+void xinputh_init (void);
+bool xinputh_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len);
+bool xinputh_set_config (uint8_t dev_addr, uint8_t itf_num);
+bool xinputh_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
+void xinputh_close (uint8_t dev_addr);
+
+//Wired 360 commands
+static const uint8_t xbox360_wired_rumble[] = {0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const uint8_t xbox360_wired_led[] = {0x01, 0x03, 0x00};
+
+//Xbone one
+static const uint8_t xboxone_start_input[] = {0x05, 0x20, 0x03, 0x01, 0x00};
+static const uint8_t xboxone_s_init[] = {0x05, 0x20, 0x00, 0x0f, 0x06};
+static const uint8_t xboxone_pdp_init1[] = {0x0a, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14};
+static const uint8_t xboxone_pdp_init2[] = {0x06, 0x30};
+static const uint8_t xboxone_pdp_init3[] = {0x06, 0x20, 0x00, 0x02, 0x01, 0x00};
+static const uint8_t xboxone_rumble[] = {0x09, 0x00, 0x00, 0x09, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xEB};
+
+//Wireless 360 commands
+static const uint8_t xbox360w_led[] = {0x00, 0x00, 0x08, 0x40};
+//Sending 0x00, 0x00, 0x08, 0x00 will permanently disable rumble until you do this:
+static const uint8_t xbox360w_rumble_enable[] = {0x00, 0x00, 0x08, 0x01};
+static const uint8_t xbox360w_rumble[] = {0x00, 0x01, 0x0F, 0xC0, 0x00, 0x00};
+static const uint8_t xbox360w_inquire_present[] = {0x08, 0x00, 0x0F, 0xC0};
+static const uint8_t xbox360w_controller_info[] = {0x00, 0x00, 0x00, 0x40};
+static const uint8_t xbox360w_unknown[] = {0x00, 0x00, 0x02, 0x80};
+static const uint8_t xbox360w_power_off[] = {0x00, 0x00, 0x08, 0xC0};
+static const uint8_t xbox360w_chatpad_init[] = {0x00, 0x00, 0x0C, 0x1B};
+static const uint8_t xbox360w_chatpad_keepalive1[] = {0x00, 0x00, 0x0C, 0x1F};
+static const uint8_t xbox360w_chatpad_keepalive2[] = {0x00, 0x00, 0x0C, 0x1E};
+
+//Original Xbox
+static const uint8_t xboxog_rumble[] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TUSB_XINPUT_HOST_H_ */
diff --git a/src/main.cpp b/src/main.cpp
index bd17e05c..b746dd85 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,21 +1,15 @@
// Copyright 2020, Ryan Wendland, usb64
// SPDX-License-Identifier: MIT
-#include
+#include "common.h"
#include "input.h"
-#include "printf.h"
-#include "n64_wrapper.h"
-#include "usb64_conf.h"
#include "n64_controller.h"
-#include "n64_transferpak_gbcarts.h"
-#include "n64_virtualpak.h"
-#include "n64_settings.h"
#include "analog_stick.h"
#include "memory.h"
#include "fileio.h"
#include "tft.h"
-
+void usbh_dev_init(void);
static void ring_buffer_init(void);
static void ring_buffer_flush();
@@ -48,25 +42,38 @@ void n64_controller4_clock_edge()
}
#endif
-extern "C" {
-FLASHMEM void startup_early_hook(void)
+#ifdef CFG_TUSB_DEBUG_PRINTF
+extern "C" int CFG_TUSB_DEBUG_PRINTF(const char *format, ...)
{
- //Get these up as early as possible.
- pinMode(N64_CONTROLLER_1_PIN, INPUT_PULLUP);
- pinMode(N64_CONTROLLER_2_PIN, INPUT_PULLUP);
- pinMode(N64_CONTROLLER_3_PIN, INPUT_PULLUP);
- pinMode(N64_CONTROLLER_4_PIN, INPUT_PULLUP);
- pinMode(N64_CONSOLE_SENSE, INPUT_PULLDOWN);
+ va_list args;
+ va_start(args, format);
+ usb64_vprintf(format, args);
+ return 1;
}
+#endif
+
+#ifndef ARDUINO
+void setup();
+void loop();
+int main(void)
+{
+ setup();
+ while(1)
+ {
+ loop();
+ }
}
+#endif
void setup()
{
- //Init the serial port and ring buffer
- serial_port.begin(256000);
+ n64hal_system_init();
+ n64hal_debug_init();
+ n64hal_gpio_init();
ring_buffer_init();
fileio_init();
memory_init();
+ usbh_dev_init();
input_init();
tft_init();
n64_subsystem_init(n64_in_dev);
@@ -74,55 +81,6 @@ void setup()
//Read in settings from flash
settings = (n64_settings *)memory_alloc_ram(SETTINGS_FILENAME, sizeof(n64_settings), MEMORY_READ_WRITE);
n64_settings_init(settings);
-
- //Set up N64 sense pin. To determine is the N64 is turned on or off
- //Input is connected to the N64 3V3 line on the controller port.
- pinMode(N64_CONSOLE_SENSE, INPUT_PULLDOWN);
-
- pinMode(N64_FRAME, OUTPUT);
-
- pinMode(USER_LED_PIN, OUTPUT);
-
-#if (ENABLE_HARDWIRED_CONTROLLER >=1)
- pinMode(HW_A, INPUT_PULLUP);
- pinMode(HW_B, INPUT_PULLUP);
- pinMode(HW_CU, INPUT_PULLUP);
- pinMode(HW_CD, INPUT_PULLUP);
- pinMode(HW_CL, INPUT_PULLUP);
- pinMode(HW_CR, INPUT_PULLUP);
- pinMode(HW_DU, INPUT_PULLUP);
- pinMode(HW_DD, INPUT_PULLUP);
- pinMode(HW_DL, INPUT_PULLUP);
- pinMode(HW_DR, INPUT_PULLUP);
- pinMode(HW_START, INPUT_PULLUP);
- pinMode(HW_Z, INPUT_PULLUP);
- pinMode(HW_R, INPUT_PULLUP);
- pinMode(HW_L, INPUT_PULLUP);
- pinMode(HW_EN, INPUT_PULLUP);
- pinMode(HW_RUMBLE, OUTPUT);
-#endif
-
-#if (MAX_CONTROLLERS >= 1)
- n64_in_dev[0].gpio_pin = N64_CONTROLLER_1_PIN;
- pinMode(N64_CONTROLLER_1_PIN, INPUT_PULLUP);
-#endif
-
-#if (MAX_CONTROLLERS >= 2)
- n64_in_dev[1].gpio_pin = N64_CONTROLLER_2_PIN;
- pinMode(N64_CONTROLLER_2_PIN, INPUT_PULLUP);
-#endif
-
-#if (MAX_CONTROLLERS >= 3)
- n64_in_dev[2].gpio_pin = N64_CONTROLLER_3_PIN;
- pinMode(N64_CONTROLLER_3_PIN, INPUT_PULLUP);
-#endif
-
-#if (MAX_CONTROLLERS >= 4)
- n64_in_dev[3].gpio_pin = N64_CONTROLLER_4_PIN;
- pinMode(N64_CONTROLLER_4_PIN, INPUT_PULLUP);
-#endif
- NVIC_SET_PRIORITY(IRQ_GPIO6789, 1);
- digitalWrite(USER_LED_PIN, HIGH);
}
static bool n64_combo = false;
@@ -134,7 +92,9 @@ void loop()
input_update_input_devices();
+#if (ENABLE_TFT_DISPLAY >= 1)
tft_try_update();
+#endif
for (uint32_t c = 0; c < MAX_CONTROLLERS; c++)
{
@@ -144,14 +104,15 @@ void loop()
{
switch (c)
{
- case 0: attachInterrupt(digitalPinToInterrupt(n64_in_dev[c].gpio_pin), n64_controller1_clock_edge, FALLING); break;
- case 1: attachInterrupt(digitalPinToInterrupt(n64_in_dev[c].gpio_pin), n64_controller2_clock_edge, FALLING); break;
- case 2: attachInterrupt(digitalPinToInterrupt(n64_in_dev[c].gpio_pin), n64_controller3_clock_edge, FALLING); break;
- case 3: attachInterrupt(digitalPinToInterrupt(n64_in_dev[c].gpio_pin), n64_controller4_clock_edge, FALLING); break;
+ case 0: n64hal_attach_interrupt(n64_in_dev[c].pin, n64_controller1_clock_edge, N64_INTMODE_FALLING); break;
+ case 1: n64hal_attach_interrupt(n64_in_dev[c].pin, n64_controller2_clock_edge, N64_INTMODE_FALLING); break;
+ case 2: n64hal_attach_interrupt(n64_in_dev[c].pin, n64_controller3_clock_edge, N64_INTMODE_FALLING); break;
+ case 3: n64hal_attach_interrupt(n64_in_dev[c].pin, n64_controller4_clock_edge, N64_INTMODE_FALLING); break;
}
n64_in_dev[c].interrupt_attached = true;
+ tft_flag_update();
}
- if (input_is_gamecontroller(c))
+ if (input_is(c, INPUT_GAMECONTROLLER))
{
n64_buttonmap *new_state = (n64_buttonmap *)n64_response[c];
input_get_state(c, new_state, &n64_combo);
@@ -191,7 +152,7 @@ void loop()
}
}
#if (MAX_MICE >= 1)
- else if (input_is_mouse(c))
+ else if (input_is(c, INPUT_MOUSE))
{
n64_buttonmap *new_state = (n64_buttonmap *)n64_response[c];
input_get_state(c, new_state, &n64_combo);
@@ -207,7 +168,7 @@ void loop()
}
#endif
#if (MAX_KB >= 1)
- else if (input_is_kb(c))
+ else if (input_is(c, INPUT_KEYBOARD))
{
n64_randnet_kb *new_state = (n64_randnet_kb *)n64_response[c];
//Maintain the old led state
@@ -228,12 +189,13 @@ void loop()
if ((!input_is_connected(c) || !n64_is_on) && n64_in_dev[c].interrupt_attached)
{
n64_in_dev[c].interrupt_attached = false;
- detachInterrupt(digitalPinToInterrupt(n64_in_dev[c].gpio_pin));
+ n64hal_detach_interrupt(n64_in_dev[c].pin);
+ tft_flag_update();
}
//Get a copy of the latest n64 button presses to handle the below combos
uint16_t n64_buttons = 0;
- if (input_is_gamecontroller(c))
+ if (input_is(c, INPUT_GAMECONTROLLER))
{
n64_buttonmap *new_state = (n64_buttonmap *)n64_response[c];
n64_buttons = new_state->dButtons;
@@ -246,6 +208,8 @@ void loop()
input_apply_rumble(c, 0xFF);
if (n64_in_dev[c].rpak->state == RUMBLE_STOP)
input_apply_rumble(c, 0x00);
+ if (n64_in_dev[c].rpak->state != RUMBLE_APPLIED && ENABLE_HARDWIRED_CONTROLLER)
+ n64hal_output_set(HW_RUMBLE, n64_in_dev[c].rpak->state == RUMBLE_START);
n64_in_dev[c].rpak->state = RUMBLE_APPLIED;
}
@@ -267,7 +231,7 @@ void loop()
//Handle ram flushing. Auto flushes when the N64 is turned off :)
static uint32_t flushing_toggle[MAX_CONTROLLERS] = {0};
- n64_is_on = digitalRead(N64_CONSOLE_SENSE);
+ n64_is_on = n64hal_input_read(N64_CONSOLE_SENSE_PIN);
if ((n64_combo && (n64_buttons & N64_A)) || (n64_is_on == 0))
{
if (flushing_toggle[c] == 0)
@@ -301,14 +265,6 @@ void loop()
{
tft_toggle[c] = 0;
}
-
- //Measure Teensy temp and if it has changed, flag a TFT update
- static int32_t teensy_temp = 0;
- if (abs((int32_t)tempmonGetTemp() - teensy_temp) > 2)
- {
- teensy_temp = (int32_t)tempmonGetTemp();
- tft_flag_update();
- }
#endif
//Handle peripheral change combinations
@@ -324,13 +280,13 @@ void loop()
if (n64_in_dev[c].current_peripheral == PERI_NONE)
break; //Already changing peripheral
- timer_peri_change[c] = millis();
+ timer_peri_change[c] = n64hal_millis();
/* CLEAR CURRENT PERIPHERALS */
- if (n64_in_dev[c].mempack != NULL)
+ if (n64_in_dev[c].cpak != NULL)
{
- n64_in_dev[c].mempack->data = NULL;
- n64_in_dev[c].mempack->id = VIRTUAL_PAK;
+ n64_in_dev[c].cpak->data = NULL;
+ n64_in_dev[c].cpak->id = VIRTUAL_PAK;
}
if (n64_in_dev[c].tpak != NULL)
@@ -363,7 +319,7 @@ void loop()
//Changing peripheral to RUMBLEPAK
if (n64_buttons & N64_LB)
{
- n64_in_dev[c].next_peripheral = PERI_RUMBLE;
+ n64_in_dev[c].next_peripheral = PERI_RPAK;
debug_print_status("[MAIN] C%u to rpak\n", c);
}
@@ -399,7 +355,7 @@ void loop()
if (gb_cart->rom == NULL || (gb_cart->ram == NULL && gb_cart->ramsize > 0))
{
- n64_in_dev[c].next_peripheral = PERI_RUMBLE; //Error, just set to rumblepak
+ n64_in_dev[c].next_peripheral = PERI_RPAK; //Error, just set to rumblepak
debug_print_error("[MAIN] ERROR: Could not allocate rom or ram buffer for %s\n", n64_in_dev[c].tpak->gbcart->filename);
n64_in_dev[c].tpak->gbcart->romsize = 0;
n64_in_dev[c].tpak->gbcart->ramsize = 0;
@@ -409,7 +365,7 @@ void loop()
}
else
{
- n64_in_dev[c].next_peripheral = PERI_RUMBLE; //Error, just set to rumblepak
+ n64_in_dev[c].next_peripheral = PERI_RPAK; //Error, just set to rumblepak
if (gb_cart->filename[0] == '\0')
debug_print_error("[MAIN] ERROR: No default TPAK ROM set or no ROMs found\n");
else if (memory_get_ext_ram_size() == 0)
@@ -419,76 +375,77 @@ void loop()
}
}
- //Changing peripheral to MEMPAK
+ //Changing peripheral to CPAK
if ((n64_buttons & N64_DU || n64_buttons & N64_DD ||
n64_buttons & N64_DL || n64_buttons & N64_DR ||
n64_buttons & N64_ST))
{
- n64_in_dev[c].next_peripheral = PERI_MEMPAK;
+ n64_in_dev[c].next_peripheral = PERI_CPAK;
- //Allocate mempack based on combo if available
- uint32_t mempak_bank = 0;
+ //Allocate cpak based on combo if available
+ uint32_t cpak_bank_num = 0;
uint16_t b = n64_buttons;
- (b & N64_DU) ? mempak_bank = 0 : (0);
- (b & N64_DR) ? mempak_bank = 1 : (0);
- (b & N64_DD) ? mempak_bank = 2 : (0);
- (b & N64_DL) ? mempak_bank = 3 : (0);
- (b & N64_ST) ? mempak_bank = VIRTUAL_PAK : (0);
+ (b & N64_DU) ? cpak_bank_num = 0 : (0);
+ (b & N64_DR) ? cpak_bank_num = 1 : (0);
+ (b & N64_DD) ? cpak_bank_num = 2 : (0);
+ (b & N64_DL) ? cpak_bank_num = 3 : (0);
+ (b & N64_ST) ? cpak_bank_num = VIRTUAL_PAK : (0);
//Create the filename
char filename[32];
- snprintf(filename, sizeof(filename), "MEMPAK%02u%s", mempak_bank, MEMPAK_SAVE_EXT);
+ snprintf(filename, sizeof(filename), "CONTROLLER_PAK_%02u%s", (unsigned int)cpak_bank_num, CPAK_SAVE_EXT);
- //Scan controllers to see if mempack is in use
+ //Scan controllers to see if cpak is in use
for (uint32_t i = 0; i < MAX_CONTROLLERS; i++)
{
- if (n64_in_dev[i].mempack->id == mempak_bank && mempak_bank != VIRTUAL_PAK)
+ if (n64_in_dev[i].cpak->id == cpak_bank_num && cpak_bank_num != VIRTUAL_PAK)
{
- debug_print_status("[MAIN] WARNING: mpak in use by C%u. Setting to rpak\n", i);
- n64_in_dev[c].next_peripheral = PERI_RUMBLE;
+ debug_print_status("[MAIN] WARNING: cpak in use by C%u. Setting to rpak\n", i);
+ n64_in_dev[c].next_peripheral = PERI_RPAK;
break;
}
}
- //Mempack wasn't in use, so allocate it in ram
- if (n64_in_dev[c].next_peripheral != PERI_RUMBLE && mempak_bank != VIRTUAL_PAK)
+ //cpak wasn't in use, so allocate it in ram
+ if (n64_in_dev[c].next_peripheral != PERI_RPAK && cpak_bank_num != VIRTUAL_PAK)
{
- n64_in_dev[c].mempack->data = memory_alloc_ram(filename, MEMPAK_SIZE, MEMORY_READ_WRITE);
+ n64_in_dev[c].cpak->data = memory_alloc_ram(filename, CPAK_SIZE, MEMORY_READ_WRITE);
+ //TODO: create an initalized CPAK data if file is empty or does not exist?!
}
- if (n64_in_dev[c].mempack->data != NULL)
+ if (n64_in_dev[c].cpak->data != NULL)
{
- debug_print_status("[MAIN] C%u to mpak %u\n", c, mempak_bank);
- n64_in_dev[c].mempack->virtual_is_active = 0;
- n64_in_dev[c].mempack->id = mempak_bank;
+ debug_print_status("[MAIN] C%u to cpak %u\n", c, cpak_bank_num);
+ n64_in_dev[c].cpak->virtual_is_active = 0;
+ n64_in_dev[c].cpak->id = cpak_bank_num;
}
- else if (mempak_bank == VIRTUAL_PAK)
+ else if (cpak_bank_num == VIRTUAL_PAK)
{
- debug_print_status("[MAIN] C%u to virtual pak\n", c);
- n64_virtualpak_init(n64_in_dev[c].mempack);
+ debug_print_status("[MAIN] C%u to virtual cpak\n", c);
+ n64_virtualpak_init(n64_in_dev[c].cpak);
}
else
{
debug_print_error("[MAIN] ERROR: Could not alloc RAM for %s, setting to rpak\n", filename);
- n64_in_dev[c].next_peripheral = PERI_RUMBLE;
+ n64_in_dev[c].next_peripheral = PERI_RPAK;
}
}
}
//Simulate a peripheral change time. The peripheral goes to NONE
//for a short period. Some games need this.
- if (n64_in_dev[c].current_peripheral == PERI_NONE && (millis() - timer_peri_change[c]) > PERI_CHANGE_TIME)
+ if (n64_in_dev[c].current_peripheral == PERI_NONE && (n64hal_millis() - timer_peri_change[c]) > PERI_CHANGE_TIME)
{
n64_in_dev[c].current_peripheral = n64_in_dev[c].next_peripheral;
tft_flag_update();
}
//Update the virtual pak if required
- if (n64_in_dev[c].mempack->virtual_update_req == 1)
+ if (n64_in_dev[c].cpak->virtual_update_req == 1)
{
//For the USB64-INFO1 Page, I write the controller info (PID,VID etc)
char msg[256];
- n64_virtualpak_update(n64_in_dev[c].mempack); //Update so we get the right page
+ n64_virtualpak_update(n64_in_dev[c].cpak); //Update so we get the right page
uint8_t c_page = n64_virtualpak_get_controller_page();
sprintf(msg, "%u:0x%04x/0x%04x\n%.15s\n%.15s\n",
c_page + 1,
@@ -499,19 +456,25 @@ void loop()
n64_virtualpak_write_info_1(msg);
//Normal update
- n64_virtualpak_update(n64_in_dev[c].mempack);
+ n64_virtualpak_update(n64_in_dev[c].cpak);
}
} //END FOR LOOP
+
+ if (check_rom_info_changed() == 1)
+ {
+ reset_rom_info_changed();
+ tft_flag_update();
+ }
+
} // MAIN LOOP
/* PRINTF HANDLING */
static uint32_t ring_buffer_pos = 0;
static char ring_buffer[4096];
-void _putchar(char character)
+extern "C" void _putchar(char character)
{
ring_buffer[ring_buffer_pos] = character;
- tft_add_log(character);
ring_buffer_pos = (ring_buffer_pos + 1) % sizeof(ring_buffer);
}
@@ -525,7 +488,8 @@ static void ring_buffer_flush()
static uint32_t _print_cursor = 0;
while (ring_buffer[_print_cursor] != 0xFF)
{
- serial_port.write(ring_buffer[_print_cursor]);
+ n64hal_debug_write(ring_buffer[_print_cursor]);
+ tft_add_log(ring_buffer[_print_cursor]);
ring_buffer[_print_cursor] = 0xFF;
_print_cursor = (_print_cursor + 1) % sizeof(ring_buffer);
}
diff --git a/src/memory.cpp b/src/memory.cpp
index 29eb43dd..a4775e5e 100644
--- a/src/memory.cpp
+++ b/src/memory.cpp
@@ -11,26 +11,23 @@
* and automatically flushes for you atleast. You can also manual flush with a button combo.
*/
-#include
+#include "common.h"
#include "memory.h"
-#include "usb64_conf.h"
+#include "common.h"
#include "fileio.h"
-#include "printf.h"
-extern uint8_t external_psram_size; //in MB. Set in startup.c
-EXTMEM uint8_t ext_ram[1]; //Just to get the start of EXTMEM
-static uint32_t internal_size = 32768; //Smaller than this will malloc to internal RAM instead
static sram_storage sram[32] = {0};
-void memory_init()
+FLASHMEM void memory_init()
{
- if (external_psram_size == 0)
- return;
-
- debug_print_memory("[MEMORY] External memory initialised\n");
- debug_print_memory("[MEMORY] Detected %uMB\n", external_psram_size);
- debug_print_memory("[MEMORY] Heap start: %08x\n", (uint32_t)ext_ram);
- debug_print_memory("[MEMORY] Heap end: %08x\n", (uint32_t)ext_ram + external_psram_size * 1024 * 1024);
+ if (!memory_dev_init())
+ {
+ debug_print_memory("[MEMORY] Warning: External memory not initialised\n");
+ }
+ else
+ {
+ debug_print_memory("[MEMORY] External memory initialised\n");
+ }
}
//This function allocates and manages SRAM for mempak and gameboy roms (tpak) for the system.
@@ -52,19 +49,13 @@ uint8_t *memory_alloc_ram(const char *name, uint32_t alloc_len, uint32_t read_on
//Already malloced, check len is ok
if (sram[i].len <= alloc_len)
{
- debug_print_memory("[MEMORY] Memory already malloced for %s at 0x%08x, returning pointer to it\n", name, sram[i].data);
+ debug_print_memory("[MEMORY] Memory already malloced for %s at 0x%llx, returning pointer to it\n", name, (uintptr_t)sram[i].data);
return sram[i].data;
}
debug_print_error("[MEMORY] ERROR: SRAM malloced memory isnt right, resetting memory\n");
//Allocated length isnt long enough. Reset it to be memory safe
- if(sram[i].data != NULL)
- {
- if (sram[i].data >= ext_ram)
- extmem_free(sram[i].data);
- else
- free(sram[i].data);
- }
+ memory_dev_free(sram[i].data);
sram[i].data = NULL;
sram[i].len = 0;
}
@@ -74,16 +65,9 @@ uint8_t *memory_alloc_ram(const char *name, uint32_t alloc_len, uint32_t read_on
{
if (sram[i].len == 0)
{
- //Smaller blocks are RAM are mallocs internally for better performance. Teensy has a reasonable
- //amount of internal RAM :)
- (alloc_len <= internal_size || external_psram_size == 0) ? (sram[i].data = (uint8_t *)malloc(alloc_len)) :
- (sram[i].data = (uint8_t *)extmem_malloc(alloc_len));
-
- //If failed to malloc to internal RAM, try external RAM
- if (sram[i].data == NULL && alloc_len <= internal_size && external_psram_size > 0)
- sram[i].data = (uint8_t *)extmem_malloc(alloc_len);
+ sram[i].data = (uint8_t *)memory_dev_malloc(alloc_len);
- //If it still failed, no RAM left?
+ //If failed, no RAM left?
if (sram[i].data == NULL)
break;
@@ -97,7 +81,7 @@ uint8_t *memory_alloc_ram(const char *name, uint32_t alloc_len, uint32_t read_on
sram[i].read_only = read_only;
sram[i].dirty = 0;
- debug_print_memory("[MEMORY] Alloc'd %s, %u bytes at 0x%08x\n", sram[i].name, sram[i].len, sram[i].data);
+ debug_print_memory("[MEMORY] Alloc'd %s, %u bytes at 0x%x\n", sram[i].name, sram[i].len, (uintptr_t)sram[i].data);
return sram[i].data;
}
}
@@ -115,11 +99,8 @@ void memory_free_item(void *ptr)
{
if (sram[i].data == ptr)
{
- debug_print_memory("[MEMORY] Freeing %s at 0x%08x\n", sram[i].name, sram[i].data);
- if (sram[i].data >= ext_ram)
- extmem_free(sram[i].data);
- else
- free(sram[i].data);
+ debug_print_memory("[MEMORY] Freeing %s at 0x%llx\n", sram[i].name, (uintptr_t)sram[i].data);
+ memory_dev_free(sram[i].data);
sram[i].name[0] = '\0';
sram[i].data = NULL;
sram[i].len = 0;
@@ -127,13 +108,13 @@ void memory_free_item(void *ptr)
return;
}
}
- debug_print_memory("[MEMORY] WARNING: Did not free 0x%08x\n", ptr);
+ debug_print_memory("[MEMORY] WARNING: Did not free 0x%llx\n", (uintptr_t)ptr);
}
//Flush SRAM to flash memory if required
void memory_flush_all()
{
- noInterrupts();
+ n64hal_disable_interrupts();
for (unsigned int i = 0; i < sizeof(sram) / sizeof(sram[0]); i++)
{
if (sram[i].len == 0 || sram[i].data == NULL || sram[i].read_only != 0 || sram[i].dirty == 0)
@@ -143,7 +124,7 @@ void memory_flush_all()
fileio_write_to_file(sram[i].name, sram[i].data, sram[i].len);
sram[i].dirty = 0;
}
- interrupts();
+ n64hal_enable_interrupts();
}
void memory_mark_dirty(void *ptr)
@@ -160,10 +141,5 @@ void memory_mark_dirty(void *ptr)
return;
}
}
- debug_print_error("[MEMORY] ERROR: Could not find 0x%08x\n", ptr);
+ debug_print_error("[MEMORY] ERROR: Could not find 0x%llx\n", (uintptr_t)ptr);
}
-
-uint8_t memory_get_ext_ram_size()
-{
- return external_psram_size;
-}
\ No newline at end of file
diff --git a/src/memory.h b/src/memory.h
index 55efb9a5..7b658977 100644
--- a/src/memory.h
+++ b/src/memory.h
@@ -4,8 +4,7 @@
#ifndef _MEMORY_H
#define _MEMORY_H
-#include
-#include "usb64_conf.h"
+#include "common.h"
#define MEMORY_READ_WRITE 0
#define MEMORY_READ_ONLY 1
@@ -26,4 +25,8 @@ void memory_free_item(void *ptr);
void memory_mark_dirty(void *ptr);
uint8_t memory_get_ext_ram_size();
+bool memory_dev_init();
+void *memory_dev_malloc(uint32_t len);
+void memory_dev_free(void *add);
+
#endif
diff --git a/src/n64/n64_controller.c b/src/n64/n64_controller.c
index 7bf64c23..32a65626 100644
--- a/src/n64/n64_controller.c
+++ b/src/n64/n64_controller.c
@@ -1,24 +1,16 @@
// Copyright 2020, Ryan Wendland, usb64
// SPDX-License-Identifier: MIT
-#include
-#include "printf.h"
-#include "usb64_conf.h"
-#include "n64_mempak.h"
-#include "n64_virtualpak.h"
-#include "n64_rumblepak.h"
-#include "n64_settings.h"
-#include "n64_transferpak_gbcarts.h"
#include "n64_controller.h"
-#include "n64_wrapper.h"
+#include "n64_rom_database.h"
-//Uncomment to enable mempak READ address CRC checks.
+//Uncomment to enable controllerpak READ address CRC checks.
//May cause timing issues.
//Address CRC check for WRITES are hardcoded on already.
//#define USE_N64_ADDRESS_CRC
n64_rumblepak n64_rpak[MAX_CONTROLLERS];
-n64_mempack n64_mpack[MAX_CONTROLLERS];
+n64_controllerpak n64_cpak[MAX_CONTROLLERS];
n64_transferpak n64_tpak[MAX_CONTROLLERS];
gameboycart gb_cart[MAX_CONTROLLERS];
@@ -29,6 +21,49 @@ static uint8_t n64_cont_with_peri[] = {0x05, 0x00, 0x01};
static uint8_t n64_cont_no_peri[] = {0x05, 0x00, 0x02};
static uint8_t n64_cont_crc_error[] = {0x05, 0x00, 0x04};
+/* Currently only works with ED64 flashcarts with OS3.05 or (unofficial OS2.12.9.1) and above
+ Implementation is OSS and will hopefully be addopted by to other flashcarts! */
+static n64_rom_t current_rom = { .crc_hi = 0, .crc_low = 0, .media_format = 0, .country_code = 0 };
+static uint8_t _rom_info_changed = 0;
+
+uint8_t check_rom_info_changed()
+{
+ return _rom_info_changed;
+}
+
+void reset_rom_info_changed()
+{
+ _rom_info_changed = 0;
+}
+
+const char *n64_get_current_rom()
+{
+ if (current_rom.crc_hi == 67505422) // 0x04060d0e .. '4','6','D','E'
+ {
+ // TODO: Should now get CRC low etc. to work out OS and HW version?! Documentation required!
+ return "ED64 Flashcart Menu";
+ }
+ else if(current_rom.crc_hi != 0)
+ {
+ //Reverse the CRC for comparison
+ uint32_t __crc = (current_rom.crc_hi >> 24 & 0xFF) << 0 |
+ (current_rom.crc_hi >> 16 & 0xFF) << 8 |
+ (current_rom.crc_hi >> 8 & 0xFF) << 16 |
+ (current_rom.crc_hi >> 0 & 0xFF) << 24;
+
+ for (int i = 0; i < (sizeof(rom_crc_lookup) / sizeof(n64_rom_crc_lookup_t)); i++)
+ {
+ if (rom_crc_lookup[i].crc_hi == __crc)
+ {
+ current_rom.name = rom_crc_lookup[i].name;
+ return current_rom.name;
+ }
+ }
+ return "ROM CRC NOT FOUND"; //current_rom.crc_hi; //TODO: return the CRC_HI, for indication.
+ }
+ return "NO ROM INFORMATION"; // Generic message, shown if flashcart does not support joybus ROM ID!.
+}
+
void n64_subsystem_init(n64_input_dev_t *in_dev)
{
// INITIALISE THE N64 STRUCTS //
@@ -37,24 +72,30 @@ void n64_subsystem_init(n64_input_dev_t *in_dev)
in_dev[i].id = i;
in_dev[i].current_bit = 7;
in_dev[i].current_byte = 0;
- in_dev[i].current_peripheral = PERI_RUMBLE;
+ in_dev[i].current_peripheral = PERI_RPAK;
in_dev[i].next_peripheral = in_dev[i].current_peripheral;
in_dev[i].rpak = &n64_rpak[i];
- in_dev[i].mempack = &n64_mpack[i];
- in_dev[i].mempack->id = VIRTUAL_PAK;
- in_dev[i].mempack->data = NULL;
+ in_dev[i].cpak = &n64_cpak[i];
+ in_dev[i].cpak->id = VIRTUAL_PAK;
+ in_dev[i].cpak->data = NULL;
in_dev[i].tpak = &n64_tpak[i];
in_dev[i].tpak->gbcart = &gb_cart[i];
in_dev[i].interrupt_attached = false;
in_dev[i].peri_access = 0;
in_dev[i].type = N64_CONTROLLER;
+ in_dev[i].pin = (i == 0) ? N64_CONTROLLER_1_PIN :
+ (i == 1) ? N64_CONTROLLER_2_PIN :
+ (i == 2) ? N64_CONTROLLER_3_PIN :
+ (i == 3) ? N64_CONTROLLER_4_PIN : -1;
}
+ memset(¤t_rom, 0, sizeof(current_rom));
+
//Setup the Controller pin IO mapping and interrupts
n64hal_hs_tick_init();
}
-static uint8_t n64_get_crc(uint8_t *data)
+__attribute__((weak)) uint8_t n64_get_crc(uint8_t *data)
{
//Generated from http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
//N64 CRC poly was brute forced as x^7 + x^2 + x^0 (0x85), initial value = 0
@@ -120,10 +161,10 @@ static void n64_send_stream(uint8_t *txbuff, uint32_t len, n64_input_dev_t *c)
while (len > 0)
{
while ((n64hal_hs_tick_get() - cycle_start) < cycle_cnt);
- n64hal_input_swap(c, N64_OUTPUT); //OUTPUT_PP will pull low
+ n64hal_input_swap(c->pin, N64_OUTPUT); //OUTPUT_PP will pull low
(txbuff[current_byte] & 0x80) ? (cycle_cnt += 1 * U_SEC) : (cycle_cnt += 3 * U_SEC);
while ((n64hal_hs_tick_get() - cycle_start) < cycle_cnt);
- n64hal_input_swap(c, N64_INPUT);
+ n64hal_input_swap(c->pin, N64_INPUT);
(txbuff[current_byte] & 0x80) ? (cycle_cnt += 3 * U_SEC) : (cycle_cnt += 1 * U_SEC);
txbuff[current_byte] = txbuff[current_byte] << 1;
current_bit--;
@@ -139,10 +180,10 @@ static void n64_send_stream(uint8_t *txbuff, uint32_t len, n64_input_dev_t *c)
//Send stop bit. Pull low for 2us, then release.
while ((n64hal_hs_tick_get() - cycle_start) < cycle_cnt);
- n64hal_input_swap(c, N64_OUTPUT);
+ n64hal_input_swap(c->pin, N64_OUTPUT);
cycle_cnt += 2 * U_SEC;
while ((n64hal_hs_tick_get() - cycle_start) < cycle_cnt);
- n64hal_input_swap(c, N64_INPUT); //Release bus. We're done
+ n64hal_input_swap(c->pin, N64_INPUT); //Release bus. We're done
}
static void n64_reset_stream(n64_input_dev_t *cont)
@@ -163,7 +204,7 @@ void n64_controller_hande_new_edge(n64_input_dev_t *cont)
uint32_t start_clock = n64hal_hs_tick_get();
//If bus has been idle for 300us, start of a new stream.
- if ((n64hal_hs_tick_get() - cont->bus_idle_timer_clks) > (300 * n64hal_hs_tick_get_speed() / 1000000))
+ if ((n64hal_hs_tick_get() - cont->bus_idle_timer_clks) > (300 * (n64hal_hs_tick_get_speed() / 1000000)))
{
n64_reset_stream(cont);
cont->peri_access = 0;
@@ -183,7 +224,7 @@ void n64_controller_hande_new_edge(n64_input_dev_t *cont)
while (n64hal_hs_tick_get() < sample_clock);
//Read bit
- cont->data_buffer[cont->current_byte] |= n64hal_input_read(cont) << cont->current_bit;
+ cont->data_buffer[cont->current_byte] |= n64hal_input_read(cont->pin) << cont->current_bit;
cont->current_bit -= 1;
//Reset idle timer
@@ -220,20 +261,22 @@ void n64_controller_hande_new_edge(n64_input_dev_t *cont)
case N64_CONTROLLER_STATUS:
if (cont->type == N64_RANDNET) //Randnet does not response to this
break;
- n64hal_output_set(N64_FRAME, 1);
+ n64hal_output_set(N64_FRAME_PIN, 1);
n64_wait_micros(2);
n64_send_stream((uint8_t *)&cont->b_state, 4, cont);
n64_reset_stream(cont);
cont->b_state.dButtons = 0x0000;
- n64hal_output_set(N64_FRAME, 0);
+ n64hal_output_set(N64_FRAME_PIN, 0);
break;
case N64_RANDNET_REQ:
break;
case N64_PERI_READ:
case N64_PERI_WRITE:
+ case N64_N64DIGITAL_ROM_ID:
cont->peri_access = 1;
break;
default:
+ debug_print_n64("[N64] Unknown command %02x\n", cont->data_buffer[N64_COMMAND_POS]);
cont->peri_access = 0;
n64_reset_stream(cont);
break;
@@ -264,8 +307,27 @@ void n64_controller_hande_new_edge(n64_input_dev_t *cont)
n64_reset_stream(cont);
}
+ //Ref https://gitlab.com/pixelfx-public/n64-game-id
+ //Flashccart sends a 10 byte packet on game launch which contains the ROM CRC, ROM type and country code
+ if (cont->peri_access == 1 && (cont->data_buffer[N64_COMMAND_POS] == N64_N64DIGITAL_ROM_ID) && cont->current_byte == 1 /*Command byte*/ + 10)
+ {
+ n64_rom_t *_rom = (n64_rom_t *)&cont->data_buffer[1];
+ current_rom.crc_hi = _rom->crc_hi;
+ current_rom.crc_low = _rom->crc_low;
+ current_rom.media_format = _rom->media_format;
+ current_rom.country_code = _rom->country_code;
+ current_rom.name = NULL;
+ debug_print_n64("[N64] N64Digital JOYBUS Packet intercepted... Booting ROM ...\n");
+ debug_print_n64(" CRC High: %08x Low: %08x\n", current_rom.crc_hi, current_rom.crc_low);
+ debug_print_n64(" Media Format: %02x\n", current_rom.media_format);
+ debug_print_n64(" Country Code: %02x\n", current_rom.country_code);
+ cont->peri_access = 0;
+ n64_reset_stream(cont);
+ _rom_info_changed = 1;
+ }
+
//If we are accessing the peripheral bus, let's handle that
- if (cont->peri_access == 1)
+ else if (cont->peri_access == 1)
{
uint16_t peri_address = (cont->data_buffer[N64_ADDRESS_MSB_POS] << 8 |
cont->data_buffer[N64_ADDRESS_LSB_POS]);
@@ -295,7 +357,7 @@ void n64_controller_hande_new_edge(n64_input_dev_t *cont)
{
case 0x0:
//VIRTUAL MEMPAK NOTE TABLE HOOK
- if (cont->mempack->virtual_is_active && cont->current_peripheral == PERI_MEMPAK &&
+ if (cont->cpak->virtual_is_active && cont->current_peripheral == PERI_CPAK &&
peri_address >= 0x300 && peri_address < 0x500)
{
/*
@@ -306,8 +368,8 @@ void n64_controller_hande_new_edge(n64_input_dev_t *cont)
* I use this as a hacky menu for the N64
*/
uint32_t row = (peri_address - 0x300) / 0x20; //What row you have 'selected' 0-15
- cont->mempack->virtual_update_req = 1;
- cont->mempack->virtual_selected_row = row;
+ cont->cpak->virtual_update_req = 1;
+ cont->cpak->virtual_selected_row = row;
debug_print_n64("[N64] Virtualpak write at row %u\n", row);
break;
}
@@ -319,8 +381,8 @@ void n64_controller_hande_new_edge(n64_input_dev_t *cont)
case 0x5:
case 0x6:
case 0x7:
- if (cont->current_peripheral == PERI_MEMPAK && !cont->crc_error)
- n64_mempack_write32(cont->mempack, peri_address, &cont->data_buffer[N64_DATA_POS]);
+ if (cont->current_peripheral == PERI_CPAK && !cont->crc_error)
+ n64_cpak_write32(cont->cpak, peri_address, &cont->data_buffer[N64_DATA_POS]);
break;
case 0x8:
if (cont->current_peripheral == PERI_TPAK)
@@ -330,7 +392,7 @@ void n64_controller_hande_new_edge(n64_input_dev_t *cont)
(cont->data_buffer[N64_DATA_POS] == 0xFE) ? tpak_reset(cont->tpak) : (0);
debug_print_tpak("[TPAK] Powerstate set to %u\n", cont->tpak->power_state);
}
- else if (cont->current_peripheral == PERI_RUMBLE)
+ else if (cont->current_peripheral == PERI_RPAK)
{
//N64 writes 32 bytes of 0x80 to initialise the rumblepak, 0xFE to reset it
(cont->data_buffer[N64_DATA_POS] == 0x80) ? cont->rpak->initialised = 1 : (0);
@@ -355,7 +417,7 @@ void n64_controller_hande_new_edge(n64_input_dev_t *cont)
}
break;
case 0xC:
- if (cont->current_peripheral == PERI_RUMBLE)
+ if (cont->current_peripheral == PERI_RPAK)
{
(cont->data_buffer[N64_DATA_POS] == 0x01) ? (cont->rpak->state = RUMBLE_START) :
(cont->rpak->state = RUMBLE_STOP);
@@ -437,15 +499,15 @@ void n64_controller_hande_new_edge(n64_input_dev_t *cont)
case 0x5:
case 0x6:
case 0x7:
- if (cont->current_peripheral == PERI_MEMPAK)
+ if (cont->current_peripheral == PERI_CPAK)
{
- n64_mempack_read32(cont->mempack, peri_address, &cont->data_buffer[N64_DATA_POS]);
+ n64_cpak_read32(cont->cpak, peri_address, &cont->data_buffer[N64_DATA_POS]);
}
break;
case 0x8:
case 0x9:
//If rumblepak is initialised, respond with 32bytes of 0x80.
- if (cont->current_peripheral == PERI_RUMBLE && cont->rpak->initialised == 1)
+ if (cont->current_peripheral == PERI_RPAK && cont->rpak->initialised == 1)
{
memset(&cont->data_buffer[N64_DATA_POS], 0x80, 32);
debug_print_n64("[N64] Request rumblepak state. Sending 0x80s (its initialised)\n");
diff --git a/src/n64/n64_controller.h b/src/n64/n64_controller.h
index 00e0c68c..dc0bb23b 100644
--- a/src/n64/n64_controller.h
+++ b/src/n64/n64_controller.h
@@ -8,9 +8,13 @@
extern "C" {
#endif
+#include
#include "n64_mempak.h"
#include "n64_rumblepak.h"
+#include "n64_settings.h"
+#include "n64_virtualpak.h"
#include "n64_transferpak_gbcarts.h"
+#include "n64_rom_database.h"
typedef struct __attribute__((packed))
{
@@ -36,8 +40,8 @@ typedef enum
typedef enum
{
PERI_NONE,
- PERI_RUMBLE,
- PERI_MEMPAK,
+ PERI_RPAK,
+ PERI_CPAK,
PERI_TPAK
} n64_peri_type;
@@ -52,17 +56,26 @@ typedef struct
n64_input_type type; //Store the type of input device. Controller, Mouse. Randnet etc.
n64_buttonmap b_state; //N64 controller button and analog stick map
n64_randnet_kb kb_state; //Randnet keyboard object
- n64_peri_type current_peripheral; //Peripheral flag, PERI_NONE, PERI_RUMBLE, PERI_MEMPAK, PERI_TPAK
+ n64_peri_type current_peripheral; //Peripheral flag, PERI_NONE, PERI_RPAK, PERI_CPAK, PERI_TPAK
n64_peri_type next_peripheral; //What Peripheral to change to next after timer
n64_transferpak *tpak; //Pointer to installed transferpak
n64_rumblepak *rpak; //Pointer to installed rumblepak
- n64_mempack *mempack; //Pointer to installed mempack
+ n64_controllerpak *cpak; //Pointer to installed controllerpak
//
uint32_t interrupt_attached; //Flag is set when this controller is connected to an ext int.
uint32_t bus_idle_timer_clks; //Timer counter for bus idle timing
- uint32_t gpio_pin; //What pin is this controller connected to
+ usb64_pin_t pin; //What pin is this controller connected to
} n64_input_dev_t;
+typedef struct
+{
+ uint32_t crc_hi;
+ uint32_t crc_low;
+ uint8_t media_format;
+ uint8_t country_code;
+ const char *name;
+} n64_rom_t;
+
//N64 JOYBUS
#define N64_IDENTIFY 0x00
#define N64_CONTROLLER_STATUS 0x01
@@ -70,6 +83,7 @@ typedef struct
#define N64_PERI_WRITE 0x03
#define N64_CONTROLLER_RESET 0xFF
#define N64_RANDNET_REQ 0x13
+#define N64_N64DIGITAL_ROM_ID 0x1D
#define N64_COMMAND_POS 0
#define N64_ADDRESS_MSB_POS 1
#define N64_ADDRESS_LSB_POS 2
@@ -106,13 +120,21 @@ typedef struct
#define RANDNET_FLAG_EXCESS_BUTTONS (1 << 4)
//Mempak
-#define MEMPAK_SIZE 32768
-#define MAX_MEMPAKS MAX_CONTROLLERS
-#define VIRTUAL_PAK MAX_MEMPAKS
+#define CPAK_SIZE 32768
+#define MAX_CPAKS MAX_CONTROLLERS
+#define VIRTUAL_PAK MAX_CPAKS
void n64_subsystem_init(n64_input_dev_t *in_dev);
void n64_controller_hande_new_edge(n64_input_dev_t *cont);
+/* Currently only works with ED64 flashcarts with OS3.05 or (unofficial OS2.12.9.1) and above
+ Implementation is OSS and will hopefully be added to others! */
+const char *n64_get_current_rom();
+uint8_t check_rom_info_changed();
+void reset_rom_info_changed();
+
+
+
#ifdef __cplusplus
}
#endif
diff --git a/src/n64/n64_mempak.c b/src/n64/n64_mempak.c
index 7f9fcd56..43ced3fe 100644
--- a/src/n64/n64_mempak.c
+++ b/src/n64/n64_mempak.c
@@ -1,34 +1,28 @@
// Copyright 2020, Ryan Wendland, usb64
// SPDX-License-Identifier: MIT
-#include
-#include "n64_mempak.h"
-#include "n64_virtualpak.h"
-#include "n64_settings.h"
-#include "n64_transferpak_gbcarts.h"
#include "n64_controller.h"
-#include "n64_wrapper.h"
-void n64_mempack_read32(n64_mempack *mempack, uint16_t address, uint8_t *rx_buff)
+void n64_cpak_read32(n64_controllerpak *cpak, uint16_t address, uint8_t *rx_buff)
{
- if (mempack->virtual_is_active)
+ if (cpak->virtual_is_active)
{
n64_virtualpak_read32(address, rx_buff);
}
else
{
- n64hal_read_extram(rx_buff, mempack->data, address, 32);
+ n64hal_read_extram(rx_buff, cpak->data, address, 32);
}
}
-void n64_mempack_write32(n64_mempack *mempack, uint16_t address, uint8_t *tx_buff)
+void n64_cpak_write32(n64_controllerpak *cpak, uint16_t address, uint8_t *tx_buff)
{
- if (mempack->virtual_is_active)
+ if (cpak->virtual_is_active)
{
n64_virtualpak_write32(address, tx_buff);
}
else
{
- n64hal_write_extram(tx_buff, mempack->data, address, 32);
+ n64hal_write_extram(tx_buff, cpak->data, address, 32);
}
}
diff --git a/src/n64/n64_mempak.h b/src/n64/n64_mempak.h
index 82188069..ffc5f83d 100644
--- a/src/n64/n64_mempak.h
+++ b/src/n64/n64_mempak.h
@@ -8,7 +8,7 @@
extern "C" {
#endif
-#define MEMPAK_SIZE 32768
+#define CPAK_SIZE 32768
typedef struct
{
@@ -18,10 +18,10 @@ typedef struct
uint32_t virtual_is_active;
uint32_t virtual_update_req;
uint32_t virtual_selected_row;
-} n64_mempack;
+} n64_controllerpak;
-void n64_mempack_read32(n64_mempack *mempack, uint16_t address, uint8_t *rx_buff);
-void n64_mempack_write32(n64_mempack *mempack, uint16_t address, uint8_t *tx_buff);
+void n64_cpak_read32(n64_controllerpak *cpak, uint16_t address, uint8_t *rx_buff);
+void n64_cpak_write32(n64_controllerpak *cpak, uint16_t address, uint8_t *tx_buff);
#ifdef __cplusplus
}
diff --git a/src/n64/n64_rom_database.h b/src/n64/n64_rom_database.h
new file mode 100644
index 00000000..8d62dff7
--- /dev/null
+++ b/src/n64/n64_rom_database.h
@@ -0,0 +1,1811 @@
+// Copyright 2020, Ryan Wendland, usb64
+// SPDX-License-Identifier: MIT
+
+#ifndef _N64_ROM_DATABASE_h
+#define _N64_ROM_DATABASE_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// This is a prototype database for N64 ROMs.
+// TODO: Possibily needs option for user expansion or remote update (without firmware change).
+// e.g. should retrive from sqlite DB on SDCARD.
+typedef struct
+{
+ uint32_t crc_hi;
+ uint32_t crc_low;
+ const char *name;
+} n64_rom_crc_lookup_t;
+
+static const FLASHMEM n64_rom_crc_lookup_t rom_crc_lookup[] = {
+{0x3B941695, 0xF90A5EEB,
+"007 - The World is Not Enough (E) (M3)"},
+{0x033F4C13, 0x319EE7A7,
+"007 - The World is Not Enough (U)"},
+{0x58FD3F25, 0xD92EAA8D,
+"1080 Snowboarding (E) [!]"},
+{0x1FBAF161, 0x2C1C54F1,
+"1080 Snowboarding (JU) [!]"},
+{0xABA51D09, 0xC668BAD9,
+"40 Winks (E) (M3) (Beta)"},
+{0xB98BA456, 0x5B2B76AF,
+"64 de Hakken!! Tamagotchi Minna de Tamagotchi World (J)"},
+{0x9C961069, 0xF5EA488D,
+"64 Oozumou (J)"},
+{0x85C18B16, 0xDF9622AF,
+"64 Oozumou 2 (J)"},
+{0x7A6081FC, 0xFF8F7A78,
+"64 Trump Collection - Alice no Wakuwaku Trump World (J) [!]"},
+{0x8F12C096, 0x45DC17E1,
+"A Bug's Life (E) [!]"},
+{0x2B38AEC0, 0x6350B810,
+"A Bug's Life (F) [!]"},
+{0xDFF227D9, 0x0D4D8169,
+"A Bug's Life (G) [!]"},
+{0xF63B89CE, 0x4582D57D,
+"A Bug's Life (I)"},
+{0x82DC04FD, 0xCF2D82F4,
+"A Bug's Life (U) [!]"},
+{0x62F6BE95, 0xF102D6D6,
+"Aerofighter's Assault (E) [!]"},
+{0x1B598BF1, 0xECA29B45,
+"Aerofighter's Assault (U) [!]"},
+{0xD83045C8, 0xF29D3A36,
+"AeroGauge (E) [!]"},
+{0xB00903C9, 0x3916C146,
+"AeroGauge - Kiosk (J) (V1.0)"},
+{0x80F41131, 0x384645F6,
+"AeroGauge (J) (V1.1) [!]"},
+{0xAEBE463E, 0xCC71464B,
+"AeroGauge (U) [!]"},
+{0x8CC182A6, 0xC2D0CAB0,
+"AI Shogi 3 (J) [!]"},
+{0x2DC4FFCC, 0xC8FF5A21,
+"Aidyn Chronicles - The First Mage (E) [!]"},
+{0xE6A95A4F, 0xBAD2EA23,
+"Aidyn Chronicles - The First Mage (U) [!] (V1.0)"},
+{0x112051D2, 0x68BEF8AC,
+"Aidyn Chronicles - The First Mage (U) [!] (V1.1)"},
+{0x27C425D0, 0x8C2D99C1,
+"Airboarder 64 (E) [!]"},
+{0x6C45B60C, 0xDCE50E30,
+"Airboarder 64 (J) [!]"},
+{0xB6951A94, 0x63C849AF,
+"Akumajou Dracula Mokushiroku - Real Action Adventure (J) [!]"},
+{0xA5533106, 0xB9F25E5B,
+"Akumajou Dracula Mokushiroku Gaiden-Legend of Cornell (J) [!]"},
+{0xDFD784AD, 0xAE426603,
+"All Star Tennis '99 (E) [!]"},
+{0xE185E291, 0x4E50766D,
+"All Star Tennis '99 (U) [!]"},
+{0x67D20729, 0xF696774C,
+"All Star! Dairantou Smash Brothers (J) [!]"},
+{0xA19F8089, 0x77884B51,
+"All-Star Baseball 2000 (E) [!]"},
+{0x5E547A4D, 0x90E60795,
+"All-Star Baseball 2000 (U) [!]"},
+{0x5446C6EF, 0xE18E47BB,
+"All-Star Baseball 2001 (U) [!]"},
+{0xD9EDD54D, 0x6BB8E274,
+"All-Star Baseball 99 (E) [!]"},
+{0xC43E23A7, 0x40B1681A,
+"All-Star Baseball 99 (U) [!]"},
+{0x3CC77150, 0x21CDB987,
+"Armorines - Project S.W.A.R.M. (E) [!]"},
+{0xC0F6DB17, 0x80E0D532,
+"Armorines - Project S.W.A.R.M. (G) [!]"},
+{0x1FB5D932, 0x3BA9481B,
+"Armorines - Project S.W.A.R.M. (U) [!]"},
+{0x4C52BBB2, 0xCEAB0F6B,
+"Army Men - Air Combat (U) [!]"},
+{0xB210DF19, 0x98B58D1A,
+"Army Men - Sarge's Heroes (E) [!]"},
+{0x862C0657, 0x8DFD896D,
+"Army Men - Sarge's Heroes (U) [!]"},
+{0xB20F73B6, 0x2975FC34,
+"Army Men - Sarge's Heroes 2 (U) [!]"},
+{0xD1F7D8AB, 0x293B0446,
+"Asteroids Hyper 64 (U) [!]"},
+{0xFC7797BF, 0x4A95E83C,
+"Automobili Lamborghini (E) [!]"},
+{0x41B25DC4, 0x1B726786,
+"Automobili Lamborghini (U) [!]"},
+{0xE340A49C, 0x74318D41,
+"Baku Bomberman (J) [!]"},
+{0xE73C7C4F, 0xAF93B838,
+"Baku Bomberman 2 (J) [!]"},
+{0xDF98B95D, 0x58840978,
+"Bakuretsu Muteki Bangaioh (J) [!]"},
+{0x88CF980A, 0x8ED52EB5,
+"Bakushou Jinsei 64 - Mezase! Resort Ou (J) [!]"},
+{0x5168D520, 0xCA5FCD0D,
+"Banjo to Kazooie no Dai Bouken (J) [!]"},
+{0x514B6900, 0xB4B19881,
+"Banjo to Kazooie no Dai Bouken 2 (J) [!]"},
+{0x733FCCB1, 0x444892F9,
+"Banjo-Kazooie (E) [!]"},
+{0xA4BF9306, 0xBF0CDFD1,
+"Banjo-Kazooie (U) [!]"},
+{0x155B7CDF, 0xF0DA7325,
+"Banjo-Tooie (A) [!]"},
+{0xC9176D39, 0xEA4779D1,
+"Banjo-Tooie (E) [!]"},
+{0xC2E9AA9A, 0x475D70AA,
+"Banjo-Tooie (U) [!]"},
+{0xB088FBB4, 0x441E4B1D,
+"Bass Hunter 64 (E) [!]"},
+{0xD76333AC, 0x0CB6219D,
+"Bass Rush - Ecogear Powerworm Championship (J)"},
+{0xD137A2CA, 0x62B65053,
+"Bass Tsuri No. 1 - Shigesato Itoi's Bass Fishing (J) [!]"},
+{0xBCFACCAA, 0xB814D8EF,
+"Bassmasters 2000 (U) [!]"},
+{0x259F7F84, 0x7C9EED26,
+"Batman of the Future - Return of the Joker (E) [!]"},
+{0x204489C1, 0x1286CF2B,
+"Batman Beyond - Return of the Joker (U) [!]"},
+{0x0CAD17E6, 0x71A5B797,
+"BattleTanx - Global Assault (E) [!]"},
+{0x75A4E247, 0x6008963D,
+"BattleTanx - Global Assault (U) [!]"},
+{0x6AA4DDE7, 0xE3E2F4E7,
+"BattleTanx (U) [!]"},
+{0x55D4C4CE, 0x7753C78A,
+"Battlezone - Rise of the Black Dogs (U) [!]"},
+{0x91691C3D, 0xF4AC5B4D,
+"Beast Wars Metals (J) [!]"},
+{0x4D79D316, 0xE8501B33,
+"Beast Wars Transmetal (U) [!]"},
+{0xA1B64A61, 0xD014940B,
+"Beetle Adventure Racing! (E) [!]"},
+{0x9C7318D2, 0x24AE0DC1,
+"Beetle Adventure Racing! (J) [!]"},
+{0xEDF419A8, 0xBF1904CC,
+"Beetle Adventure Racing! (U) [!]"},
+{0x08FFA4B7, 0x01F453B6,
+"Big Mountain 2000 (U) [!]"},
+{0xAB7C101D, 0xEC58C8B0,
+"Bio F.R.E.A.K.S. (E) [!]"},
+{0x08123595, 0x0510F1DE,
+"Bio F.R.E.A.K.S. (U) [!]"},
+{0x7EAE2488, 0x9D40A35A,
+"Bio Hazard 2 (J) [!]"},
+{0x7C64E6DB, 0x55B924DB,
+"Blast Corps (E) [!]"},
+{0x7C647C25, 0xD9D901E6,
+"Blast Corps (U) (V1.0) [!]"},
+{0x7C647E65, 0x1948D305,
+"Blast Corps (U) (V1.1) [!]"},
+{0x65234451, 0xEBD3346F,
+"Blast Dozer (J) [!]"},
+{0xD571C883, 0x822D3FCF,
+"Blues Brothers 2000 (E) [!]"},
+{0x7CD08B12, 0x1153FF89,
+"Blues Brothers 2000 (U) [!]"},
+{0x0B58B8CD, 0xB7B291D2,
+"Body Harvest (E) [!]"},
+{0x5326696F, 0xFE9A99C3,
+"Body Harvest (U) [!]"},
+{0xB3D451C6, 0xE1CB58E2,
+"Bokujo Monogatari 2 (J) (V1.0) [!]"},
+{0x736657F6, 0x3C88A702,
+"Bokujo Monogatari 2 (J) (V1.1)"},
+{0x7365D8F8, 0x9ED9326F,
+"Bokujo Monogatari 2 (J) (V1.2)"},
+{0xDF6FF0F4, 0x29D14238,
+"Bomberman 64 - Arcade Edition (J) [!]"},
+{0x237E73B4, 0xD63B6B37,
+"Bomberman 64 - The Second Attack! (U) [!]"},
+{0x5A160336, 0xBC7B37B0,
+"Bomberman 64 (E) [!]"},
+{0xF568D51E, 0x7E49BA1E,
+"Bomberman 64 (U) [!]"},
+{0xD85C4E29, 0x88E276AF,
+"Bomberman Hero (E) [!]"},
+{0x67FF12CC, 0x76BF0212,
+"Bomberman Hero (J) [!]"},
+{0x4446FDD6, 0xE3788208,
+"Bomberman Hero (U) [!]"},
+{0xD72FD14D, 0x1FED32C4,
+"Bottom of the 9th (U) [!]"},
+{0x1E22CF2E, 0x42AAC813,
+"Brunswick Circuit Pro Bowling (U) [!]"},
+{0xD5B2339C, 0xCABCCAED,
+"Buck Bumble (E) [!]"},
+{0xD7C762B6, 0xF83D9642,
+"Buck Bumble (J) [!]"},
+{0x85AE781A, 0xC756F05D,
+"Buck Bumble (U) [!]"},
+{0xCEDCDE1E, 0x513A0502,
+"Bust-A-Move 2 - Arcade Edition (E) [!]"},
+{0x8A86F073, 0xCD45E54B,
+"Bust-A-Move 2 - Arcade Edition (U) [!]"},
+{0xE328B4FA, 0x004A28E1,
+"Bust-A-Move 3 DX (E) [!]"},
+{0x4222D89F, 0xAFE0B637,
+"Bust-A-Move '99 (U) [!]"},
+{0xAC16400E, 0xCF5D071A,
+"California Speed (U) [!]"},
+{0x580162EC, 0xE3108BF1,
+"Carmageddon 64 (G) [!]"},
+{0xE48E01F5, 0xE6E51F9B,
+"Carmageddon 64 (E) [!]"},
+{0xF00F2D4E, 0x340FAAF4,
+"Carmageddon 64 (U) [!]"},
+{0xA2C54BE7, 0x6719CBB2,
+"Castlevania - Legacy of Darkness (E) [!]"},
+{0x1CC06338, 0x87388926,
+"Castlevania - Legacy of Darkness (U) [!]"},
+{0x64F1B7CA, 0x71A23755,
+"Castlevania (E) [!]"},
+{0xF35D5F95, 0x8AFE3D69,
+"Castlevania (U) (V1.0) [!]"},
+{0x4BCDFF47, 0xAAA3AF8F,
+"Castlevania (U) (V1.2) [!]"},
+{0xDCCF2134, 0x9DD63578,
+"Centre Court Tennis (E) [!]"},
+{0xB9AF8CC6, 0xDEC9F19F,
+"Chameleon Twist (E) [!]"},
+{0xA4F2F521, 0xF0EB168E,
+"Chameleon Twist (J) [!]"},
+{0x6420535A, 0x50028062,
+"Chameleon Twist (U) [!]"},
+{0x07A69D01, 0x9A7D41A1,
+"Chameleon Twist 2 (E) [!]"},
+{0x0549765A, 0x93B9D042,
+"Chameleon Twist 2 (J) [!]"},
+{0xCD538CE4, 0x618AFCF9,
+"Chameleon Twist 2 (U) [!]"},
+{0xFB3C48D0, 0x8D28F69F,
+"Charlie Blast's Territory (E) [!]"},
+{0x1E0E96E8, 0x4E28826B,
+"Charlie Blast's Territory (U) [!]"},
+{0x2E359339, 0x3FA5EDA6,
+"Chopper Attack (E) [!]"},
+{0x214CAD94, 0xBE1A3B24,
+"Chopper Attack (U) [!]"},
+{0x2BCCF9C4, 0x403D9F6F,
+"Choro Q 64 (J) [!]"},
+{0x26CD0F54, 0x53EBEFE0,
+"Choro Q 64 II (J) [!]"},
+{0x8ACE6683, 0x3FBA426E,
+"Chou Kuukan Night Pro Yakyuu King (J)"},
+{0x3A180FF4, 0x5C8E8AF7,
+"Chou-Kuukan Night Pro Yakyuu King 2 (J)"},
+{0xA7941528, 0x61F1199D,
+"Chou Snowbow Kids (J) [!]"},
+{0xF8009DB0, 0x6B291823,
+"City-Tour GP-All Japan Grand Touring Car Championship (J) [!]"},
+{0xFA5A3DFF, 0xB4C9CDB9,
+"Clay Fighter - Sculptor's Cut (U) [!]"},
+{0x2B6FA7C0, 0x09A71225,
+"Clay Fighter 63 1-3 (U) (beta)"},
+{0x8E9692B3, 0x4264BB2A,
+"Clay Fighter 63 1-3 (E) [!]"},
+{0xF03C24CA, 0xC5237BCC,
+"Clay Fighter 63 1-3 (U) [!]"},
+{0xAE5B9465, 0xC54D6576,
+"Command & Conquer (E) [!]"},
+{0xB5025BAD, 0xD32675FD,
+"Command & Conquer (G) [!]"},
+{0x95286EB4, 0xB76AD58F,
+"Command & Conquer (U) [!]"},
+{0x373F5889, 0x9A6CA80A,
+"Conker's Bad Fur Day (E) [!]"},
+{0x30C7AC50, 0x7704072D,
+"Conker's Bad Fur Day (U) [!]"},
+{0x46A3F7AF, 0x0F7591D0,
+"Cruis'n Exotica (U) [!]"},
+{0x503EA760, 0xE1300E96,
+"Cruis'n USA (E) [!]"},
+{0xFF2F2FB4, 0xD161149A,
+"Cruis'n USA (U) (V1.0) [!]"},
+{0x5306CF45, 0xCBC49250,
+"Cruis'n USA (U) (V1.1) [!]"},
+{0xB3402554, 0x7340C004,
+"Cruis'n USA (U) (V1.2) [!]"},
+{0x83F3931E, 0xCB72223D,
+"Cruis'n World (E) [!]"},
+{0xDFE61153, 0xD76118E6,
+"Cruis'n World (U) [!]"},
+{0x83CB0B87, 0x7E325457,
+"Custom Robo (J) [!]"},
+{0x079501B9, 0xAB0232AB,
+"Custom Robo V2 (J) [!]"},
+{0xD1A78A07, 0x52A3DD3E,
+"CyberTiger (E) [!]"},
+{0xE8FC8EA1, 0x9F738391,
+"CyberTiger (U) [!]"},
+{0x7188F445, 0x84410A68,
+"Dance Dance Revolution - Disney Dancing Museum (J) [!]"},
+{0x7ED67CD4, 0xB4415E6D,
+"Dark Rift (E) [!]"},
+{0xA4A52B58, 0x23759841,
+"Dark Rift (U) [!]"},
+{0xF5363349, 0xDBF9D21B,
+"Deadly Arts (U) [!]"},
+{0x3F66A9D9, 0x9BCB5B00,
+"Defi au Tetris Magique (Magical Tetris Challenge) (F) [!]"},
+{0x17C54A61, 0x4A83F2E7,
+"Densha de GO! 64 (J) [!]"},
+{0xA5F667E1, 0xDA1FBD1F,
+"Derby Stallion (J) [!]"},
+{0x630AA37D, 0x896BD7DB,
+"Destruction Derby 64 (E) [!]"},
+{0xDEE584A2, 0x0F161187,
+"Destruction Derby 64 (U) [!]"},
+{0x76712159, 0x35666812,
+"Dexanoid R1 by Protest Design (PD) [!]"},
+{0x8979169C, 0xF189F6A0,
+"Dezaemon 3D (J) [!]"},
+{0xFD73F775, 0x9724755A,
+"Diddy Kong Racing (E) (V1.0) [!]"},
+{0x596E145B, 0xF7D9879F,
+"Diddy Kong Racing (E) (V1.1) [!]"},
+{0xF389A35A, 0x17785562,
+"Diddy Kong Racing (J) [!]"},
+{0x53D440E7, 0x7519B011,
+"Diddy Kong Racing (U) (V1.0) [!]"},
+{0xE402430D, 0xD2FCFC9D,
+"Diddy Kong Racing (U) (V1.1) [!]"},
+{0x906C3F77, 0xCE495EA1,
+"Dinosaur Planet (U) (Beta) (Unreleased)"},
+{0xC16C421B, 0xA21580F7,
+"Disney's Donald Duck - Goin' Quackers (U) [!]"},
+{0xD614E5BF, 0xA76DBCC1,
+"Disney's Tarzan (E) [!]"},
+{0x001A3BD0, 0xAFB3DE1A,
+"Disney's Tarzan (F) [!]"},
+{0x4C261323, 0x4F295E1A,
+"Disney's Tarzan (G) [!]"},
+{0xCBFE69C7, 0xF2C0AB2A,
+"Disney's Tarzan (U) [!]"},
+{0xBD8E206D, 0x98C35E1C,
+"Dobutsu no Mori (J) [!]"},
+{0x3DF17480, 0x193DED5A,
+"Donald Duck - Quack Attack (E) [!]"},
+{0x0DD4ABAB, 0xB5A2A91E,
+"Donkey Kong 64 - Kiosk (U) [!]"},
+{0x11936D8C, 0x6F2C4B43,
+"Donkey Kong 64 (E) [!]"},
+{0x053C89A7, 0xA5064302,
+"Donkey Kong 64 (J) [!]"},
+{0xEC58EABF, 0xAD7C7169,
+"Donkey Kong 64 (U) [!]"},
+{0x2C739EAC, 0x9EF77726,
+"Doom 64 (E) [!]"},
+{0x7AA65B36, 0xFDCEE5AD,
+"Doom 64 (J) [!]"},
+{0xA83E101A, 0xE937B69D,
+"Doom 64 (U) (V1.0) [!]"},
+{0x423E96F4, 0xCE88F05B,
+"Doom 64 (U) (v1.1)"},
+{0xBFF7B1C2, 0xAEBF148E,
+"Doraemon - Mittsu no Seireiseki (J) [!]"},
+{0xB6306E99, 0xB63ED2B2,
+"Doraemon 2 - Hikari no Shinden (J) [!]"},
+{0xA8275140, 0xB9B056E8,
+"Doraemon 3 - Nobi Dai no Machi SOS! (J) [!]"},
+{0x769D4D13, 0xDA233FFE,
+"Dr. Mario 64 (U) [!]"},
+{0xB6524461, 0xED6D04B1,
+"Dual Heroes (E) [!]"},
+{0x056EAB63, 0xC215FCD5,
+"Dual Heroes (J) [!]"},
+{0xA62230C3, 0xF0834488,
+"Dual Heroes (U) [!]"},
+{0xFBB9F1FA, 0x6BF88689,
+"Duck Dodgers Starring Daffy Duck (U) [!]"},
+{0xDC36626A, 0x3F3770CB,
+"Duke Nukem - ZER0 H0UR (E) [!]"},
+{0x32CA974B, 0xB2C29C50,
+"Duke Nukem - ZER0 H0UR (F) [!]"},
+{0x04DAF07F, 0x0D18E688,
+"Duke Nukem - ZER0 H0UR (U) [!]"},
+{0x57BFF74D, 0xDE747743,
+"Duke Nukem 64 (E) [!]"},
+{0x1E12883D, 0xD3B92718,
+"Duke Nukem 64 (F)"},
+{0xA273AB56, 0xDA33DB9A,
+"Duke Nukem 64 (U) [!]"},
+{0x492B9DE8, 0xC6CCC81C,
+"Earthworm Jim 3D (E) [!]"},
+{0xDF574191, 0x9EB5123D,
+"Earthworm Jim 3D (U) [!]"},
+{0x8C38E5DB, 0xB37C27D7,
+"ECW Hardcore Revolution (E) [!]"},
+{0xBDF9766D, 0xBD068D70,
+"ECW Hardcore Revolution (U) [!]"},
+{0xF2A653CB, 0x60633B3B,
+"Elmo's Letter Adventure (U) [!]"},
+{0x02B1538F, 0xC94B88D0,
+"Elmo's Number Journey (U) [!]"},
+{0xE13AE2DC, 0x4FB65CE8,
+"Eltale Monsters (J) [!]"},
+{0xAF754F7B, 0x1DD17381,
+"Excitebike 64 - Kiosk (U) [!]"},
+{0x202A8EE4, 0x83F88B89,
+"Excitebike 64 (E) [!]"},
+{0x861C3519, 0xF6091CE5,
+"Excitebike 64 (J) [!]"},
+{0x07861842, 0xA12EBC9F,
+"Excitebike 64 (U) [!]"},
+{0x8E9D834E, 0x1E8B29A9,
+"Extreme-G (E) [!]"},
+{0xEE802DC4, 0x690BD57D,
+"Extreme-G (J) [!]"},
+{0xFDA245D2, 0xA74A3D47,
+"Extreme-G (U) [!]"},
+{0x1185EC85, 0x4B5A7731,
+"Extreme-G XG2 (E) [!]"},
+{0x399B9B81, 0xD533AD11,
+"Extreme-G XG2 (J) [!]"},
+{0x5CD4150B, 0x470CC2F1,
+"Extreme-G XG2 (U) [!]"},
+{0xFDD248B2, 0x569A020E,
+"F-1 Pole Position 64 (E) [!]"},
+{0xAE82687A, 0x9A3F388D,
+"F-1 Pole Position 64 (U) [!]"},
+{0xCC3CC8B3, 0x0EC405A4,
+"F-1 World Grand Prix (E) [!]"},
+{0xB70BAEE5, 0x3A5005A8,
+"F-1 World Grand Prix (F) [!]"},
+{0x38442634, 0x66B3F060,
+"F-1 World Grand Prix (G)"},
+{0x64BF47C4, 0xF4BD22BA,
+"F-1 World Grand Prix (J) [!]"},
+{0xCC3CC8B3, 0x0EC405A4,
+"F-1 World Grand Prix (U) [!]"},
+{0x07C1866E, 0x5775CCDE,
+"F-1 World Grand Prix II (E) [!]"},
+{0x6DFF4C37, 0xB1B763FD,
+"Famista 64 (J) [!]"},
+{0x3CECBCB8, 0x6126BF07,
+"F1 Racing Championship (E) [!]"},
+{0x0E31EDF0, 0xC37249D5,
+"FIFA - Road to World Cup 98 (E) [!]"},
+{0xF5733C67, 0x17A3973A,
+"FIFA - Road to World Cup 98 (J) [!]"},
+{0xCB1ACDDE, 0xCF291DF2,
+"FIFA - Road to World Cup 98 (U) [!]"},
+{0x0198A651, 0xFC219D84,
+"FIFA 99 (E) [!]"},
+{0x7613A630, 0x3ED696F3,
+"FIFA 99 (U) [!]"},
+{0xC3F19159, 0x65D2BC5A,
+"FIFA Soccer 64 (E) [!]"},
+{0xC3F19159, 0x65D2BC5A,
+"FIFA Soccer 64 (U) [!]"},
+{0x36F1C74B, 0xF2029939,
+"Fighter's Destiny (E) [!]"},
+{0x0C41F9C2, 0x01717A0D,
+"Fighter's Destiny (F) [!]"},
+{0xFE94E570, 0xE4873A9C,
+"Fighter's Destiny (G) [!]"},
+{0x52F78805, 0x8B8FCAB7,
+"Fighter's Destiny (U) [!]"},
+{0xAEEF2F45, 0xF97E30F1,
+"Fighter's Destiny 2 (U) [!]"},
+{0x49E46C2D, 0x7B1A110C,
+"Fighting Cup (J) [!]"},
+{0x66CF0FFE, 0xAD697F9C,
+"Fighting Force 64 (E) [!]"},
+{0x32EFC7CB, 0xC3EA3F20,
+"Fighting Force 64 (U) [!]"},
+{0x28D5562D, 0xE4D5AE50,
+"Fire Electric Pen (J) [!]"},
+{0x22E9623F, 0xB60E52AD,
+"Flying Dragon (E) [!]"},
+{0xA92D52E5, 0x1D26B655,
+"Flying Dragon (U) [!]"},
+{0x142A17AA, 0x13028D96,
+"Forsaken 64 (E) [!]"},
+{0xC3CD76FF, 0x9B9DCBDE,
+"Forsaken 64 (G) [!]"},
+{0x9E330C01, 0x8C0314BA,
+"Forsaken 64 (U) [!]"},
+{0x3261D479, 0xED0DBC25,
+"Fox Sports College Hoops '99 (U) [!]"},
+{0xE8E5B179, 0x44AA30E8,
+"Frogger 2 (U) (Unreleased Alpha)"},
+{0xF774EAEE, 0xF0D8B13E,
+"Fushigi no Dungeon - Furai no Shiren 2 (J) [!]"},
+{0x776646F6, 0x06B9AC2B,
+"F-Zero X (E) [!]"},
+{0x4D3E622E, 0x9B828B4E,
+"F-Zero X (J) [!]"},
+{0xB30ED978, 0x3003C9F9,
+"F-Zero X (U) [!]"},
+{0x68FCF726, 0x49658CBC,
+"G.A.S.P! Fighter's NEXTream (E) [!]"},
+{0xAF8679B6, 0x5E1011BF,
+"G.A.S.P! Fighter's NEXTream (J) [!]"},
+{0x8F89ABA0, 0xC34C2610,
+"GameShark V3.3 (Unl)"},
+{0x832C168B, 0x56A2CDAE,
+"Ganbare Goemon (J)"},
+{0x457B9CD9, 0x09C55352,
+"Ganbare Goemon 2 - Deorudero Douchuu Obake Tenkomori (J) [!]"},
+{0xB2C6D27F, 0x2DA48CFD,
+"Ganbare Goemon - Mononoke Sugoroku (J)"},
+{0x21FFFD0A, 0xFA0D1D98,
+"Ganbare Nippon Olympics 2000 (J) [!]"},
+{0xD543BCD6, 0x2BA5E256,
+"Gauntlet Legends (E) [!]"},
+{0x70B0260E, 0x6716D04C,
+"Gauntlet Legends (J) [!]"},
+{0x729B5E32, 0xB728D980,
+"Gauntlet Legends (U) [!]"},
+{0x489C84E6, 0x4C6E49F9,
+"Getter Love!! Cho Renai Party Game (J) [!]"},
+{0x99179359, 0x2FE7EBC3,
+"Gex 3 - Deep Cover Gecko (E) [!]"},
+{0x874733A4, 0xA823745A,
+"Gex 3 - Deep Cover Gecko (FG) [!]"},
+{0x3EDC7E12, 0xE26C1CC9,
+"Gex 3 - Deep Cover Gecko (U) [!]"},
+{0xE68A000E, 0x639166DD,
+"Gex 64 - Enter the Gecko (E) [!]"},
+{0x89FED774, 0xCAAFE21B,
+"Gex 64 - Enter the Gecko (U) [!]"},
+{0xF5237301, 0x99E3EE93,
+"Glover (E) [!]"},
+{0x8E6E01FF, 0xCCB4F948,
+"Glover (U) [!]"},
+{0x4252A5AD, 0xAE6FBF4E,
+"Goemon's Great Adventure (U) [!]"},
+{0x4690FB1C, 0x4CD56D44,
+"Golden Nugget 64 (U) [!]"},
+{0x0414CA61, 0x2E57B8AA,
+"GoldenEye 007 (E) [!]"},
+{0xA24F4CF1, 0xA82327BA,
+"GoldenEye 007 (J) [!]"},
+{0xDCBC50D1, 0x09FD1AA3,
+"GoldenEye 007 (U) [!]"},
+{0xEE4A0E33, 0x8FD588C9,
+"GT 64 Championship Edition (E) [!]"},
+{0xC49ADCA2, 0xF1501B62,
+"GT 64 Championship Edition (U) [!]"},
+{0x95A80114, 0xE0B72A7F,
+"Hamster Monogatari 64 (J)"},
+{0x36F22FBF, 0x318912F2,
+"Hanafuda 64 - Tenshi no Yakusoku (J) [!]"},
+{0x09AE57B1, 0x182A5637,
+"Harukanaru Augusta Masters 98 (J) [!]"},
+{0x98DF9DFC, 0x6606C189,
+"Harvest Moon 64 (U) [!]"},
+{0x3E70E866, 0x4438BAE8,
+"Heiwa Pachinko World (J) [!]"},
+{0xAE90DBEB, 0x79B89123,
+"Hercules - The Legendary Journeys (E) [!]"},
+{0x7F3CEB77, 0x8981030A,
+"Hercules - The Legendary Journeys (U) [!]"},
+{0x95B2B30B, 0x2B6415C1,
+"Hexen (E) [!]"},
+{0x5C1B5FBD, 0x7E961634,
+"Hexen (F)"},
+{0x9AB3B50A, 0xBC666105,
+"Hexen (G) [!]"},
+{0x66751A57, 0x54A29D6E,
+"Hexen (J) [!]"},
+{0x9CAB6AEA, 0x87C61C00,
+"Hexen (U) [!]"},
+{0xD3F10E5D, 0x052EA579,
+"Hey You, Pikachu! (U) [!]"},
+{0x35FF8F1A, 0x6E79E3BE,
+"Hiro no Ken Twin (J) [!]"},
+{0x277B129D, 0xDD3879FF,
+"Holy Magic Century (E) [!]"},
+{0xB35FEBB0, 0x7427B204,
+"Holy Magic Century (F)"},
+{0x75FA0E14, 0xC9B3D105,
+"Holy Magic Century (G) [!]"},
+{0xC1D702BD, 0x6D416547,
+"Hoshi no Kirby 64 (J) (v1.0)"},
+{0xCA1BB86F, 0x41CCA5C5,
+"Hoshi no Kirby 64 (J) (V1.1)"},
+{0x0C581C7A, 0x3D6E20E4,
+"Hoshi no Kirby 64 (J) (v1.2)"},
+{0xBCB1F89F, 0x060752A2,
+"Hoshi no Kirby 64 (J) (v1.3)"},
+{0xE7D20193, 0xC1158E93,
+"Hot Wheels Turbo Racing (E) [!]"},
+{0xC7C98F8E, 0x42145DDE,
+"Hot Wheels Turbo Racing (U) [!]"},
+{0x72611D7D, 0x9919BDD2,
+"HSV Adventure Racing (A)"},
+{0x5535972E, 0xBD8E3295,
+"Human Grand Prix (J) [!]"},
+{0x641D3A7F, 0x86820466,
+"Hybrid Heaven (E) [!]"},
+{0x0DE2CE36, 0xD41D29E6,
+"Hybrid Heaven (J) [!]"},
+{0x102888BF, 0x434888CA,
+"Hybrid Heaven (U) [!]"},
+{0xB58988E9, 0xB1FC4BE8,
+"Hydro Thunder (E) [!]"},
+{0x29A045CE, 0xABA9060E,
+"Hydro Thunder (F)"},
+{0xC8DC65EB, 0x3D8C8904,
+"Hydro Thunder (U) [!]"},
+{0x69458B9E, 0xFC95F936,
+"Iggy-kun no Bura Bura Poyon (J) [!]"},
+{0xD692CC5E, 0xEC58D072,
+"Iggy's Reckin' Balls (E) [!]"},
+{0xE616B5BC, 0xC9658B88,
+"Iggy's Reckin' Balls (U) [!]"},
+{0xAF9DCC15, 0x1A723D88,
+"Indiana Jones and the Infernal Machine (U) [!]"},
+{0xE436467A, 0x82DE8F9B,
+"Indy Racing 2000 (U) [!]"},
+{0x8C138BE0, 0x95700E46,
+"In-Fisherman Bass Hunter 64 (U) [!]"},
+{0x336364A0, 0x06C8D5BF,
+"International Superstar Soccer 2000 (E) [!]"},
+{0xBAE8E871, 0x35FF944E,
+"International Superstar Soccer 2000 (FI)"},
+{0x8E835437, 0xCD5748B4,
+"International Superstar Soccer 2000 (U) [!]"},
+{0xE2D37CF0, 0xF57E4EAE,
+"International Superstar Soccer 64 (E) [!]"},
+{0x5F2763C4, 0x62412AE5,
+"International Superstar Soccer 64 (U) [!]"},
+{0xF41B6343, 0xC10661E6,
+"International Superstar Soccer '98 (E) [!]"},
+{0x7F0FDA09, 0x6061CE0B,
+"International Superstar Soccer '98 (U) [!]"},
+{0x20073BC7, 0x5E3B0111,
+"International Track and Field 2000 (U) [!]"},
+{0x6712C779, 0x3B72781D,
+"International Track and Field Summer Games (E) [!]"},
+{0x87766747, 0x91C27165,
+"J. League Dynamite Soccer (J) [!]"},
+{0x4FBFA429, 0x6920BB15,
+"J. League Eleven Beat 1997 (J) [!]"},
+{0x54554A42, 0xE4985FFB,
+"J. League Live 64 (J)"},
+{0xE8D29DA0, 0x15E61D94,
+"J. League Tactics Soccer (J) [!]"},
+{0xC73AD016, 0x48C5537D,
+"Jangou Simulation Mahjong Do 64 (J) [!]"},
+{0x69256460, 0xB9A3F586,
+"Jeopardy! (U) [!]"},
+{0x21F7ABFB, 0x6A8AA7E8,
+"Jeremy McGrath Supercross 2000 (E) [!]"},
+{0xBB30B1A5, 0xFCF712CE,
+"Jeremy McGrath Supercross 2000 (U) [!]"},
+{0xDFD8AB47, 0x3CDBEB89,
+"Jet Force Gemini - Kiosk (U) [!]"},
+{0x68D7A1DE, 0x0079834A,
+"Jet Force Gemini (E) [!]"},
+{0x8A6009B6, 0x94ACE150,
+"Jet Force Gemini (U) [!]"},
+{0xCDB8B4D0, 0x8832352D,
+"Jet Force Gemini (U) [f1]"},
+{0xAF19D9F5, 0xB70223CC,
+"Jikkyou G1 Stable (J) [!]"},
+{0x63112A53, 0xA29FA88F,
+"Jikkyou J. League 1999 - Perfect Striker 2 (J) [!]"},
+{0x146C4366, 0x72A6DEB3,
+"Jikkyou J. League Perfect Striker (J) [!]"},
+{0x0AC244D1, 0x1F0EC605,
+"Jikkyou Powerful Pro Yakyuu 2000 (J) (V1.0) [!]"},
+{0x4264DF23, 0xBE28BDF7,
+"Jikkyou Powerful Pro Yakyuu 2000 (J) (V1.1) [!]"},
+{0x6EDD4766, 0xA93E9BA8,
+"Jikkyou Powerful Pro Baseball Basic 2001 (J) [!]"},
+{0x3FEA5620, 0x7456DB40,
+"Jikkyou World Cup France '98 (J) (v1.0)"},
+{0xC954B38C, 0x6F62BEB3,
+"Jikkyou World Cup France '98 (J) (v1.1)"},
+{0xE1C7ABD6, 0x4E707F28,
+"Jikkyou World Cup France '98 (J) (v1.2)"},
+{0xE0A79F8C, 0x32CC97FA,
+"Jikkyou World Soccer 3 (J) [!]"},
+{0x4AAAF6ED, 0x376428AD,
+"Jinsei Game 64 (J) [!]"},
+{0x0F743195, 0xD8A6DB95,
+"John Romero's Daikatana (E) [!]"},
+{0x9D7E3C4B, 0xE60F4A6C,
+"John Romero's Daikatana (J) [!]"},
+{0xD0151AB0, 0xFE5CA14B,
+"John Romero's Daikatana (U) [!]"},
+{0x4F29474F, 0x30CB707A,
+"Kakutou Denshou - F-Cup Maniax (J) [!]"},
+{0x36281F23, 0x009756CF,
+"Ken Griffey Jr.'s Slugfest (U) [!]"},
+{0x979B263E, 0xF8470004,
+"Killer Instinct Gold (E) [!]"},
+{0x9E8FE2BA, 0x8B270770,
+"Killer Instinct Gold (U) (V1.0) [!]"},
+{0x9E8FCDFA, 0x49F5652B,
+"Killer Instinct Gold (U) (V1.1) [!]"},
+{0xF908CA4C, 0x36464327,
+"Killer Instinct Gold (U) (V1.2) [!]"},
+{0x519EA4E1, 0xEB7584E8,
+"King Hill 64 - Extreme Snowboarding (J) [!]"},
+{0x75BC6AD6, 0x78552BC9,
+"Kiratto Kaiketsu! 64 Tanteidan (J) [!]"},
+{0x0D93BA11, 0x683868A6,
+"Kirby 64 - The Crystal Shards (E) [!]"},
+{0x46039FB4, 0x0337822C,
+"Kirby 64 - The Crystal Shards (U) [!]"},
+{0x4A997C74, 0xE2087F99,
+"Knife Edge - Nose Gunner (E) [!]"},
+{0x931AEF3F, 0xEF196B90,
+"Knife Edge - Nose Gunner (J) [!]"},
+{0xFCE0D799, 0x65316C54,
+"Knife Edge - Nose Gunner (U) [!]"},
+{0xE3D6A795, 0x2A1C5D3C,
+"Knockout Kings 2000 (E) [!]"},
+{0x0894909C, 0xDAD4D82D,
+"Knockout Kings 2000 (U) [!]"},
+{0x1739EFBA, 0xD0B43A68,
+"Kobe Bryant's NBA Courtside (E) [!]"},
+{0x616B8494, 0x8A509210,
+"Kobe Bryant's NBA Courtside (U) [!]"},
+{0x5E3E60E8, 0x4AB5D495,
+"Kuiki Uhabi Suigo (J) [!]"},
+{0x7F304099, 0x52CF5276,
+"Last Legion UX (J) [!]"},
+{0xE97955C6, 0xBC338D38,
+"Legend of Zelda 2, The - Majora's Mask (E) [!]"},
+{0x0A5D8F83, 0x98C5371A,
+"Legend of Zelda, The - Majora's Mask (E) (M4) (v1.1)"},
+{0x5354631C, 0x03A2DEF0,
+"Legend of Zelda 2, The - Majora's Mask (U) [!]"},
+{0xB044B569, 0x373C1985,
+"Legend of Zelda, The - Ocarina of Time (E) (V1.0) [!]"},
+{0xB2055FBD, 0x0BAB4E0C,
+"Legend of Zelda, The - Ocarina of Time (E) (M3) (V1.1)"},
+{0x09465AC3, 0xF8CB501B,
+"Legend of Zelda, The - Ocarina of Time (E) (GC Version)"},
+{0xEC7011B7, 0x7616D72B,
+"Legend of Zelda, The - Ocarina of Time (U) (V1.0) [!]"},
+{0xD43DA81F, 0x021E1E19,
+"Legend of Zelda, The - Ocarina of Time (U) (V1.1) [!]"},
+{0x693BA2AE, 0xB7F14E9F,
+"Legend of Zelda, The - Ocarina of Time (U) (V1.2) [!]"},
+{0xF034001A, 0xAE47ED06,
+"Legend of Zelda, The - Ocarina of Time - Master Quest (U) (GC Version)"},
+{0xF3DD35BA, 0x4152E075,
+"Legend of Zelda, The - Ocarina of Time (U) (GC Version)"},
+{0x1D4136F3, 0xAF63EEA9,
+"Legend of Zelda, The - Ocarina of Time - Master Quest (E) [h1C]"},
+{0x1D4136F3, 0xAF63EEA9,
+"Legend of Zelda, The - Ocarina of Time - Master Quest (E)"},
+{0x27A3831D, 0xB505A533,
+"Legend of Zelda, The - Ocarina of Time - Master Quest (E) [f1] (NTSC)"},
+{0xB443EB08, 0x4DB31193,
+"Legend of Zelda, The - Majora's Mask - Collector's Edition (U) (GC Version)"},
+{0xB443EB08, 0x4DB31193,
+"Legend of Zelda, The - Majora's Mask (U) (GC Version)"},
+{0x917D18F6, 0x69BC5453,
+"Legend of Zelda, The - Ocarina of Time - Master Quest (U) (Debug Rom)"},
+{0x6AECEC4F, 0xF0924814,
+"Legend of Zelda, The - Majora's Mask - Collector's Edition (E) (GC Version)"},
+{0xBF799345, 0x39FF7A02,
+"Legend of Zelda, The - Majora's Mask (U) (Demo)"},
+{0xF478D8B3, 0x9716DD6D,
+"LEGO Racers (E) [!]"},
+{0x096A40EA, 0x8ABE0A10,
+"LEGO Racers (U) [!]"},
+{0x2B696CB4, 0x7B93DCD8,
+"Les Razmoket - La Chasse Aux Tresors (F) [!]"},
+{0x3D67C62B, 0x31D03150,
+"Let's Smash Tennis (J) [!]"},
+{0x60460680, 0x305F0E72,
+"Lode Runner 3-D (E) [!]"},
+{0x964ADD0B, 0xB29213DB,
+"Lode Runner 3-D (J) [!]"},
+{0x255018DF, 0x57D6AE3A,
+"Lode Runner 3-D (U) [!]"},
+{0x0AA0055B, 0x7637DF65,
+"Looney Tunes - Duck Dodgers (E) [!]"},
+{0x2483F22B, 0x136E025E,
+"Lylat Wars (A) [!]"},
+{0xF4CBE92C, 0xB392ED12,
+"Lylat Wars (E) [!]"},
+{0x1145443D, 0x11610EDB,
+"Mace - The Dark Age (E) [!]"},
+{0x6B700750, 0x29D621FE,
+"Mace - The Dark Age (U) [!]"},
+{0x0CB81686, 0x5FD85A81,
+"Madden 2000 (U) [!]"},
+{0xA197CB52, 0x7520DE0E,
+"Madden Football 64 (E) [!]"},
+{0x13836389, 0x265B3C76,
+"Madden Football 64 (U) [!]"},
+{0xEB38F792, 0x190EA246,
+"Madden NFL 2001 (U) [!]"},
+{0xD7134F8D, 0xC11A00B5,
+"Madden NFL 2002 (U) [!]"},
+{0x3925D625, 0x8C83C75E,
+"Madden NFL 99 (E) [!]"},
+{0xDEB78BBA, 0x52F6BD9D,
+"Madden NFL 99 (U) [!]"},
+{0xE4906679, 0x9F243F05,
+"Magical Tetris Challenge (E) [!]"},
+{0xE1EF93F7, 0x14908B0B,
+"Magical Tetris Challenge (G) [!]"},
+{0x80C8564A, 0x929C65AB,
+"Magical Tetris Challenge (J) [!]"},
+{0x75B61647, 0x7ADABF78,
+"Magical Tetris Challenge (U) [!]"},
+{0xC53EDC41, 0xECE19359,
+"Mahjong 64 (KOEI) (J) [!]"},
+{0xCCCC821E, 0x96E88A83,
+"Mahjong Hourouki Classic (J) [!]"},
+{0x0FC42C70, 0x8754F1CD,
+"Mahjong Master (J) [!]"},
+{0xCDB998BE, 0x1024A5C8,
+"Major League Baseball Featuring Ken Griffey Jr. (E) [!]"},
+{0x80C1C05C, 0xEA065EF4,
+"Major League Baseball Featuring Ken Griffey Jr. (U) [!]"},
+{0x9CCE5B1D, 0x6351E283,
+"MAME 64 Emulator V1.0 (PD)"},
+{0x62E957D0, 0x7FC15A5D,
+"Mario Golf (E) [!]"},
+{0x664BA3D4, 0x678A80B7,
+"Mario Golf (U) [!]"},
+{0xD48944D1, 0xB0D93A0E,
+"Mario Golf 64 (J) [!]"},
+{0xC3B6DE9D, 0x65D2DE76,
+"Mario Kart 64 (E) (V1.0) [!]"},
+{0x2577C7D4, 0xD18FAAAE,
+"Mario Kart 64 (E) (V1.1) [!]"},
+{0x6BFF4758, 0xE5FF5D5E,
+"Mario Kart 64 (J) (V1.0) [!]"},
+{0xC9C3A987, 0x5810344C,
+"Mario Kart 64 (J) (V1.1) [!]"},
+{0x3E5055B6, 0x2E92DA52,
+"Mario Kart 64 (U) [!]"},
+{0x9A9890AC, 0xF0C313DF,
+"Mario no Photopie (J) [!]"},
+{0x9C663069, 0x80F24A80,
+"Mario Party (E) [!]"},
+{0xADA815BE, 0x6028622F,
+"Mario Party (J) [!]"},
+{0x2829657E, 0xA0621877,
+"Mario Party (U) [!]"},
+{0x82380387, 0xDFC744D9,
+"Mario Party 2 (E) [!]"},
+{0xED567D0F, 0x38B08915,
+"Mario Party 2 (J) [!]"},
+{0x9EA95858, 0xAF72B618,
+"Mario Party 2 (U) [!]"},
+{0xC5674160, 0x0F5F453C,
+"Mario Party 3 (E) [!]"},
+{0x0B0AB4CD, 0x7B158937,
+"Mario Party 3 (J) [!]"},
+{0x7C3829D9, 0x6E8247CE,
+"Mario Party 3 (U) [!]"},
+{0x3BA7CDDC, 0x464E52A0,
+"Mario Story (J) [!]"},
+{0x839F3AD5, 0x406D15FA,
+"Mario Tennis (E) [!]"},
+{0x3A6C42B5, 0x1ACADA1B,
+"Mario Tennis (J) [!]"},
+{0x5001CF4F, 0xF30CB3BD,
+"Mario Tennis (U) [!]"},
+{0x0EC158F5, 0xFB3E6896,
+"Mega Man 64 (U) [!]"},
+{0x1001F10C, 0x3D51D8C1,
+"Mia Hamm Soccer 64 (U) [!]"},
+{0xE36166C2, 0x8613A2E5,
+"Michael Owens WLS 2000 (E) [!]"},
+{0x736AE6AF, 0x4117E9C7,
+"Mickey no Racing Challenge USA (J) [!]"},
+{0xDED0DD9A, 0xE78225A7,
+"Mickey's Speedway USA (E) [!]"},
+{0xFA8C4571, 0xBBE7F9C0,
+"Mickey's Speedway USA (U) [!]"},
+{0x2A49018D, 0xD0034A02,
+"Micro Machines 64 Turbo (E) [!]"},
+{0xF1850C35, 0xACE07912,
+"Micro Machines 64 Turbo (U) [!]"},
+{0xE4B35E4C, 0x1AC45CC9,
+"Midway's Greatest Arcade Hits Volume 1 (U) [!]"},
+{0x09D53E16, 0x3AB268B9,
+"Mike Piazza's Strike Zone (U) [!]"},
+{0x9A490D9D, 0x8F013ADC,
+"Milo's Astro Lanes (E) [!]"},
+{0x2E955ECD, 0xF3000884,
+"Milo's Astro Lanes (U) [!]"},
+{0x418BDA98, 0x248A0F58,
+"Mischief Makers (E) [!]"},
+{0x0B93051B, 0x603D81F9,
+"Mischief Makers (U) [!]"},
+{0x2256ECDA, 0x71AB1B9C,
+"Mission Impossible (E) [!]"},
+{0x20095B34, 0x343D9E87,
+"Mission Impossible (F) [!]"},
+{0x93EB3F7E, 0x81675E44,
+"Mission Impossible (G) [!]"},
+{0xEBA949DC, 0x39BAECBD,
+"Mission Impossible (I) [!]"},
+{0x5F6A04E2, 0xD4FA070D,
+"Mission Impossible (S) [!]"},
+{0x26035CF8, 0x802B9135,
+"Mission Impossible (U) [!]"},
+{0x28768D6D, 0xB379976C,
+"Monaco Grand Prix (U) [!]"},
+{0x5AC383E1, 0xD712E387,
+"Monopoly (U) [!]"},
+{0xD3D806FC, 0xB43AA2A8,
+"Monster Truck Madness 64 (E) [!]"},
+{0xB19AD999, 0x7E585118,
+"Monster Truck Madness 64 (U) [!]"},
+{0xE8E8DD70, 0x415DD198,
+"Morita Shogi 64 (J) [!]"},
+{0x73036F3B, 0xCE0D69E9,
+"Mortal Kombat 4 (E) [!]"},
+{0x417DD4F4, 0x1B482FE2,
+"Mortal Kombat 4 (U) [!]"},
+{0xFF44EDC4, 0x1AAE9213,
+"Mortal Kombat Mythologies - Sub-Zero (E) [!]"},
+{0xC34304AC, 0x2D79C021,
+"Mortal Kombat Mythologies - Sub-Zero (U) [!]"},
+{0x8C3D1192, 0xBEF172E1,
+"Mortal Kombat Trilogy (E) [!]"},
+{0xD9F75C12, 0xA8859B59,
+"Mortal Kombat Trilogy (U) (V1.0) [!]"},
+{0x83F33AA9, 0xA901D40D,
+"Mortal Kombat Trilogy (U) (V1.2) [!]"},
+{0xB8F0BD03, 0x4479189E,
+"MRC - Multi Racing Championship (E) [!]"},
+{0xA6B6B413, 0x15D113CC,
+"MRC - Multi Racing Championship (J) [!]"},
+{0x2AF9B65C, 0x85E2A2D7,
+"MRC - Multi Racing Championship (U) [!]"},
+{0x1938525C, 0x586E9656,
+"Ms. Pac-Man Maze Madness (U) [!]"},
+{0xF5360FBE, 0x2BF1691D,
+"Mystical Ninja - Starring Goemon (E) [!]"},
+{0xFCBCCB21, 0x72903C6B,
+"Mystical Ninja - Starring Goemon (U) [!]"},
+{0x7F9345D3, 0x841ECADE,
+"Mystical Ninja 2 - Starring Goemon (E) [!]"},
+{0xAE2D3A35, 0x24F0D41A,
+"Nagano Olympic Hockey '98 (E) [!]"},
+{0x7EC22587, 0xEF1AE323,
+"Nagano Olympic Hockey '98 (U) [!]"},
+{0x90F43037, 0x5C5370F5,
+"Nagano Olympic Hockey '98 (J) [!]"},
+{0x6D452016, 0x713C09EE,
+"Nagano Winter Olympics '98 (E) [!]"},
+{0x2FC5C34C, 0x7A05CC9D,
+"Nagano Winter Olympics '98 (J) [!]"},
+{0x8D2BAE98, 0xD73725BF,
+"Nagano Winter Olympics '98 (U) [!]"},
+{0x5129B6DA, 0x9DEF3C8C,
+"Namco Museum 64 (U) [!]"},
+{0xDF331A18, 0x5FD4E044,
+"NASCAR 2000 (U) [!]"},
+{0xAE4992C9, 0x9253B253,
+"NASCAR 99 (E) [!]"},
+{0x23749578, 0x80DC58FD,
+"NASCAR 99 (U) [!]"},
+{0x916852D8, 0x73DBEAEF,
+"NBA Courtside 2 - Featuring Kobe Bryant (U) [!]"},
+{0xC788DCAE, 0xBD03000A,
+"NBA Hangtime (E) [!]"},
+{0x4E69B487, 0xFE18E290,
+"NBA Hangtime (U) [!]"},
+{0xAAE11F01, 0x2625A045,
+"NBA In the Zone 2 (J) [!]"},
+{0xB3054F9F, 0x96B69EB5,
+"NBA In the Zone 2000 (E) [!]"},
+{0x8DF95B18, 0xECDA497B,
+"NBA In the Zone 2000 (U) [!]"},
+{0x36ACBA9B, 0xF28D4D94,
+"NBA In the Zone '98 (J) [!]"},
+{0x6A121930, 0x665CC274,
+"NBA In the Zone '98 (U) [!]"},
+{0xA292524F, 0x3D6C2A49,
+"NBA In the Zone '99 (U) [!]"},
+{0xB6D0CAA0, 0xE3F493C8,
+"NBA Jam 2000 (E) [!]"},
+{0xEBEEA8DB, 0xF2ECB23C,
+"NBA Jam 2000 (U) [!]"},
+{0xE600831E, 0x59F422A8,
+"NBA Jam 99 (E) [!]"},
+{0x810729F6, 0xE03FCFC1,
+"NBA Jam 99 (U) [!]"},
+{0xEB499C8F, 0xCD4567B6,
+"NBA Live 2000 (E) [!]"},
+{0x5F25B0EE, 0x6227C1DB,
+"NBA Live 2000 (U) [!]"},
+{0xCF84F45F, 0x00E4F6EB,
+"NBA Live 99 (E) [!]"},
+{0x57F81C9B, 0x1133FA35,
+"NBA Live 99 (U) [!]"},
+{0xACDE962F, 0xB2CBF87F,
+"NBA Pro 98 (E) [!]"},
+{0x8D1780B6, 0x57B3B976,
+"NBA Pro 99 (E) [!]"},
+{0x3FFE80F4, 0xA7C15F7E,
+"NBA Showtime - NBA on NBC (U) [!]"},
+{0x147E0EDB, 0x36C5B12C,
+"Neon Genesis Evangelion (J) [!]"},
+{0xE61CFF0A, 0xCE1C0D71,
+"New Tetris, The (E) [!]"},
+{0x2153143F, 0x992D6351,
+"New Tetris, The (U) [!]"},
+{0x30EAD54F, 0x31620BF6,
+"NFL Blitz - Special Edition (U) [!]"},
+{0xD094B170, 0xD7C4B5CC,
+"NFL Blitz (U) [!]"},
+{0x15A00969, 0x34E5A285,
+"NFL Blitz 2000 (U) [!]"},
+{0x36FA35EB, 0xE85E2E36,
+"NFL Blitz 2001 (U) [!]"},
+{0x88BD5A9E, 0xE81FDFBF,
+"NFL Quarterback Club 2000 (E) [!]"},
+{0xE3AB4ED0, 0x83040DD2,
+"NFL Quarterback Club 2000 (U) [!]"},
+{0x28784622, 0xFFB22985,
+"NFL Quarterback Club 2001 (U) [!]"},
+{0x4B629EF4, 0x99B21D9B,
+"NFL Quarterback Club 98 (E) [!]"},
+{0xD89BE2F8, 0x99C97ADF,
+"NFL Quarterback Club 98 (U) [!]"},
+{0x52A3CF47, 0x4EC13BFC,
+"NFL Quarterback Club 99 (E) [!]"},
+{0xBE76EDFF, 0x20452D09,
+"NFL Quarterback Club 99 (U) [!]"},
+{0x287D601E, 0xABF4F8AE,
+"NHL 99 (E) [!]"},
+{0x591A806E, 0xA5E6921D,
+"NHL 99 (U) [!]"},
+{0x82EFDC30, 0x806A2461,
+"NHL Blades of Steel '99 (U) [!]"},
+{0x29CE7692, 0x71C58579,
+"NHL Breakaway 98 (E) [!]"},
+{0x6DFDCDC3, 0x4DE701C8,
+"NHL Breakaway 98 (U) [!]"},
+{0x874621CB, 0x0031C127,
+"NHL Breakaway 99 (E) [!]"},
+{0x441768D0, 0x7D73F24F,
+"NHL Breakaway 99 (U) [!]"},
+{0xA9895CD9, 0x7020016C,
+"NHL Pro 99 (E) [!]"},
+{0x2857674D, 0xCC4337DA,
+"Nightmare Creatures (U) [!]"},
+{0xCD3C3CDF, 0x317793FA,
+"Nintama Rantarou 64 (J)"},
+{0x8A97A197, 0x272DF6C1,
+"Nuclear Strike 64 (E) [!]"},
+{0x8F50B845, 0xD729D22F,
+"Nuclear Strike 64 (G) [!]"},
+{0x4998DDBB, 0xF7B7AEBC,
+"Nuclear Strike 64 (U) [!]"},
+{0x5B9B1618, 0x1B43C649,
+"Nushi Tsuri 64 - Shiokaze ni Notte (J) [!]"},
+{0xD83BB920, 0xCC406416,
+"Nushi Tsuri 64 (J) [!]"},
+{0xE86415A6, 0x98395B53,
+"O.D.T (Or Die Trying) (E) (M5) (Unreleased Final)"},
+{0x2655BB70, 0x667D9925,
+"O.D.T (Or Die Trying) (U) (M3) (Unreleased Final)"},
+{0x812289D0, 0xC2E53296,
+"Off Road Challenge (E) [!]"},
+{0x319093EC, 0x0FC209EF,
+"Off Road Challenge (U) [!]"},
+{0x0375CF67, 0x56A93FAA,
+"Ogre Battle 64 - Person of Lordly Caliber (J) (V1.1) [!]"},
+{0xE6419BC5, 0x69011DE3,
+"Ogre Battle 64 - Person of Lordly Caliber (U) [!]"},
+{0xDC649466, 0x572FF0D9,
+"Onegai Monsters (J) [!]"},
+{0x74554B3B, 0xF4AEBCB5,
+"Pachinko 365 Nichi (J) [!]"},
+{0x19AB29AF, 0xC71BCD28,
+"Paper Mario (E) [!]"},
+{0x65EEE53A, 0xED7D733C,
+"Paper Mario (U) [!]"},
+{0xAC976B38, 0xC3A9C97A,
+"Paperboy (E) [!]"},
+{0x3E198D9E, 0xF2E1267E,
+"Paperboy (U) [!]"},
+{0xCFE2CB31, 0x4D6B1E1D,
+"Parlor! Pro 64 Pachinko Jikki Simulation Game (J) [!]"},
+{0x34495BAD, 0x502E9D26,
+"Jikkyou Powerful Pro Yakyuu 4 (J) [!]"},
+{0xD7891F1C, 0xC3E43788,
+"Jikkyou Powerful Pro Yakyuu 4 (J) (V1.1) [!]"},
+{0xD22943DA, 0xAC2B77C0,
+"Jikkyou Powerful Pro Yakyuu 5 (J) [!]"},
+{0xB75E20B7, 0xB3FEFDFD,
+"Jikkyou Powerful Pro Yakyuu (J) [!]"},
+{0xF468118C, 0xE32EE44E,
+"PD Ultraman Battle Collection 64 (J) [!]"},
+{0xC83CEB83, 0xFDC56219,
+"Penny Racers (E) [!]"},
+{0x73ABB1FB, 0x9CCA6093,
+"Penny Racers (U) [!]"},
+{0xE4B08007, 0xA602FF33,
+"Perfect Dark (E) [!]"},
+{0x96747EB4, 0x104BB243,
+"Perfect Dark (J) [!]"},
+{0xDDF460CC, 0x3CA634C0,
+"Perfect Dark (U) (V1.0) [!]"},
+{0x41F2B98F, 0xB458B466,
+"Perfect Dark (U) (V1.1) [!]"},
+{0xEE08C602, 0x6BC2D5A6,
+"PGA European Tour (E) [!]"},
+{0xB54CE881, 0xBCCB6126,
+"PGA European Tour (U) [!]"},
+{0x3F245305, 0xFC0B74AA,
+"Pikachu Genki Dechu (J) [!]"},
+{0x1AA05AD5, 0x46F52D80,
+"Pilotwings 64 (E) [!]"},
+{0x09CC4801, 0xE42EE491,
+"Pilotwings 64 (J) [!]"},
+{0xC851961C, 0x78FCAAFA,
+"Pilotwings 64 (U) [!]"},
+{0xEC0F690D, 0x32A7438C,
+"Pocket Monsters Snap (J) [!]"},
+{0x665E8259, 0xD098BD1D,
+"Pocket Monsters Stadium (J) [!]"},
+{0x63775886, 0x5FB80E7B,
+"Pocket Monsters Stadium 2 (J) [!]"},
+{0x4A1CD153, 0xD830AEF8,
+"Pokemon Puzzle League (E) [!]"},
+{0x3EB2E6F3, 0x062F9EFE,
+"Pokemon Puzzle League (F) [!]"},
+{0x7A4747AC, 0x44EEEC23,
+"Pokemon Puzzle League (G) [!]"},
+{0x19C553A7, 0xA70F4B52,
+"Pokemon Puzzle League (U) [!]"},
+{0x7BB18D40, 0x83138559,
+"Pokemon Snap (A) [!]"},
+{0x4FF5976F, 0xACF559D8,
+"Pokemon Snap (E) [!]"},
+{0xBA6C293A, 0x9FAFA338,
+"Pokemon Snap (F) [!]"},
+{0x5753720D, 0x2A8A884D,
+"Pokemon Snap (G) [!]"},
+{0xC0C85046, 0x61051B05,
+"Pokemon Snap (I) [!]"},
+{0x817D286A, 0xEF417416,
+"Pokemon Snap (S) [!]"},
+{0xCA12B547, 0x71FA4EE4,
+"Pokemon Snap (U) [!]"},
+{0x39119872, 0x07722E9F,
+"Pokemon Snap Station (U) [!]"},
+{0x1A122D43, 0xC17DAF0F,
+"Pokemon Stadium - Kiosk (U) (V1.1) [!]"},
+{0x84077275, 0x57315B9C,
+"Pokemon Stadium (E) [!]"},
+{0x91C9E05D, 0xAD3AAFB9,
+"Pokemon Stadium (E) (V1.1)"},
+{0xA23553A3, 0x42BF2D39,
+"Pokemon Stadium (F) [!]"},
+{0x42011E1B, 0xE3552DB5,
+"Pokemon Stadium (G) [!]"},
+{0xA53FA82D, 0xDAE2C15D,
+"Pokemon Stadium (I)"},
+{0xB6E549CE, 0xDC8134C0,
+"Pokemon Stadium (S) [!]"},
+{0x90F5D9B3, 0x9D0EDCF0,
+"Pokemon Stadium (U) [!]"},
+{0x2952369C, 0xB6E4C3A8,
+"Pokemon Stadium 2 (E) [!]"},
+{0xAC5AA5C7, 0xA9B0CDC3,
+"Pokemon Stadium 2 (F) [!]"},
+{0x439B7E7E, 0xC1A1495D,
+"Pokemon Stadium 2 (G) [!]"},
+{0xEFCEAF00, 0x22094848,
+"Pokemon Stadium 2 (I)"},
+{0xD0A1FC5B, 0x2FB8074B,
+"Pokemon Stadium 2 (S) [!]"},
+{0x03571182, 0x892FD06D,
+"Pokemon Stadium 2 (U) [!]"},
+{0xEE4FD7C2, 0x9CF1D938,
+"Pokemon Stadium GS (J) [!]"},
+{0x41380792, 0xA167E045,
+"Polaris Sno Cross (U) [!]"},
+{0xD7A6DCFA, 0xCCFEB6B7,
+"Power League Baseball 64 (J) [!]"},
+{0x39F60C11, 0xAB2EBA7D,
+"Power Rangers - Lightspeed Rescue (E) [!]"},
+{0xCF8957AD, 0x96D57EA9,
+"Power Rangers - Lightspeed Rescue (U) [!]"},
+{0xFC74D475, 0x9A0278AB,
+"Powerpuff Girls, The - Chemical X-traction (U) [!]"},
+{0xF3D27F54, 0xC111ACF9,
+"Premier Manager 64 (E) [!]"},
+{0x9BA10C4E, 0x0408ABD3,
+"Pro Mahjong Kiwame 64 (J) [!]"},
+{0x1BDCB30F, 0xA132D876,
+"Pro Mahjong Tsuwamono 64 (J)"},
+{0x4B4672B9, 0x2DBE5DE7,
+"Puyo Puyo 4 - Puyo Puyo Party (J) [!]"},
+{0x94807E6B, 0x60CC62E4,
+"Puyo Puyo Sun 64 (J) [!]"},
+{0xC0DE0747, 0xA2DF72D3,
+"Puzzle Bobble 64 (J) [!]"},
+{0x4BBBA2E2, 0x8BF3BBB2,
+"Puzzle Master 64 by Michael Searl (PD)"},
+{0x16931D74, 0x65DC6D34,
+"Quake 64 (E) [!]"},
+{0x9F5BF79C, 0xD2FE08A0,
+"Quake 64 (U) [!]"},
+{0x7433D9D7, 0x2C4322D0,
+"Quake II (E) [!]"},
+{0xBDA8F143, 0xB1AF2D62,
+"Quake II (U) [!]"},
+{0xC8BB4DD9, 0xCC5F430B,
+"Quest 64 (U) [!]"},
+{0x28705FA5, 0xB509690E,
+"Racing Simulation - Monaco Grand Prix (E) [!]"},
+{0x2877AC2D, 0xC3DC139A,
+"Racing Simulation 2 (G) [!]"},
+{0x67D21868, 0xC5424061,
+"Rakuga Kids (E) [!]"},
+{0x9F1ECAF0, 0xEEC48A0E,
+"Rakuga Kids (J) [!]"},
+{0x35D9BA0C, 0xDF485586,
+"Rally '99 (J) [!]"},
+{0x73A88E3D, 0x3AC5C571,
+"Rally Challenge 2000 (U) [!]"},
+{0x84D44448, 0x67CA19B0,
+"Rampage - World Tour (E) [!]"},
+{0xC29FF9E4, 0x264BFE7D,
+"Rampage - World Tour (U) [!]"},
+{0x5DFC4249, 0x99529C07,
+"Rampage 2 - Universal Tour (E) [!]"},
+{0x673D099B, 0xA4C808DE,
+"Rampage 2 - Universal Tour (U) [!]"},
+{0x20FD0BF1, 0xF5CF1D87,
+"Rat Attack (E) [!]"},
+{0x0304C48E, 0xAC4001B8,
+"Rat Attack (U) [!]"},
+{0x60D5E10B, 0x8BEDED46,
+"Rayman 2 - The Great Escape (E) [!]"},
+{0xF3C5BF9B, 0x160F33E2,
+"Rayman 2 - The Great Escape (U) [!]"},
+{0x3918834A, 0x15B50C29,
+"Razor Freestyle Scooter (U) [!]"},
+{0x8BD4A334, 0x1E138B05,
+"Ready 2 Rumble Boxing (E) [!]"},
+{0xEAB7B429, 0xBAC92C57,
+"Ready 2 Rumble Boxing (U) [!]"},
+{0xE9219533, 0x13FBAFBD,
+"Ready 2 Rumble Boxing Round 2 (U) [!]"},
+{0x9B500E8E, 0xE90550B3,
+"Resident Evil 2 (E) [!]"},
+{0xAA18B1A5, 0x07DB6AEB,
+"Resident Evil 2 (U) [!]"},
+{0xC3E7E29E, 0x5D7251CC,
+"Re-Volt (E) [!]"},
+{0x0F1FA987, 0xBFC1AFA6,
+"Re-Volt (U) [!]"},
+{0x02D8366A, 0x6CABEF9C,
+"Road Rash 64 (E) [!]"},
+{0xF050746C, 0x247B820B,
+"Road Rash 64 (U) [!]"},
+{0x74E87A70, 0x6293AED4,
+"Roadsters (E) [!]"},
+{0x0B6B4DDB, 0x9671E682,
+"Roadsters (U) [!]"},
+{0x272B690F, 0xAD0A7A77,
+"Robot Ponkottsu 64 - Caramel of the 7 Seas (J) [!]"},
+{0x75A0B893, 0x4CA321B5,
+"Robotech - Crystal Dreams (U) (beta)"},
+{0x9FF69D4F, 0x195F0059,
+"Robotron 64 (E) [!]"},
+{0xAC8E4B32, 0xE7B47326,
+"Robotron 64 (U) [!]"},
+{0x9FD375F8, 0x45F32DC8,
+"Rocket - Robot on Wheels (E) [!]"},
+{0x0C5EE085, 0xA167DD3E,
+"Rocket - Robot on Wheels (U) [!]"},
+{0xD666593B, 0xD7A25C07,
+"Rockman Dash (J) [!]"},
+{0xFEE97010, 0x4E94A9A0,
+"RR64 - Ridge Racer 64 (E) [!]"},
+{0x2500267E, 0x2A7EC3CE,
+"RR64 - Ridge Racer 64 (U) [!]"},
+{0x658F8F37, 0x1813D28D,
+"RTL World League Soccer 2000 (G) [!]"},
+{0x0C02B3C5, 0x9E2511B8,
+"Rugrats - Scavenger Hunt (U) [!]"},
+{0x4D3ADFDA, 0x7598FCAE,
+"Rugrats - Treasure Hunt (E) [!]"},
+{0x451ACA0F, 0x7863BC8A,
+"Rugrats - Die große Schatzsuche (G)"},
+{0x0AC61D39, 0xABFA03A6,
+"Rugrats in Paris - The Movie (E) [!]"},
+{0x1FC21532, 0x0B6466D4,
+"Rugrats in Paris - The Movie (U) [!]"},
+{0xB7CF2136, 0xFA0AA715,
+"Rush 2 - Extreme Racing USA (E) [!]"},
+{0xEDD6E031, 0x68136013,
+"Rush 2 - Extreme Racing USA (U) [!]"},
+{0x918E2D60, 0xF865683E,
+"S.C.A.R.S. (E) [!]"},
+{0x769147F3, 0x2033C10E,
+"S.C.A.R.S. (U) [!]"},
+{0x61D116B0, 0xFA24D60C,
+"San Francisco Rush - Extreme Racing (E) [!]"},
+{0x2A6B1820, 0x6ABCF466,
+"San Francisco Rush - Extreme Racing (U) [!]"},
+{0x51D29418, 0xD5B46AE3,
+"San Francisco Rush 2049 (E) [!]"},
+{0xB9A9ECA2, 0x17AAE48E,
+"San Francisco Rush 2049 (U) [!]"},
+{0xE3BD221D, 0x3C0834D3,
+"Scooby-Doo - Classic Creep Capers (E) [!]"},
+{0x0C814EC4, 0x58FE5CA8,
+"Scooby-Doo - Classic Creep Capers (U) [!]"},
+{0xEBF5F6B7, 0xC956D739,
+"SD Hiryuu no Ken Densetsu (J) [!]"},
+{0x60C437E5, 0xA2251EE3,
+"Shadow Man (E) [!]"},
+{0xEA06F8C3, 0x07C2DEED,
+"Shadow Man (F) [!]"},
+{0x84D5FD75, 0xBBFD3CDF,
+"Shadow Man (G) [!]"},
+{0x3A4760B5, 0x2D74D410,
+"Shadow Man (U) [!]"},
+{0xD84EEA84, 0x45B2F1B4,
+"Shadowgate 64 - Trials of the Four Towers (E) [!]"},
+{0x2BC1FCF2, 0x7B9A0DF4,
+"Shadowgate 64 - Trials of the Four Towers (FGD) [!]"},
+{0x02B46F55, 0x61778D0B,
+"Shadowgate 64 - Trials of the Four Towers (IS)"},
+{0xCCEDB696, 0xD3883DB4,
+"Shadowgate 64 - Trials of the Four Towers (J) [!]"},
+{0x036897CE, 0xE0D4FA54,
+"Shadowgate 64 - Trials of the Four Towers (U) [!]"},
+{0xB1D5280C, 0x4BA7BC2A,
+"Sim City 2000 (J) [!]"},
+{0xB6BC0FB0, 0xE3812198,
+"Sin and Punishment - Tsumi To Batsu (J) [!]"},
+{0x2EF4D519, 0xC64A0C5E,
+"Snow Speeder (J) [!]"},
+{0x5FD7CDA0, 0xD9BB51AD,
+"Snowboard Kids (E) [!]"},
+{0xDBF4EA9D, 0x333E82C0,
+"Snowboard Kids (U) [!]"},
+{0x84FC04FF, 0xB1253CE9,
+"Snowbow Kids (J) [!]"},
+{0xC2751D1A, 0xF8C19BFF,
+"Snowboard Kids 2 (E) [!]"},
+{0x930C29EA, 0x939245BF,
+"Snowboard Kids 2 (U) [!]"},
+{0x22212351, 0x4046594B,
+"Sonic Wings Assault (J) [!]"},
+{0xC00CA948, 0x8E60D34B,
+"South Park - Chef's Luv Shack (E) [!]"},
+{0xC00CA948, 0x8E60D34B,
+"South Park - Chef's Luv Shack (U) [!]"},
+{0x20B53662, 0x7B61899F,
+"South Park (E) [!]"},
+{0x91B66D42, 0x16AC4E46,
+"South Park (G) [!]"},
+{0x7ECBE939, 0x3C331795,
+"South Park (U) [!]"},
+{0x4F8AFC3A, 0xF7912DF2,
+"South Park Rally (E) [!]"},
+{0x07F3B276, 0xEC8F3D39,
+"South Park Rally (U) [!]"},
+{0x37463412, 0xEAC5388D,
+"Space Dynamites (J) [!]"},
+{0xEBFE2397, 0xFF74DA34,
+"Space Invaders (U) [!]"},
+{0xFC70E272, 0x08FFE7AA,
+"Spacestation Silicon Valley (E)/(F) [!]"},
+{0xBFE23884, 0xEF48EAAF,
+"Spacestation Silicon Valley (J) [!]"},
+{0xBFE23884, 0xEF48EAAF,
+"Spacestation Silicon Valley (U) [!]"},
+{0xA60ED171, 0x3D85D06E,
+"Spider-Man (U) [!]"},
+{0x0DED0568, 0x1502515E,
+"St. Andrews Old Course (J) [!]"},
+{0xFFCAA7C1, 0x68858537,
+"Star Fox 64 (J) [!]"},
+{0xA7D015F8, 0x2289AA43,
+"Star Fox 64 (U) [!]"},
+{0xBA780BA0, 0x0F21DB34,
+"Star Fox 64 (U) (V1.1)"},
+{0xB703EB23, 0x28AAE53A,
+"Star Soldier Vanishing Earth (J) [!]"},
+{0xDDD93C85, 0xDAE381E8,
+"Star Soldier Vanishing Earth (U) [!]"},
+{0xF163A242, 0xF2449B3B,
+"Star Twins (J) [!]"},
+{0x7EE0E8BB, 0x49E411AA,
+"Star Wars - Rogue Squadron (E) [!]"},
+{0x219191C1, 0x33183C61,
+"Star Wars - Rogue Squadron (E) (V1.1)"},
+{0x66A24BEC, 0x2EADD94F,
+"Star Wars - Rogue Squadron (U) [!]"},
+{0x4D486681, 0xAB7D9245,
+"Star Wars - Shadows of the Empire (E) [!]"},
+{0xFE24AC63, 0x1B41AA17,
+"Star Wars - Shadows of the Empire (J) [!]"},
+{0x264D7E5C, 0x18874622,
+"Star Wars - Shadows of the Empire (U) (V1.0) [!]"},
+{0x4147B091, 0x63251060,
+"Star Wars - Shadows of the Empire (U) (V1.1) [!]"},
+{0x4DD7ED54, 0x74F9287D,
+"Star Wars - Shadows of the Empire (U) (V1.2) [!]"},
+{0x827E4890, 0x958468DC,
+"Star Wars - Shuggeki Rogue Chitai (J) [!]"},
+{0xEAE6ACE2, 0x020B4384,
+"Star Wars Episode I - Battle for Naboo (E) [!]"},
+{0x3D02989B, 0xD4A381E2,
+"Star Wars Episode I - Battle for Naboo (U) [!]"},
+{0x53ED2DC4, 0x06258002,
+"Star Wars Episode I - Racer (E) [!]"},
+{0x61F5B152, 0x046122AB,
+"Star Wars Episode I - Racer (J) [!]"},
+{0x72F70398, 0x6556A98B,
+"Star Wars Episode I - Racer (U) [!]"},
+{0xBC9B2CC3, 0x4ED04DA5,
+"StarCraft 64 (E) [!]"},
+{0x42CF5EA3, 0x9A1334DF,
+"StarCraft 64 (E) [!]"},
+{0x0684FBFB, 0x5D3EA8A5,
+"StarCraft 64 (U) [!]"},
+{0xBC9B2CC3, 0x4ED04DA5,
+"StarCraft 64 (Beta)"},
+{0xD89E0E55, 0xB17AA99A,
+"Starshot - Space Circus Fever (E) [!]"},
+{0x94EDA5B8, 0x8673E903,
+"Starshot - Space Circus Fever (U) [!]"},
+{0x9510D8D7, 0x35100DD2,
+"Stunt Racer 64 (U) [!]"},
+{0xF4646B69, 0xC5751095,
+"Super B-Daman - Battle Phoenix 64 (J) [!]"},
+{0xF3F2F385, 0x6E490C7F,
+"Super Bowling (J) [!]"},
+{0xAA1D215A, 0x91CBBE9A,
+"Super Bowling 64 (U) [!]"},
+{0xA03CF036, 0xBCC1C5D2,
+"Super Mario 64 (E) [!]"},
+{0x4EAA3D0E, 0x74757C24,
+"Super Mario 64 (J) [!]"},
+{0x635A2BFF, 0x8B022326,
+"Super Mario 64 (U) [!]"},
+{0xD6FBA4A8, 0x6326AA2C,
+"Super Mario 64 Shindou Edition (J) [!]"},
+{0x66572080, 0x28E348E1,
+"Super Robot Spirits (J) [!]"},
+{0x1649D810, 0xF73AD6D2,
+"Super Robot Taisen 64 (J) [!]"},
+{0xDD26FDA1, 0xCB4A6BE3,
+"Super Smash Bros. (A) [!]"},
+{0x93945F48, 0x5C0F2E30,
+"Super Smash Bros. (E) [!]"},
+{0x916B8B5B, 0x780B85A4,
+"Super Smash Bros. (U) [!]"},
+{0x9CE02E22, 0x206EF1B0,
+"Super Speed Race 64 (J) [!]"},
+{0x2CBB127F, 0x09C2BFD8,
+"Supercross 2000 (E) [!]"},
+{0xC1452553, 0x5D7B24D9,
+"Supercross 2000 (U) [!]"},
+{0xB44CAB74, 0x07029A29,
+"Superman (E) [!]"},
+{0xA2E8F35B, 0xC9DC87D9,
+"Superman (U) [!]"},
+{0x35E811F3, 0x99792724,
+"Susume! Taisen Puzzle Dama Toukon! Marumata Chou (J) [!]"},
+{0xAEBCDD54, 0x15FF834A,
+"Taz Express (E) [!]"},
+{0xD9042FBB, 0xFCFF997C,
+"Telefoot Soccer 2000 (F) [!]"},
+{0x963ADBA6, 0xF7D5C89B,
+"Tetris 64 (J) [!]"},
+{0x0FE684A9, 0x8BB77AC4,
+"Tetrisphere (E) [!]"},
+{0x3C1FDABE, 0x02A4E0BA,
+"Tetrisphere (U) [!]"},
+{0xE0C4F72F, 0x769E1506,
+"Tigger's Honey Hunt (E) [!]"},
+{0x4EBFDD33, 0x664C9D84,
+"Tigger's Honey Hunt (U) [!]"},
+{0x2B4F4EFB, 0x43C511FE,
+"Tom and Jerry in Fists of Furry (E) [!]"},
+{0x63E7391C, 0xE6CCEA33,
+"Tom and Jerry in Fists of Furry (U) [!]"},
+{0x4875AF3D, 0x9A66D3A2,
+"Tom Clancy's Rainbow Six (E) [!]"},
+{0x486BF335, 0x034DCC81,
+"Tom Clancy's Rainbow Six (F)"},
+{0x8D412933, 0x588F64DB,
+"Tom Clancy's Rainbow Six (G) [!]"},
+{0x392A0C42, 0xB790E77D,
+"Tom Clancy's Rainbow Six (U) [!]"},
+{0x093F916E, 0x4408B698,
+"Tonic Trouble (E) [!]"},
+{0xEF9E9714, 0xC03B2C7D,
+"Tonic Trouble (U) (V1.1) [!]"},
+{0x9F8926A5, 0x0587B409,
+"Tony Hawk's Pro Skater (E) [!]"},
+{0x204EC022, 0xB119D185,
+"Tony Hawk's Pro Skater (U) [!]"},
+{0xE0144180, 0x650B78C9,
+"Tony Hawk's Pro Skater (V1.1) [!]"},
+{0x84EAB557, 0xC88A190F,
+"Tony Hawk's Pro Skater 2 (E) [!]"},
+{0x99150E18, 0x1266E6A5,
+"Tony Hawk's Pro Skater 2 (U) [!]"},
+{0x1A7F70B5, 0x00B7B9FD,
+"Tony Hawk's Pro Skater 3 (U)"},
+{0x5F3F49C6, 0x0DC714B0,
+"Top Gear Hyper-Bike (E) [!]"},
+{0x845B0269, 0x57DE9502,
+"Top Gear Hyper-Bike (J) [!]"},
+{0x8ECC02F0, 0x7F8BDE81,
+"Top Gear Hyper-Bike (U) [!]"},
+{0xD09BA538, 0x1C1A5489,
+"Top Gear Overdrive (E) [!]"},
+{0x0578F24F, 0x9175BF17,
+"Top Gear Overdrive (J) [!]"},
+{0xD741CD80, 0xACA9B912,
+"Top Gear Overdrive (U) [!]"},
+{0x7F43E701, 0x536328D1,
+"Top Gear Rally (E) [!]"},
+{0x0E596247, 0x753D4B8B,
+"Top Gear Rally (J) [!]"},
+{0x62269B3D, 0xFE11B1E8,
+"Top Gear Rally (U) [!]"},
+{0xBEBAB677, 0x51B0B5E4,
+"Top Gear Rally 2 (E) [!]"},
+{0xF82DD377, 0x8C3FB347,
+"TG Rally 2 (UK Version)"},
+{0xCFEF2CD6, 0xC9E973E6,
+"Top Gear Rally 2 (J) [!]"},
+{0xBE5973E0, 0x89B0EDB8,
+"Top Gear Rally 2 (U) [!]"},
+{0xEF703CA4, 0x4D4A9AC9,
+"Toukon Road - Brave Spirits (J) [!]"},
+{0x551C7F43, 0x9149831C,
+"Toukon Road 2 - The Next Generation (J) [!]"},
+{0xCCEB3858, 0x26952D97,
+"Toy Story 2 (E) [!]"},
+{0xCB93DB97, 0x7F5C63D5,
+"Toy Story 2 (F) [!]"},
+{0x782A9075, 0xE552631D,
+"Toy Story 2 (G) [!]"},
+{0xA150743E, 0xCF2522CD,
+"Toy Story 2 (U) [!]"},
+{0xFE4B6B43, 0x081D29A7,
+"Triple Play 2000 (U) [!]"},
+{0x2F7009DD, 0xFC3BAC53,
+"Turok - Dinosaur Hunter (E) (V1.0) [!]"},
+{0x665F09DD, 0xFC3BAC53,
+"Turok - Dinosaur Hunter (E) (V1.0) [a1]"},
+{0x2F700DCD, 0x176CC5C9,
+"Turok - Dinosaur Hunter (E) (V1.1)/(V1.2) [!]"},
+{0x665FD963, 0xB5CC6612,
+"Turok - Dinosaur Hunter (G) [!]"},
+{0x916AE6B8, 0x8817AB22,
+"Turok - Dinosaur Hunter (J) [!]"},
+{0x2F70F10D, 0x5C4187FF,
+"Turok - Dinosaur Hunter (U) (V1.0) [!]"},
+{0x2F700DCD, 0x176CC5C9,
+"Turok - Dinosaur Hunter (U) (V1.1)/(v1.2) [!]"},
+{0x66E4FA0F, 0xDE88C7D0,
+"Turok - Legenden des Verlorenen Landes (Rage Wars) (G) [!]"},
+{0x1EA26214, 0xE790900F,
+"Turok - Rage Wars (E) [!]"},
+{0x2E0E7749, 0xB8B49D59,
+"Turok 2 - Seeds of Evil (FIS)"},
+{0xADB9498B, 0xDAF28F55,
+"Turok - Rage Wars (U) [!]"},
+{0xE8C95AFC, 0x35D121DA,
+"Turok 2 - Seeds of Evil - Kiosk (E) [!]"},
+{0xE8C95AFC, 0x35D121DA,
+"Turok 2 - Seeds of Evil - Kiosk (U) [!]"},
+{0xE0B92B94, 0x80E87CBD,
+"Turok 2 - Seeds of Evil (E) [!]"},
+{0xFE05840B, 0x9393320C,
+"Turok 2 - Seeds of Evil (G) [!]"},
+{0x2E0E7749, 0xB8B49D59,
+"Turok 2 - Seeds of Evil (FIS)"},
+{0x49088A11, 0x6494957E,
+"Turok 2 - Seeds of Evil (U) [!]"},
+{0x6A162FF2, 0x2093704C,
+"Turok 3 - Shadow of Oblivion (E) [!]"},
+{0x89A579F1, 0x667E97EF,
+"Turok 3 - Shadow of Oblivion (U) [!]"},
+{0xE688A5B8, 0xB14B3F18,
+"Twisted Edge Extreme Snowboarding (E) [!]"},
+{0xBBC99D32, 0x117DAA80,
+"Twisted Edge Extreme Snowboarding (U) [!]"},
+{0xDD10BC7E, 0xF900B351,
+"Vigilante 8 - 2nd Offence (E) [!]"},
+{0xF5C5866D, 0x052713D9,
+"Vigilante 8 - 2nd Offense (U) [!]"},
+{0x151F79F4, 0x8EEDC8E5,
+"Vigilante 8 (E) [!]"},
+{0xE2BC82A2, 0x591CD694,
+"Vigilante 8 (F) [!]"},
+{0x6EDA5178, 0xD396FEC1,
+"Vigilante 8 (G) [!]"},
+{0xEA71056A, 0xE4214847,
+"Vigilante 8 (U) [!]"},
+{0x60006C98, 0x2605A381,
+"Violence Killer - Turok New Generation (J) [!]"},
+{0x2FDAA221, 0xA588A7CE,
+"Virtual Chess 64 (E) [!]"},
+{0x82B3248B, 0xE73E244D,
+"Virtual Chess 64 (U) [!]"},
+{0x98F9F2D0, 0x03D9F09C,
+"Virtual Pool 64 (E) [!]"},
+{0x4E4A7643, 0xA37439D7,
+"Virtual Pool 64 (U) [!]"},
+{0x045C08C4, 0x4AFD798B,
+"Virtual Pro Wrestling (J) [!]"},
+{0xCD094235, 0x88074B62,
+"Virtual Pro Wrestling 2 (J) [!]"},
+{0x636E6B19, 0xE57DDC5F,
+"V-Rally Edition 99 (E) [!]"},
+{0x4D0224A5, 0x1BEB5794,
+"V-Rally Edition 99 (J) [!]"},
+{0x3C059038, 0xC8BF2182,
+"V-Rally Edition 99 (U) [!]"},
+{0x93053075, 0x261E0F43,
+"Waialae Country Club-True Golf Classics (E) (V1.0) [!]"},
+{0x0C5057AD, 0x046E126E,
+"Waialae Country Club-True Golf Classics (E) (V1.1) [!]"},
+{0x8066D58A, 0xC3DECAC1,
+"Waialae Country Club-True Golf Classics (U) [!]"},
+{0xD715CC70, 0x271CF5D6,
+"War Gods (E) [!]"},
+{0xF7FE28F6, 0xC3F2ACC3,
+"War Gods (U) [!]"},
+{0x650EFA96, 0x30DDF9A7,
+"Wave Race 64 (E) [!]"},
+{0x5C9191D6, 0xB30AC306,
+"Wave Race 64 (J) [!]"},
+{0x44995484, 0x20A5FC5E,
+"Wave Race 64 (J) (V1.1) [!]"},
+{0x7DE11F53, 0x74872F9D,
+"Wave Race 64 (U) (V1.0) [!]"},
+{0x492F4B61, 0x04E5146A,
+"Wave Race 64 (U) (V1.1) [!]"},
+{0x535DF3E2, 0x609789F1,
+"Wave Race 64 Shindou Edition (J) (V1.2) [!]"},
+{0x2209094B, 0x2C9559AF,
+"Wayne Gretzky's 3D Hockey (E) [!]"},
+{0xF1301043, 0xFD80541A,
+"Wayne Gretzky's 3D Hockey (J) [!]"},
+{0x6B45223F, 0xF00E5C56,
+"Wayne Gretzky's 3D Hockey (U) [!]"},
+{0xDC3BAA59, 0x0ABB456A,
+"Wayne Gretzky's 3D Hockey (U) (V1.1)"},
+{0x661B45F3, 0x9ED6266D,
+"Wayne Gretzky's 3D Hockey '98 (E) [!]"},
+{0x5A9D3859, 0x97AAE710,
+"Wayne Gretzky's 3D Hockey '98 (U) [!]"},
+{0x396F5ADD, 0x6693ECA7,
+"WCW Backstage Assault (U) [!]"},
+{0xAA7B0658, 0x9C96937B,
+"WCW Mayhem (E) [!]"},
+{0x33BE8CD6, 0xEC186912,
+"WCW Mayhem (U) [!]"},
+{0xD4C45A1A, 0xF425B25E,
+"WCW Nitro (U) [!]"},
+{0x8BDBAF68, 0x345B4B36,
+"WCW vs. nWo - World Tour (E) [!]"},
+{0x2C3E19BD, 0x5113EE5E,
+"WCW vs. nWo - World Tour (U) (V1.0) [!]"},
+{0x71BE60B9, 0x1DDBFB3C,
+"WCW vs. nWo - World Tour (U) (V1.1) [!]"},
+{0x68E8A875, 0x0CE7A486,
+"WCW-nWo Revenge (E) [!]"},
+{0xDEE596AB, 0xAF3B7AE7,
+"WCW-nWo Revenge (U) [!]"},
+{0xCEA8B54F, 0x7F21D503,
+"Wetrix (E) [!]"},
+{0xDCB6EAFA, 0xC6BBCFA3,
+"Wetrix (J) [!]"},
+{0xCEA8B54F, 0x7F21D503,
+"Wetrix (U) [!]"},
+{0xE896092B, 0xDC244D4E,
+"Wheel of Fortune (U) [!]"},
+{0x0CEBC4C7, 0x0C9CE932,
+"Wild Choppers (J) [!]"},
+{0xD5898CAF, 0x6007B65B,
+"WinBack - Covert Operations (E) [!]"},
+{0x1FA056E0, 0xA4B9946A,
+"WinBack - Covert Operations (J) [!]"},
+{0xED98957E, 0x8242DCAC,
+"WinBack - Covert Operations (U) [!]"},
+{0x54310E7D, 0x6B5430D8,
+"Wipeout 64 (E) [!]"},
+{0x132D2732, 0xC70E9118,
+"Wipeout 64 (U) [!]"},
+{0xE43C9765, 0x05B1C1BE,
+"Wonder Project J2 (J) [!]"},
+{0xF9FC3090, 0xFF014EC2,
+"World Cup 98 (E) [!]"},
+{0xBD636D6A, 0x5D1F54BA,
+"World Cup 98 (U) [!]"},
+{0xAC062778, 0xDFADFCB8,
+"World Driver Championship (E) [!]"},
+{0x308DFEC8, 0xCE2EB5F6,
+"World Driver Championship (U) [!]"},
+{0x3B941695, 0xF90A5EEB,
+"World is Not Enough, The (E) [!]"},
+{0x033F4C13, 0x319EE7A7,
+"World is Not Enough, The (U) [!]"},
+{0x2D21C57B, 0x8FE4C58C,
+"Worms - Armageddon (E) [!]"},
+{0x13E959A0, 0x0E93CAB0,
+"Worms - Armageddon (U) [!]"},
+{0x33A275A4, 0xB8504459,
+"WWF - War Zone (E) [!]"},
+{0xCD5BEC0F, 0x86FD1008,
+"WWF - War Zone (U) [!]"},
+{0x5BF45B7B, 0x596BEEE8,
+"WWF Attitude (E) [!]"},
+{0x8F3151C8, 0x4F3AF545,
+"WWF Attitude (G) [!]"},
+{0xD2BE2F14, 0x38453788,
+"WWF Attitude (U) [!]"},
+{0x6D8DF08E, 0xD008C3CF,
+"WWF No Mercy (E) (V1.0) [!]"},
+{0x8CDB94C2, 0xCB46C6F0,
+"WWF No Mercy (E) (V1.1) [!]"},
+{0x4E4B0640, 0x1B49BCFB,
+"WWF No Mercy (U) [!]"},
+{0xC71353BE, 0xAA09A6EE,
+"WWF WrestleMania 2000 (E) [!]"},
+{0x12737DA5, 0x23969159,
+"WWF Wrestlemania 2000 (J) [!]"},
+{0x90A59003, 0x31089864,
+"WWF WrestleMania 2000 (U) [!]"},
+{0x0A1667C7, 0x293346A6,
+"Xena Warrior Princess - Talisman of Fate (E) [!]"},
+{0x0553AE9D, 0xEAD8E0C1,
+"Xena Warrior Princess - Talisman of Fate (U) [!]"},
+{0x9F8B96C3, 0xA01194DC,
+"Yakouchuu II - Satsujun Kouru (J) [!]"},
+{0xD3F97D49, 0x6924135B,
+"Yoshi's Story (E) [!]"},
+{0x2DCFCA60, 0x8354B147,
+"Yoshi's Story (J) [!]"},
+{0x2337D8E8, 0x6B8E7CEC,
+"Yoshi's Story (U) [!]"},
+{0x77DA3B8D, 0x162B0D7C,
+" Yousuke Ide's Mahjong School (J) [!]"},
+{0x9FE6162D, 0xE97E4037,
+"Yuke Yuke!! Trouble Makers (J) [!]"},
+{0xEC7011B7, 0x7616D72B,
+"Zelda no Densetsu - Toki no Ocarina (J) (V1.0)"},
+{0xD43DA81F, 0x021E1E19,
+"Zelda no Densetsu - Toki no Ocarina (J) (V1.1)"},
+{0x693BA2AE, 0xB7F14E9F,
+"Zelda no Densetsu - Toki no Ocarina (J) (V1.2)"},
+{0xF7F52DB8, 0x2195E636,
+"Zelda no Densetsu - Toki no Ocarina - Zelda Collection Version (J) (GC Version)"},
+{0xF43B45BA, 0x2F0E9B6F,
+"Zelda no Densetsu - Toki no Ocarina GC Ura (J) (GC Version)"},
+{0xF611F4BA, 0xC584135C,
+"Zelda no Densetsu - Toki no Ocarina GC (J) (GC Version)"},
+{0xEC417312, 0xEB31DE5F,
+"Zelda no Densetsu - Mujura no Kamen (J) (V1.0)"},
+{0x69AE0438, 0x2C63F3F3,
+"Zelda no Densetsu - Mujura no Kamen (J) (V1.1)"},
+{0x8473D0C1, 0x23120666,
+"Zelda no Densetsu - Mujura no Kamen - Zelda Collection Version (J) (GC Version)"},
+{0x1C010CCD, 0x22D3B7FA,
+"Zool - Majou Tsukai Densetsu (J) [!]"},
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/src/n64/n64_settings.c b/src/n64/n64_settings.c
index 050ae90c..77ad5e20 100644
--- a/src/n64/n64_settings.c
+++ b/src/n64/n64_settings.c
@@ -1,10 +1,7 @@
// Copyright 2020, Ryan Wendland, usb64
// SPDX-License-Identifier: MIT
-#include
-#include "n64_settings.h"
-#include "n64_wrapper.h"
-#include "printf.h"
+#include "n64_controller.h"
n64_settings *_settings = NULL;
diff --git a/src/n64/n64_settings.h b/src/n64/n64_settings.h
index 24c12076..63d67564 100644
--- a/src/n64/n64_settings.h
+++ b/src/n64/n64_settings.h
@@ -8,7 +8,7 @@
extern "C" {
#endif
-#include "usb64_conf.h"
+#include "common.h"
typedef struct
{
diff --git a/src/n64/n64_transferpak_gbcarts.c b/src/n64/n64_transferpak_gbcarts.c
index 0e80a0db..89cf08e2 100644
--- a/src/n64/n64_transferpak_gbcarts.c
+++ b/src/n64/n64_transferpak_gbcarts.c
@@ -7,14 +7,7 @@
* Tranferpak emulation is my own RE.
*/
-#include
-#include "printf.h"
-#include "n64_mempak.h"
-#include "n64_virtualpak.h"
-#include "n64_settings.h"
-#include "n64_transferpak_gbcarts.h"
#include "n64_controller.h"
-#include "n64_wrapper.h"
static uint32_t _gb_get_rom_size(uint8_t rom_type)
{
@@ -321,8 +314,8 @@ void gb_init_cart(gameboycart *cart, uint8_t *gb_header, char *filename)
memcpy(cart->filename, filename, sizeof(cart->filename));
debug_print_tpak("[TPAK] gb_init_cart: GB Name: %.15s\n", cart->title);
- debug_print_tpak("[TPAK] gb_init_cart: ROM Bytes: %lu\n", cart->romsize);
- debug_print_tpak("[TPAK] gb_init_cart: SRAM Bytes: %lu\n", cart->ramsize);
+ debug_print_tpak("[TPAK] gb_init_cart: ROM Bytes: %u\n", cart->romsize);
+ debug_print_tpak("[TPAK] gb_init_cart: SRAM Bytes: %u\n", cart->ramsize);
debug_print_tpak("[TPAK] gb_init_cart: MBC Type: 0x%02x\n", cart->mbc);
}
diff --git a/src/n64/n64_virtualpak.c b/src/n64/n64_virtualpak.c
index 063d0ff5..d1403bed 100644
--- a/src/n64/n64_virtualpak.c
+++ b/src/n64/n64_virtualpak.c
@@ -1,15 +1,7 @@
// Copyright 2020, Ryan Wendland, usb64
// SPDX-License-Identifier: MIT
-#include
-#include "printf.h"
-#include "usb64_conf.h"
-#include "n64_mempak.h"
-#include "n64_virtualpak.h"
-#include "n64_settings.h"
-#include "n64_transferpak_gbcarts.h"
#include "n64_controller.h"
-#include "n64_wrapper.h"
#define HEADING MENU_LINE1
#define SUBHEADING MENU_LINE2
@@ -38,9 +30,9 @@ uint8_t n64_virtualpak_scratch[0x20] = {
0x81, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
-//First 0x300 bytes of mempak. I took this from a mempak I generated on my n64.
+//First 0x300 bytes of controller pak. I took this from a controller pak I generated on my n64.
//const as the console only needs to read from this area
-const uint8_t n64_virtualpak_header[0x300] = {
+const uint8_t n64_virtualpak_header[0x300] PROGMEM = {
0x81, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x1A, 0x5F, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -90,7 +82,7 @@ const uint8_t n64_virtualpak_header[0x300] = {
0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03};
-//This is the notesTable located at address 0x300 to 0x500 in the mempack address space.
+//This is the notesTable located at address 0x300 to 0x500 in the cpak address space.
//This initialises the title blocks as all blank titles using 1 page each.
//Basically what is displayed on the mempak manager page.
/* 0x4E = N (Media Type Cartridge)
@@ -150,7 +142,7 @@ uint8_t n64_virtualpak_note_table[0x200] = {
static void n64_virtualpak_write_string(char *msg, uint8_t line, uint8_t ext)
{
//Obtained from pulling known save titles and a bit of trial and error
- static const uint8_t MEMPACK_CHARMAP[] =
+ static const uint8_t CPAK_CHARMAP[] =
{
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
@@ -181,9 +173,9 @@ static void n64_virtualpak_write_string(char *msg, uint8_t line, uint8_t ext)
msg[i] = '-'; //replace _ with -
//Find a match in the CHARMAP
- for (uint32_t j = 0; j < sizeof(MEMPACK_CHARMAP); j++)
+ for (uint32_t j = 0; j < sizeof(CPAK_CHARMAP); j++)
{
- if (msg[i] == MEMPACK_CHARMAP[j])
+ if (msg[i] == CPAK_CHARMAP[j])
n64char = j;
}
@@ -203,7 +195,7 @@ static void n64_virtualpak_write_string(char *msg, uint8_t line, uint8_t ext)
}
}
-void n64_virtualpak_init(n64_mempack *vpak)
+void n64_virtualpak_init(n64_controllerpak *vpak)
{
vpak->virtual_is_active = 1;
vpak->virtual_selected_row = MENU_MAIN;
@@ -213,9 +205,9 @@ void n64_virtualpak_init(n64_mempack *vpak)
for (uint32_t i = 0; i < num_roms; i++)
{
if (gbrom_filenames[i] != NULL)
- free(gbrom_filenames[i]);
+ n64hal_free(gbrom_filenames[i]);
if (gbrom_titlenames[i] != NULL)
- free(gbrom_titlenames[i]);
+ n64hal_free(gbrom_titlenames[i]);
gbrom_filenames[i] = NULL;
gbrom_titlenames[i] = NULL;
@@ -233,7 +225,7 @@ void n64_virtualpak_init(n64_mempack *vpak)
gb_init_cart(&gb_cart, gb_header, gbrom_filenames[i]);
//Copy the gb cart title (from the rom header into an array)
- gbrom_titlenames[i] = (char *)malloc(strlen(gb_cart.title) + 1);
+ gbrom_titlenames[i] = (char *)n64hal_malloc(strlen(gb_cart.title) + 1);
strcpy(gbrom_titlenames[i], gb_cart.title);
}
n64_virtualpak_update(vpak);
@@ -260,7 +252,7 @@ void n64_virtualpak_write32(uint16_t address, uint8_t *tx_buff)
memcpy(&n64_virtualpak_scratch[address], tx_buff, 32);
}
-void n64_virtualpak_update(n64_mempack *vpak)
+void n64_virtualpak_update(n64_controllerpak *vpak)
{
n64_settings *settings = n64_settings_get();
if (settings == NULL)
@@ -292,7 +284,7 @@ void n64_virtualpak_update(n64_mempack *vpak)
//Print generic headers and footers
n64_virtualpak_write_string("USB64 - RYZEE119", HEADING, MENU_NAME_FIELD);
- sprintf(buff, "CONTROLLER %u", controller_page + 1);
+ usb64_sprintf(buff, "CONTROLLER %u", controller_page + 1);
n64_virtualpak_write_string(buff, SUBHEADING, MENU_NAME_FIELD);
n64_virtualpak_write_string("________________", SUBHEADING + 1, MENU_NAME_FIELD);
n64_virtualpak_write_string("CHANGE CONT", CHANGE_CONTROLLER, MENU_NAME_FIELD);
@@ -355,7 +347,7 @@ void n64_virtualpak_update(n64_mempack *vpak)
if (current_menu == MENU_CONTROLLER_SETTINGS)
{
- sprintf(buff, "CONTROLLER %u", controller_page + 1);
+ usb64_sprintf(buff, "CONTROLLER %u", controller_page + 1);
n64_virtualpak_write_string(buff, SUBHEADING + 0, MENU_NAME_FIELD);
n64_virtualpak_write_string("________________", SUBHEADING + 1, MENU_NAME_FIELD);
n64_virtualpak_write_string("CONT SETTINGS", SUBHEADING + 2, MENU_NAME_FIELD);
@@ -398,16 +390,16 @@ void n64_virtualpak_update(n64_mempack *vpak)
}
//Print the current values of each setting
- sprintf(buff, "%u\0", settings->sensitivity[controller_page]);
+ usb64_sprintf(buff, "%u", settings->sensitivity[controller_page]);
n64_virtualpak_write_string(buff, SUBHEADING + 4, MENU_EXT_FIELD);
- sprintf(buff, "%u\0", settings->deadzone[controller_page]);
+ usb64_sprintf(buff, "%u", settings->deadzone[controller_page]);
n64_virtualpak_write_string(buff, SUBHEADING + 7, MENU_EXT_FIELD);
- sprintf(buff, "%u\0", settings->snap_axis[controller_page]);
+ usb64_sprintf(buff, "%u", settings->snap_axis[controller_page]);
n64_virtualpak_write_string(buff, SUBHEADING + 10, MENU_EXT_FIELD);
- sprintf(buff, "%u\0", settings->octa_correct[controller_page]);
+ usb64_sprintf(buff, "%u", settings->octa_correct[controller_page]);
n64_virtualpak_write_string(buff, SUBHEADING + 11, MENU_EXT_FIELD);
vpak->virtual_selected_row = -1;
@@ -450,12 +442,12 @@ void n64_virtualpak_update(n64_mempack *vpak)
void n64_virtualpak_write_info_1(char *msg)
{
- strncpy(info_text_0, msg, sizeof(info_text_0));
+ strncpy(info_text_0, msg, sizeof(info_text_0) - 1);
}
void n64_virtualpak_write_info_2(char *msg)
{
- strncpy(info_text_1, msg, sizeof(info_text_1));
+ strncpy(info_text_1, msg, sizeof(info_text_1) - 1);
}
uint8_t n64_virtualpak_get_controller_page()
diff --git a/src/n64/n64_virtualpak.h b/src/n64/n64_virtualpak.h
index 574cdcaf..30273b49 100644
--- a/src/n64/n64_virtualpak.h
+++ b/src/n64/n64_virtualpak.h
@@ -28,8 +28,8 @@ extern "C" {
#define MENU_NAME_FIELD 0
#define MENU_EXT_FIELD 1
-void n64_virtualpak_init(n64_mempack *vpak);
-void n64_virtualpak_update(n64_mempack *vpak);
+void n64_virtualpak_init(n64_controllerpak *vpak);
+void n64_virtualpak_update(n64_controllerpak *vpak);
void n64_virtualpak_read32(uint16_t address, uint8_t *rx_buff);
void n64_virtualpak_write32(uint16_t address, uint8_t *tx_buff);
void n64_virtualpak_write_info_1(char* msg);
diff --git a/src/n64_wrapper.h b/src/n64_wrapper.h
deleted file mode 100644
index 9f1afd90..00000000
--- a/src/n64_wrapper.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2020, Ryan Wendland, usb64
-// SPDX-License-Identifier: MIT
-
-#ifndef N64_N64_WRAPPER_H_
-#define N64_N64_WRAPPER_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include
-#include "n64_controller.h"
-
-#define N64_OUTPUT 1
-#define N64_INPUT 2
-
-//RTC wrapper prototypes (For gameboy roms with RTC, i.e Pokemon games)
-void n64hal_rtc_read(uint8_t *day_high, uint8_t *day_low, uint8_t *h, uint8_t *m, uint8_t *s);
-void n64hal_rtc_write(uint8_t *day_high, uint8_t *day_low, uint8_t *h, uint8_t *m, uint8_t *s);
-
-//Timer wrappers
-uint32_t n64hal_hs_tick_get_speed();
-void n64hal_hs_tick_init();
-uint32_t n64hal_hs_tick_get();
-
-//RAM access wrappers
-void n64hal_read_extram(void *rx_buff, void *src, uint32_t offset, uint32_t len);
-void n64hal_write_extram(void *tx_buff, void *dst, uint32_t offset, uint32_t len);
-
-//GPIO wrappers
-void n64hal_output_set(uint8_t pin, uint8_t level);
-void n64hal_input_swap(n64_input_dev_t *controller, uint8_t val);
-uint8_t n64hal_input_read(n64_input_dev_t *controller);
-
-//FileIO wrappers
-uint32_t n64hal_list_gb_roms(char **list, uint32_t max);
-void n64hal_read_storage(char *name, uint32_t file_offset, uint8_t *data, uint32_t len);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* N64_N64_WRAPPER_H_ */
diff --git a/src/port_stm32f7/common/bsp_common/fileio_stm32.cpp b/src/port_stm32f7/common/bsp_common/fileio_stm32.cpp
new file mode 100644
index 00000000..a3e43a7b
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_common/fileio_stm32.cpp
@@ -0,0 +1,138 @@
+// Copyright 2020, Ryan Wendland, usb64
+// SPDX-License-Identifier: MIT
+
+#include "common.h"
+#include "ff.h"
+#include "ff_gen_drv.h"
+#include "sd_diskio.h"
+
+static FATFS fs;
+static char SDPath[4] = {0};
+extern const Diskio_drvTypeDef SD_Driver;
+
+bool fileio_dev_init()
+{
+ if (FATFS_LinkDriver(&SD_Driver, SDPath) != 0)
+ {
+ return false;
+ }
+
+ int retries = 3;
+
+ while (retries)
+ {
+ if (f_mount(&fs, (TCHAR const *)SDPath, 1) != FR_OK)
+ {
+ retries--;
+ if (retries == 0)
+ return false;
+ HAL_Delay(100);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ return f_chdir((TCHAR const *)SDPath) == FR_OK;
+}
+
+int fileio_dev_open_dir(const char *dir)
+{
+ DIR *dp = (DIR *)malloc(sizeof(DIR));
+ if (dp == NULL)
+ {
+ return 0;
+ }
+ n64hal_disable_interrupts();
+ FRESULT res = f_opendir(dp, (const TCHAR *)dir);
+ n64hal_enable_interrupts();
+
+ if (res != FR_OK)
+ {
+ free(dp);
+ return 0;
+ }
+
+ return (uint32_t)dp;
+}
+
+const char *fileio_dev_get_next_filename(int handle)
+{
+ static FILINFO fno;
+ FRESULT res;
+ DIR *dp = (DIR *)handle;
+ n64hal_disable_interrupts();
+ res = f_readdir(dp, &fno);
+ n64hal_enable_interrupts();
+ if (dp && res == FR_OK && fno.fname[0] != 0)
+ {
+ return fno.fname;
+ }
+ return NULL;
+}
+
+void fileio_dev_close_dir(int handle)
+{
+ if (handle == 0)
+ {
+ return;
+ }
+
+ DIR *dp = (DIR *)handle;
+ f_closedir(dp);
+ free(dp);
+}
+
+int fileio_dev_read(char *filename, uint32_t file_offset, uint8_t *data, uint32_t len)
+{
+ FIL fil;
+ FRESULT res;
+ UINT br;
+ n64hal_disable_interrupts();
+ res = f_open(&fil, filename, FA_READ);
+ if (res != FR_OK)
+ {
+ n64hal_enable_interrupts();
+ return -1;
+ }
+
+ f_lseek(&fil, file_offset);
+ res = f_read(&fil, data, len, &br);
+ if (res != FR_OK || br != len)
+ {
+ f_close(&fil);
+ n64hal_enable_interrupts();
+ return -2;
+ }
+
+ f_close(&fil);
+ n64hal_enable_interrupts();
+ return 0;
+}
+
+int fileio_dev_write(char *filename, uint8_t *data, uint32_t len)
+{
+ FIL fil;
+ FRESULT res;
+ UINT bw;
+ n64hal_disable_interrupts();
+ res = f_open(&fil, filename, FA_WRITE | FA_CREATE_ALWAYS);
+ if (res != FR_OK)
+ {
+ n64hal_enable_interrupts();
+ return -1;
+ }
+
+ res = f_write(&fil, data, len, &bw);
+ if (res != FR_OK || bw != len)
+ {
+ f_close(&fil);
+ n64hal_enable_interrupts();
+ return -2;
+ }
+
+ f_close(&fil);
+ n64hal_enable_interrupts();
+ return 0;
+}
diff --git a/src/port_stm32f7/common/bsp_common/memory_stm32.cpp b/src/port_stm32f7/common/bsp_common/memory_stm32.cpp
new file mode 100644
index 00000000..2d6440dd
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_common/memory_stm32.cpp
@@ -0,0 +1,71 @@
+// Copyright 2020, Ryan Wendland, usb64
+// SPDX-License-Identifier: MIT
+
+#include "common.h"
+#include "tinyalloc.h"
+#include "memory.h"
+
+static uint32_t extram_start = 0;
+static uint32_t extram_end = 0;
+
+bool memory_dev_init()
+{
+ extram_start = SDRAM_DEVICE_ADDR + 0x200000;
+ extram_end = extram_start + SDRAM_DEVICE_SIZE - 0x200000;
+
+ //There's 8MB usable SDRAM on the f750-k board located from 0xC0000000
+ //The first 2MB are reversed for the LCD. extram_start starts just after this
+ //I create a new heap at this location for allocating large files
+ extern SDRAM_HandleTypeDef sdramHandle;
+ if (sdramHandle.State != HAL_SDRAM_STATE_READY)
+ {
+ BSP_SDRAM_Init();
+ }
+
+ uint32_t extram_bytes = extram_end - extram_start;
+ ta_init((void *)(extram_start), //Base of heap
+ (void *)(extram_end), //End of heap
+ extram_bytes / 32768, //Number of memory chunks (32k/per chunk)
+ 16, //Smaller chunks than this won't split
+ 4); //32 word size alignment
+
+ debug_print_memory("[MEMORY] External memory initialised\n");
+ debug_print_memory("[MEMORY] Detected %ukB\n", extram_bytes / 1024);
+ debug_print_memory("[MEMORY] Heap start: %08x\n", (void *)(extram_start));
+ debug_print_memory("[MEMORY] Heap end: %08x\n", (void *)(extram_end));
+ debug_print_memory("[MEMORY] Number of memory chunks: %u\n", extram_bytes / 32768);
+ return true;
+}
+
+void *memory_dev_malloc(uint32_t len)
+{
+ void *pt = ta_alloc(len);
+ if (pt == NULL)
+ {
+ debug_print_error("[MEMORY] ERROR, could not allocate memory\n");
+ }
+ return pt;
+}
+
+void memory_dev_free(void *add)
+{
+ if ((uint32_t)add >= extram_start)
+ {
+ ta_free(add);
+ }
+ else
+ {
+ free(add);
+ }
+}
+
+/*
+ * Function: Detect the amount of external RAM installed. This prints it to the LCD and a number > 0 is required for TPAK
+ * emulation. If you device has loads of internal RAM suitable for TPAK emulation (>2MB or so) which you want to use, set this to a non-zero number.
+ * ----------------------------
+ * Returns: How many MB of external RAM is installed.
+ */
+uint8_t memory_get_ext_ram_size()
+{
+ return (extram_end - extram_start) / 1024 / 1024;
+}
diff --git a/src/port_stm32f7/common/bsp_common/tft_stm32.cpp b/src/port_stm32f7/common/bsp_common/tft_stm32.cpp
new file mode 100644
index 00000000..649138d7
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_common/tft_stm32.cpp
@@ -0,0 +1,78 @@
+// Copyright 2020, Ryan Wendland, usb64
+// SPDX-License-Identifier: MIT
+
+#include "common.h"
+#include "tft.h"
+#include "controller_icon.h"
+#include "usb64_logo.h"
+#include "GuiLite.h"
+
+#define TFT_FRAMEBUFFER_SIZE (TFT_WIDTH * TFT_HEIGHT * TFT_PIXEL_SIZE)
+c_surface *psurface_guilite = NULL;
+c_display *pdisplay_guilite = NULL;
+static uint8_t *_framebuffer = (uint8_t *)(LCD_FB_START_ADDRESS);
+struct EXTERNAL_GFX_OP my_gfx_op;
+float scale = 1;
+
+static void _tft_assert(const char *file, int line)
+{
+ debug_print_error("[TFT] Error: Assert in %s on line %d\n", file, line);
+ while (1)
+ ;
+}
+
+static void _tft_log_out(const char *log)
+{
+ debug_print_status(log);
+}
+
+#if TFT_USE_FRAMEBUFFER == 0
+static void _draw_pixel(int x, int y, unsigned int rgb)
+{
+ BSP_LCD_SetTextColor(rgb);
+ BSP_LCD_FillRect(x * scale, y * scale, scale + 1, scale + 1);
+}
+
+static void _fill_rect(int x0, int y0, int x1, int y1, unsigned int rgb)
+{
+ BSP_LCD_SetTextColor(rgb);
+ BSP_LCD_FillRect(x0 * scale, y0 * scale, (x1 - x0) * scale, (y1 - y0) * scale);
+}
+#endif
+
+void tft_dev_draw(bool force)
+{
+ //Dont need to do anything. This TFT just updates from the SDRAM buffer automatically.
+}
+
+extern "C" void BSP_LCD_ClockConfig(LTDC_HandleTypeDef *hltdc, void *Params)
+{
+ //Overrise the internal clock config as it messes with other clock divs and multipliers.
+ //Dont do anything. All clocks are setup properly at boot
+}
+
+void tft_dev_init()
+{
+ //Always draw into a 320x240 Framebuffer on stm32
+ static c_surface_no_fb surface(320, 240, 2, &my_gfx_op, Z_ORDER_LEVEL_0);
+ static c_display display(NULL, 320, 240, &surface);
+ scale = MIN(TFT_HEIGHT / 240.0f, TFT_WIDTH / 320.0f);
+ my_gfx_op.draw_pixel = _draw_pixel;
+ my_gfx_op.fill_rect = _fill_rect;
+ psurface_guilite = &surface;
+ pdisplay_guilite = &display;
+ register_debug_function(_tft_assert, _tft_log_out);
+#if (ENABLE_TFT_DISPLAY >= 1)
+ BSP_LCD_Init();
+ BSP_LCD_LayerDefaultInit(0, (uint32_t)_framebuffer);
+ BSP_LCD_SelectLayer(0);
+ BSP_LCD_SetBackColor(TFT_BG_COLOR);
+ BSP_LCD_Clear(TFT_BG_COLOR);
+ BSP_LCD_DisplayOn();
+#endif
+}
+
+bool tft_dev_is_busy()
+{
+ return 0;
+}
diff --git a/src/port_stm32f7/common/bsp_drivers/Adafruit_Shield/Release_Notes.html b/src/port_stm32f7/common/bsp_drivers/Adafruit_Shield/Release_Notes.html
new file mode 100644
index 00000000..1b181fcd
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Adafruit_Shield/Release_Notes.html
@@ -0,0 +1,599 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Release Notes for Adafruit_Shield Drivers
+
+
+
+
+
+
+
+
+
+
+
The BSP (Board Specific
+Package) drivers are parts of the STM32Cube package based on the HAL
+drivers and provide a set of high level APIs relative to the hardware
+components and features in the evaluation boards, discovery kits and nucleo
+boards coming with the STM32Cube package for a given STM32 serie.
+
The BSP drivers allow a quick access to the boards’
+services using high level APIs and without any specific configuration as the
+link with the HAL and the external components is done in intrinsic within the drivers.
+
+
From project settings points of view, user has only
+to add the necessary driver’s files in the workspace and call the needed
+functions from examples. However some low level
+configuration functions are weak and can be overridden by the applications if user
+wants to change some BSP drivers default behavior.
Add workaround for the issue seen on some STM32 Nucleo boards; reading the SD card status will return an error
+
A fix will be implemented in next release
+
+
+
stm32_adafruit_lcd.h: change "\" by "/" in the include path to fix compilation issue under Linux
+
+
Miscellaneous comments update
+
+
+
V1.1.0 / 22-July-2014
+
Main
+Changes
+
+
+
+
+
Add new user API BSP_LCD_DrawBitmap() to draw a bitmap picture loaded in the STM32 MCU internal memory
+
Add new static API SetDisplayWindow(), needed by BSP_LCD_DrawBitmap()
+
+
Update static API DrawChar()
+
Note: This driver version needs ST7735 component driver V1.1.0 and later.
+
+
+
+
V1.0.0 / 22-April-2014
Main
+Changes
+
+
First official release.
License
+
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Adafruit_Shield/stm32_adafruit_lcd.c b/src/port_stm32f7/common/bsp_drivers/Adafruit_Shield/stm32_adafruit_lcd.c
new file mode 100644
index 00000000..cc00060f
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Adafruit_Shield/stm32_adafruit_lcd.c
@@ -0,0 +1,1067 @@
+/**
+ ******************************************************************************
+ * @file stm32_adafruit_lcd.c
+ * @author MCD Application Team
+ * @brief This file includes the driver for Liquid Crystal Display (LCD) module
+ * mounted on the Adafruit 1.8" TFT LCD shield (reference ID 802),
+ * that is used with the STM32 Nucleo board through SPI interface.
+ ******************************************************************************
+ * @attention
+ *
+ *
First official release with Accelerometer, Audio, Camera, Gyroscope, IO, LCD and Touch Screen drivers function prototypes
License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/Common/accelero.h b/src/port_stm32f7/common/bsp_drivers/Components/Common/accelero.h
new file mode 100644
index 00000000..0de82329
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/Common/accelero.h
@@ -0,0 +1,143 @@
+/**
+ ******************************************************************************
+ * @file accelero.h
+ * @author MCD Application Team
+ * @version V4.0.1
+ * @date 21-July-2015
+ * @brief This header file contains the functions prototypes for the Accelerometer driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __ACCELERO_H
+#define __ACCELERO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup ACCELERO
+ * @{
+ */
+
+/** @defgroup ACCELERO_Exported_Types
+ * @{
+ */
+
+/** @defgroup ACCELERO_Driver_structure Accelerometer Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(uint16_t);
+ void (*DeInit)(void);
+ uint8_t (*ReadID)(void);
+ void (*Reset)(void);
+ void (*LowPower)(void);
+ void (*ConfigIT)(void);
+ void (*EnableIT)(uint8_t);
+ void (*DisableIT)(uint8_t);
+ uint8_t (*ITStatus)(uint16_t);
+ void (*ClearIT)(void);
+ void (*FilterConfig)(uint8_t);
+ void (*FilterCmd)(uint8_t);
+ void (*GetXYZ)(int16_t *);
+}ACCELERO_DrvTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup ACCELERO_Configuration_structure Accelerometer Configuration structure
+ * @{
+ */
+
+/* ACCELERO struct */
+typedef struct
+{
+ uint8_t Power_Mode; /* Power-down/Normal Mode */
+ uint8_t AccOutput_DataRate; /* OUT data rate */
+ uint8_t Axes_Enable; /* Axes enable */
+ uint8_t High_Resolution; /* High Resolution enabling/disabling */
+ uint8_t BlockData_Update; /* Block Data Update */
+ uint8_t Endianness; /* Endian Data selection */
+ uint8_t AccFull_Scale; /* Full Scale selection */
+ uint8_t Communication_Mode;
+}ACCELERO_InitTypeDef;
+
+/* ACCELERO High Pass Filter struct */
+typedef struct
+{
+ uint8_t HighPassFilter_Mode_Selection; /* Internal filter mode */
+ uint8_t HighPassFilter_CutOff_Frequency; /* High pass filter cut-off frequency */
+ uint8_t HighPassFilter_AOI1; /* HPF_enabling/disabling for AOI function on interrupt 1 */
+ uint8_t HighPassFilter_AOI2; /* HPF_enabling/disabling for AOI function on interrupt 2 */
+ uint8_t HighPassFilter_Data_Sel;
+ uint8_t HighPassFilter_Stat;
+}ACCELERO_FilterConfigTypeDef;
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ACCELERO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/Common/audio.h b/src/port_stm32f7/common/bsp_drivers/Components/Common/audio.h
new file mode 100644
index 00000000..8b93673f
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/Common/audio.h
@@ -0,0 +1,122 @@
+/**
+ ******************************************************************************
+ * @file audio.h
+ * @author MCD Application Team
+ * @version V4.0.1
+ * @date 21-July-2015
+ * @brief This header file contains the common defines and functions prototypes
+ * for the Audio driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AUDIO_H
+#define __AUDIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup AUDIO
+ * @{
+ */
+
+/** @defgroup AUDIO_Exported_Constants
+ * @{
+ */
+
+/* Codec audio Standards */
+#define CODEC_STANDARD 0x04
+#define I2S_STANDARD I2S_STANDARD_PHILIPS
+
+/**
+ * @}
+ */
+
+/** @defgroup AUDIO_Exported_Types
+ * @{
+ */
+
+/** @defgroup AUDIO_Driver_structure Audio Driver structure
+ * @{
+ */
+typedef struct
+{
+ uint32_t (*Init)(uint16_t, uint16_t, uint8_t, uint32_t);
+ void (*DeInit)(void);
+ uint32_t (*ReadID)(uint16_t);
+ uint32_t (*Play)(uint16_t, uint16_t*, uint16_t);
+ uint32_t (*Pause)(uint16_t);
+ uint32_t (*Resume)(uint16_t);
+ uint32_t (*Stop)(uint16_t, uint32_t);
+ uint32_t (*SetFrequency)(uint16_t, uint32_t);
+ uint32_t (*SetVolume)(uint16_t, uint8_t);
+ uint32_t (*SetMute)(uint16_t, uint32_t);
+ uint32_t (*SetOutputMode)(uint16_t, uint8_t);
+ uint32_t (*Reset)(uint16_t);
+}AUDIO_DrvTypeDef;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AUDIO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/Common/camera.h b/src/port_stm32f7/common/bsp_drivers/Components/Common/camera.h
new file mode 100644
index 00000000..c64f32fd
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/Common/camera.h
@@ -0,0 +1,141 @@
+/**
+ ******************************************************************************
+ * @file camera.h
+ * @author MCD Application Team
+ * @version V4.0.1
+ * @date 21-July-2015
+ * @brief This header file contains the common defines and functions prototypes
+ * for the camera driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __CAMERA_H
+#define __CAMERA_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup CAMERA
+ * @{
+ */
+
+
+/** @defgroup CAMERA_Exported_Types
+ * @{
+ */
+
+/** @defgroup CAMERA_Driver_structure Camera Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(uint16_t, uint32_t);
+ uint16_t (*ReadID)(uint16_t);
+ void (*Config)(uint16_t, uint32_t, uint32_t, uint32_t);
+}CAMERA_DrvTypeDef;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup CAMERA_Exported_Constants
+ * @{
+ */
+#define CAMERA_R160x120 0x00 /* QQVGA Resolution */
+#define CAMERA_R320x240 0x01 /* QVGA Resolution */
+#define CAMERA_R480x272 0x02 /* 480x272 Resolution */
+#define CAMERA_R640x480 0x03 /* VGA Resolution */
+
+#define CAMERA_CONTRAST_BRIGHTNESS 0x00 /* Camera contrast brightness features */
+#define CAMERA_BLACK_WHITE 0x01 /* Camera black white feature */
+#define CAMERA_COLOR_EFFECT 0x03 /* Camera color effect feature */
+
+#define CAMERA_BRIGHTNESS_LEVEL0 0x00 /* Brightness level -2 */
+#define CAMERA_BRIGHTNESS_LEVEL1 0x01 /* Brightness level -1 */
+#define CAMERA_BRIGHTNESS_LEVEL2 0x02 /* Brightness level 0 */
+#define CAMERA_BRIGHTNESS_LEVEL3 0x03 /* Brightness level +1 */
+#define CAMERA_BRIGHTNESS_LEVEL4 0x04 /* Brightness level +2 */
+
+#define CAMERA_CONTRAST_LEVEL0 0x05 /* Contrast level -2 */
+#define CAMERA_CONTRAST_LEVEL1 0x06 /* Contrast level -1 */
+#define CAMERA_CONTRAST_LEVEL2 0x07 /* Contrast level 0 */
+#define CAMERA_CONTRAST_LEVEL3 0x08 /* Contrast level +1 */
+#define CAMERA_CONTRAST_LEVEL4 0x09 /* Contrast level +2 */
+
+#define CAMERA_BLACK_WHITE_BW 0x00 /* Black and white effect */
+#define CAMERA_BLACK_WHITE_NEGATIVE 0x01 /* Negative effect */
+#define CAMERA_BLACK_WHITE_BW_NEGATIVE 0x02 /* BW and Negative effect */
+#define CAMERA_BLACK_WHITE_NORMAL 0x03 /* Normal effect */
+
+#define CAMERA_COLOR_EFFECT_NONE 0x00 /* No effects */
+#define CAMERA_COLOR_EFFECT_BLUE 0x01 /* Blue effect */
+#define CAMERA_COLOR_EFFECT_GREEN 0x02 /* Green effect */
+#define CAMERA_COLOR_EFFECT_RED 0x03 /* Red effect */
+#define CAMERA_COLOR_EFFECT_ANTIQUE 0x04 /* Antique effect */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CAMERA_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/Common/epd.h b/src/port_stm32f7/common/bsp_drivers/Components/Common/epd.h
new file mode 100644
index 00000000..a06be10d
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/Common/epd.h
@@ -0,0 +1,115 @@
+/**
+ ******************************************************************************
+ * @file epd.h
+ * @author MCD Application Team
+ * @version V4.0.1
+ * @date 21-July-2015
+ * @brief This file contains all the functions prototypes for the
+ * EPD (E Paper Display) driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __EPD_H
+#define __EPD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup Common
+ * @{
+ */
+
+/** @addtogroup EPD
+ * @{
+ */
+
+/** @defgroup EPD_Exported_Types
+ * @{
+ */
+
+/** @defgroup EPD_Driver_structure E Paper Display Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(void);
+ void (*WritePixel)(uint8_t);
+
+ /* Optimized operation */
+ void (*SetDisplayWindow)(uint16_t, uint16_t, uint16_t, uint16_t);
+ void (*RefreshDisplay)(void);
+ void (*CloseChargePump)(void);
+
+ uint16_t (*GetEpdPixelWidth)(void);
+ uint16_t (*GetEpdPixelHeight)(void);
+ void (*DrawImage)(uint16_t, uint16_t, uint16_t, uint16_t, uint8_t*);
+}
+EPD_DrvTypeDef;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EPD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/Common/gyro.h b/src/port_stm32f7/common/bsp_drivers/Components/Common/gyro.h
new file mode 100644
index 00000000..462928c9
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/Common/gyro.h
@@ -0,0 +1,145 @@
+/**
+ ******************************************************************************
+ * @file gyro.h
+ * @author MCD Application Team
+ * @version V4.0.1
+ * @date 21-July-2015
+ * @brief This header file contains the functions prototypes for the gyroscope driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __GYRO_H
+#define __GYRO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup GYRO
+ * @{
+ */
+
+/** @defgroup GYRO_Exported_Types
+ * @{
+ */
+
+/** @defgroup GYRO_Driver_structure Gyroscope Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(uint16_t);
+ void (*DeInit)(void);
+ uint8_t (*ReadID)(void);
+ void (*Reset)(void);
+ void (*LowPower)(uint16_t);
+ void (*ConfigIT)(uint16_t);
+ void (*EnableIT)(uint8_t);
+ void (*DisableIT)(uint8_t);
+ uint8_t (*ITStatus)(uint16_t, uint16_t);
+ void (*ClearIT)(uint16_t, uint16_t);
+ void (*FilterConfig)(uint8_t);
+ void (*FilterCmd)(uint8_t);
+ void (*GetXYZ)(float *);
+}GYRO_DrvTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup GYRO_Config_structure Gyroscope Configuration structure
+ * @{
+ */
+
+typedef struct
+{
+ uint8_t Power_Mode; /* Power-down/Sleep/Normal Mode */
+ uint8_t Output_DataRate; /* OUT data rate */
+ uint8_t Axes_Enable; /* Axes enable */
+ uint8_t Band_Width; /* Bandwidth selection */
+ uint8_t BlockData_Update; /* Block Data Update */
+ uint8_t Endianness; /* Endian Data selection */
+ uint8_t Full_Scale; /* Full Scale selection */
+}GYRO_InitTypeDef;
+
+/* GYRO High Pass Filter struct */
+typedef struct
+{
+ uint8_t HighPassFilter_Mode_Selection; /* Internal filter mode */
+ uint8_t HighPassFilter_CutOff_Frequency; /* High pass filter cut-off frequency */
+}GYRO_FilterConfigTypeDef;
+
+/*GYRO Interrupt struct */
+typedef struct
+{
+ uint8_t Latch_Request; /* Latch interrupt request into CLICK_SRC register */
+ uint8_t Interrupt_Axes; /* X, Y, Z Axes Interrupts */
+ uint8_t Interrupt_ActiveEdge; /* Interrupt Active edge */
+}GYRO_InterruptConfigTypeDef;
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __GYRO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/Common/idd.h b/src/port_stm32f7/common/bsp_drivers/Components/Common/idd.h
new file mode 100644
index 00000000..1b8a762e
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/Common/idd.h
@@ -0,0 +1,168 @@
+/**
+ ******************************************************************************
+ * @file idd.h
+ * @author MCD Application Team
+ * @version V4.0.1
+ * @date 21-July-2015
+ * @brief This file contains all the functions prototypes for the IDD driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __IDD_H
+#define __IDD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup IDD
+ * @{
+ */
+
+/** @defgroup IDD_Exported_Types IDD Exported Types
+ * @{
+ */
+
+/** @defgroup IDD_Config_structure IDD Configuration structure
+ * @{
+ */
+typedef struct
+{
+ uint16_t AmpliGain; /*!< Specifies ampli gain value
+ */
+ uint16_t VddMin; /*!< Specifies minimum MCU VDD can reach to protect MCU from reset
+ */
+ uint16_t Shunt0Value; /*!< Specifies value of Shunt 0 if existing
+ */
+ uint16_t Shunt1Value; /*!< Specifies value of Shunt 1 if existing
+ */
+ uint16_t Shunt2Value; /*!< Specifies value of Shunt 2 if existing
+ */
+ uint16_t Shunt3Value; /*!< Specifies value of Shunt 3 if existing
+ */
+ uint16_t Shunt4Value; /*!< Specifies value of Shunt 4 if existing
+ */
+ uint16_t Shunt0StabDelay; /*!< Specifies delay of Shunt 0 stabilization if existing
+ */
+ uint16_t Shunt1StabDelay; /*!< Specifies delay of Shunt 1 stabilization if existing
+ */
+ uint16_t Shunt2StabDelay; /*!< Specifies delay of Shunt 2 stabilization if existing
+ */
+ uint16_t Shunt3StabDelay; /*!< Specifies delay of Shunt 3 stabilization if existing
+ */
+ uint16_t Shunt4StabDelay; /*!< Specifies delay of Shunt 4 stabilization if existing
+ */
+ uint8_t ShuntNbOnBoard; /*!< Specifies number of shunts that are present on board
+ This parameter can be a value of @ref IDD_shunt_number */
+ uint8_t ShuntNbUsed; /*!< Specifies number of shunts used for measurement
+ This parameter can be a value of @ref IDD_shunt_number */
+ uint8_t VrefMeasurement; /*!< Specifies if Vref is automatically measured before each Idd measurement
+ This parameter can be a value of @ref IDD_Vref_Measurement */
+ uint8_t Calibration; /*!< Specifies if calibration is done before each Idd measurement
+ */
+ uint8_t PreDelayUnit; /*!< Specifies Pre delay unit
+ This parameter can be a value of @ref IDD_PreDelay */
+ uint8_t PreDelayValue; /*!< Specifies Pre delay value in selected unit
+ */
+ uint8_t MeasureNb; /*!< Specifies number of Measure to be performed
+ This parameter can be a value between 1 and 256 */
+ uint8_t DeltaDelayUnit; /*!< Specifies Delta delay unit
+ This parameter can be a value of @ref IDD_DeltaDelay */
+ uint8_t DeltaDelayValue; /*!< Specifies Delta delay between 2 measures
+ value can be between 1 and 128 */
+}IDD_ConfigTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup IDD_Driver_structure IDD Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(uint16_t);
+ void (*DeInit)(uint16_t);
+ uint16_t (*ReadID)(uint16_t);
+ void (*Reset)(uint16_t);
+ void (*LowPower)(uint16_t);
+ void (*WakeUp)(uint16_t);
+ void (*Start)(uint16_t);
+ void (*Config)(uint16_t,IDD_ConfigTypeDef);
+ void (*GetValue)(uint16_t, uint32_t *);
+ void (*EnableIT)(uint16_t);
+ void (*ClearIT)(uint16_t);
+ uint8_t (*GetITStatus)(uint16_t);
+ void (*DisableIT)(uint16_t);
+ void (*ErrorEnableIT)(uint16_t);
+ void (*ErrorClearIT)(uint16_t);
+ uint8_t (*ErrorGetITStatus)(uint16_t);
+ void (*ErrorDisableIT)(uint16_t);
+ uint8_t (*ErrorGetSrc)(uint16_t);
+ uint8_t (*ErrorGetCode)(uint16_t);
+}IDD_DrvTypeDef;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __IDD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/Common/io.h b/src/port_stm32f7/common/bsp_drivers/Components/Common/io.h
new file mode 100644
index 00000000..b33c00e6
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/Common/io.h
@@ -0,0 +1,150 @@
+/**
+ ******************************************************************************
+ * @file io.h
+ * @author MCD Application Team
+ * @version V4.0.1
+ * @date 21-July-2015
+ * @brief This file contains all the functions prototypes for the IO driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __IO_H
+#define __IO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup IO
+ * @{
+ */
+
+/** @defgroup IO_Exported_Types
+ * @{
+ */
+
+/**
+ * @brief IO Bit SET and Bit RESET enumeration
+ */
+typedef enum
+{
+ IO_PIN_RESET = 0,
+ IO_PIN_SET
+}IO_PinState;
+
+typedef enum
+{
+ IO_MODE_INPUT = 0, /* input floating */
+ IO_MODE_OUTPUT, /* output Push Pull */
+ IO_MODE_IT_RISING_EDGE, /* float input - irq detect on rising edge */
+ IO_MODE_IT_FALLING_EDGE, /* float input - irq detect on falling edge */
+ IO_MODE_IT_LOW_LEVEL, /* float input - irq detect on low level */
+ IO_MODE_IT_HIGH_LEVEL, /* float input - irq detect on high level */
+ /* following modes only available on MFX*/
+ IO_MODE_ANALOG, /* analog mode */
+ IO_MODE_OFF, /* when pin isn't used*/
+ IO_MODE_INPUT_PU, /* input with internal pull up resistor */
+ IO_MODE_INPUT_PD, /* input with internal pull down resistor */
+ IO_MODE_OUTPUT_OD, /* Open Drain output without internal resistor */
+ IO_MODE_OUTPUT_OD_PU, /* Open Drain output with internal pullup resistor */
+ IO_MODE_OUTPUT_OD_PD, /* Open Drain output with internal pulldown resistor */
+ IO_MODE_OUTPUT_PP, /* PushPull output without internal resistor */
+ IO_MODE_OUTPUT_PP_PU, /* PushPull output with internal pullup resistor */
+ IO_MODE_OUTPUT_PP_PD, /* PushPull output with internal pulldown resistor */
+ IO_MODE_IT_RISING_EDGE_PU, /* push up resistor input - irq on rising edge */
+ IO_MODE_IT_RISING_EDGE_PD, /* push dw resistor input - irq on rising edge */
+ IO_MODE_IT_FALLING_EDGE_PU, /* push up resistor input - irq on falling edge */
+ IO_MODE_IT_FALLING_EDGE_PD, /* push dw resistor input - irq on falling edge */
+ IO_MODE_IT_LOW_LEVEL_PU, /* push up resistor input - irq detect on low level */
+ IO_MODE_IT_LOW_LEVEL_PD, /* push dw resistor input - irq detect on low level */
+ IO_MODE_IT_HIGH_LEVEL_PU, /* push up resistor input - irq detect on high level */
+ IO_MODE_IT_HIGH_LEVEL_PD, /* push dw resistor input - irq detect on high level */
+
+}IO_ModeTypedef;
+
+/** @defgroup IO_Driver_structure IO Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(uint16_t);
+ uint16_t (*ReadID)(uint16_t);
+ void (*Reset)(uint16_t);
+
+ void (*Start)(uint16_t, uint32_t);
+ uint8_t (*Config)(uint16_t, uint32_t, IO_ModeTypedef);
+ void (*WritePin)(uint16_t, uint32_t, uint8_t);
+ uint32_t (*ReadPin)(uint16_t, uint32_t);
+
+ void (*EnableIT)(uint16_t);
+ void (*DisableIT)(uint16_t);
+ uint32_t (*ITStatus)(uint16_t, uint32_t);
+ void (*ClearIT)(uint16_t, uint32_t);
+
+}IO_DrvTypeDef;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __IO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/Common/lcd.h b/src/port_stm32f7/common/bsp_drivers/Components/Common/lcd.h
new file mode 100644
index 00000000..9ff398b4
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/Common/lcd.h
@@ -0,0 +1,114 @@
+/**
+ ******************************************************************************
+ * @file lcd.h
+ * @author MCD Application Team
+ * @version V4.0.1
+ * @date 21-July-2015
+ * @brief This file contains all the functions prototypes for the LCD driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LCD_H
+#define __LCD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup LCD
+ * @{
+ */
+
+/** @defgroup LCD_Exported_Types
+ * @{
+ */
+
+/** @defgroup LCD_Driver_structure LCD Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(void);
+ uint16_t (*ReadID)(void);
+ void (*DisplayOn)(void);
+ void (*DisplayOff)(void);
+ void (*SetCursor)(uint16_t, uint16_t);
+ void (*WritePixel)(uint16_t, uint16_t, uint16_t);
+ uint16_t (*ReadPixel)(uint16_t, uint16_t);
+
+ /* Optimized operation */
+ void (*SetDisplayWindow)(uint16_t, uint16_t, uint16_t, uint16_t);
+ void (*DrawHLine)(uint16_t, uint16_t, uint16_t, uint16_t);
+ void (*DrawVLine)(uint16_t, uint16_t, uint16_t, uint16_t);
+
+ uint16_t (*GetLcdPixelWidth)(void);
+ uint16_t (*GetLcdPixelHeight)(void);
+ void (*DrawBitmap)(uint16_t, uint16_t, uint8_t*);
+ void (*DrawRGBImage)(uint16_t, uint16_t, uint16_t, uint16_t, uint8_t*);
+}LCD_DrvTypeDef;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LCD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/Common/magneto.h b/src/port_stm32f7/common/bsp_drivers/Components/Common/magneto.h
new file mode 100644
index 00000000..dc27dd03
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/Common/magneto.h
@@ -0,0 +1,125 @@
+/**
+ ******************************************************************************
+ * @file magneto.h
+ * @author MCD Application Team
+ * @version V4.0.1
+ * @date 21-July-2015
+ * @brief This header file contains the functions prototypes for the MAGNETO driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MAGNETO_H
+#define __MAGNETO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup MAGNETO
+ * @{
+ */
+
+/** @defgroup MAGNETO_Exported_Types
+ * @{
+ */
+
+/** @defgroup MAGNETO_Config_structure Magnetometer Configuration structure
+ * @{
+ */
+typedef struct
+{
+ uint8_t Register1;
+ uint8_t Register2;
+ uint8_t Register3;
+ uint8_t Register4;
+ uint8_t Register5;
+}MAGNETO_InitTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup MAGNETO_Driver_structure Magnetometer Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(MAGNETO_InitTypeDef);
+ void (*DeInit)(void);
+ uint8_t (*ReadID)(void);
+ void (*Reset)(void);
+ void (*LowPower)(void);
+ void (*ConfigIT)(void);
+ void (*EnableIT)(uint8_t);
+ void (*DisableIT)(uint8_t);
+ uint8_t (*ITStatus)(uint16_t);
+ void (*ClearIT)(void);
+ void (*FilterConfig)(uint8_t);
+ void (*FilterCmd)(uint8_t);
+ void (*GetXYZ)(int16_t *);
+}MAGNETO_DrvTypeDef;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MAGNETO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/Common/ts.h b/src/port_stm32f7/common/bsp_drivers/Components/Common/ts.h
new file mode 100644
index 00000000..73705964
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/Common/ts.h
@@ -0,0 +1,107 @@
+/**
+ ******************************************************************************
+ * @file ts.h
+ * @author MCD Application Team
+ * @version V4.0.1
+ * @date 21-July-2015
+ * @brief This file contains all the functions prototypes for the Touch Screen driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TS_H
+#define __TS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup TS
+ * @{
+ */
+
+/** @defgroup TS_Exported_Types
+ * @{
+ */
+
+/** @defgroup TS_Driver_structure Touch Sensor Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(uint16_t);
+ uint16_t (*ReadID)(uint16_t);
+ void (*Reset)(uint16_t);
+ void (*Start)(uint16_t);
+ uint8_t (*DetectTouch)(uint16_t);
+ void (*GetXY)(uint16_t, uint16_t*, uint16_t*);
+ void (*EnableIT)(uint16_t);
+ void (*ClearIT)(uint16_t);
+ uint8_t (*GetITStatus)(uint16_t);
+ void (*DisableIT)(uint16_t);
+}TS_DrvTypeDef;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/Common/tsensor.h b/src/port_stm32f7/common/bsp_drivers/Components/Common/tsensor.h
new file mode 100644
index 00000000..4ea0ffc2
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/Common/tsensor.h
@@ -0,0 +1,118 @@
+/**
+ ******************************************************************************
+ * @file tsensor.h
+ * @author MCD Application Team
+ * @version V4.0.1
+ * @date 21-July-2015
+ * @brief This header file contains the functions prototypes for the
+ * Temperature Sensor driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSENSOR_H
+#define __TSENSOR_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup TSENSOR
+ * @{
+ */
+
+/** @defgroup TSENSOR_Exported_Types
+ * @{
+ */
+
+/** @defgroup TSENSOR_Config_structure Temperature Sensor Configuration structure
+ * @{
+ */
+typedef struct
+{
+ uint8_t AlertMode; /* Alert Mode Temperature out of range*/
+ uint8_t ConversionMode; /* Continuous/One Shot Mode */
+ uint8_t ConversionResolution; /* Temperature Resolution */
+ uint8_t ConversionRate; /* Number of measure per second */
+ uint8_t TemperatureLimitHigh; /* High Temperature Limit Range */
+ uint8_t TemperatureLimitLow; /* Low Temperature Limit Range */
+}TSENSOR_InitTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup TSENSOR_Driver_structure Temperature Sensor Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(uint16_t, TSENSOR_InitTypeDef *);
+ uint8_t (*IsReady)(uint16_t, uint32_t);
+ uint8_t (*ReadStatus)(uint16_t);
+ uint16_t (*ReadTemp)(uint16_t);
+}TSENSOR_DrvTypeDef;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TSENSOR_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/adv7533/Release_Notes.html b/src/port_stm32f7/common/bsp_drivers/Components/adv7533/Release_Notes.html
new file mode 100644
index 00000000..03a5dacf
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/adv7533/Release_Notes.html
@@ -0,0 +1,204 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Release Notes for STM32 BSP Components Drivers
+
+
+
+
+
+
+
+
+
+
Add adv7533_SetVolume, adv7533_SetOutputMode and adv7533_Reset to adv7533_drv for compatibility reasons
+
+
V1.0.0
+/ 26-August-2016
+
+
Main
+Changes
+
+
+
+
+
+
+
+
+
+
First official release of ADV7533 HDMI component driver
+
License
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/adv7533/adv7533.c b/src/port_stm32f7/common/bsp_drivers/Components/adv7533/adv7533.c
new file mode 100644
index 00000000..aee24e5c
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/adv7533/adv7533.c
@@ -0,0 +1,511 @@
+/**
+ ******************************************************************************
+ * @file adv7533.c
+ * @author MCD Application Team
+ * @brief This file provides the ADV7533 DSI to HDMI bridge driver
+ ******************************************************************************
+ * @attention
+ *
+ *
+
+ First official release of ampire480272 LCD component
+
License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/ampire480272/ampire480272.h b/src/port_stm32f7/common/bsp_drivers/Components/ampire480272/ampire480272.h
new file mode 100644
index 00000000..bf1d9ec6
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/ampire480272/ampire480272.h
@@ -0,0 +1,119 @@
+/**
+ ******************************************************************************
+ * @file ampire480272.h
+ * @author MCD Application Team
+ * @brief This file contains all the constants parameters for the ampire480272
+ * LCD component.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AMPIRE480272_H
+#define __AMPIRE480272_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup ampire480272
+ * @{
+ */
+
+/** @defgroup AMPIRE480272_Exported_Types
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup AMPIRE480272_Exported_Constants
+ * @{
+ */
+
+/**
+ * @brief AMPIRE480272 Size
+ */
+#define AMPIRE480272_WIDTH ((uint16_t)480) /* LCD PIXEL WIDTH */
+#define AMPIRE480272_HEIGHT ((uint16_t)272) /* LCD PIXEL HEIGHT */
+
+/**
+ * @brief AMPIRE480272 Timing
+ */
+#define AMPIRE480272_HSYNC ((uint16_t)41) /* Horizontal synchronization */
+#define AMPIRE480272_HBP ((uint16_t)2) /* Horizontal back porch */
+#define AMPIRE480272_HFP ((uint16_t)2) /* Horizontal front porch */
+#define AMPIRE480272_VSYNC ((uint16_t)10) /* Vertical synchronization */
+#define AMPIRE480272_VBP ((uint16_t)2) /* Vertical back porch */
+#define AMPIRE480272_VFP ((uint16_t)2) /* Vertical front porch */
+
+/**
+ * @brief AMPIRE480272 frequency divider
+ */
+#define AMPIRE480272_FREQUENCY_DIVIDER 5 /* LCD Frequency divider */
+/**
+ * @}
+ */
+
+/** @defgroup AMPIRE480272_Exported_Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMPIRE480272_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/ampire640480/Release_Notes.html b/src/port_stm32f7/common/bsp_drivers/Components/ampire640480/Release_Notes.html
new file mode 100644
index 00000000..203e0261
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/ampire640480/Release_Notes.html
@@ -0,0 +1,230 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Release Notes for Ampire480272 LCD Component Driver
+
+
+
+
+
+
+
+
+
+
+
+
+ First official release of ampire640480 LCD component
+
License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/ampire640480/ampire640480.h b/src/port_stm32f7/common/bsp_drivers/Components/ampire640480/ampire640480.h
new file mode 100644
index 00000000..0f566fc6
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/ampire640480/ampire640480.h
@@ -0,0 +1,119 @@
+/**
+ ******************************************************************************
+ * @file ampire640480.h
+ * @author MCD Application Team
+ * @brief This file contains all the constants parameters for the ampire640480
+ * LCD component.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AMPIRE640480_H
+#define __AMPIRE640480_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup ampire640480
+ * @{
+ */
+
+/** @defgroup AMPIRE640480_Exported_Types
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup AMPIRE640480_Exported_Constants
+ * @{
+ */
+
+/**
+ * @brief AMPIRE640480 Size
+ */
+#define AMPIRE640480_WIDTH ((uint16_t)640) /* LCD PIXEL WIDTH */
+#define AMPIRE640480_HEIGHT ((uint16_t)480) /* LCD PIXEL HEIGHT */
+
+/**
+ * @brief AMPIRE640480 Timing
+ */
+#define AMPIRE640480_HSYNC ((uint16_t)30) /* Horizontal synchronization */
+#define AMPIRE640480_HBP ((uint16_t)114) /* Horizontal back porch */
+#define AMPIRE640480_HFP ((uint16_t)16) /* Horizontal front porch */
+#define AMPIRE640480_VSYNC ((uint16_t)3) /* Vertical synchronization */
+#define AMPIRE640480_VBP ((uint16_t)32) /* Vertical back porch */
+#define AMPIRE640480_VFP ((uint16_t)10) /* Vertical front porch */
+
+/**
+ * @brief AMPIRE640480 frequency divider
+ */
+#define AMPIRE640480_FREQUENCY_DIVIDER 3 /* LCD Frequency divider */
+/**
+ * @}
+ */
+
+/** @defgroup AMPIRE640480_Exported_Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMPIRE640480_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/exc7200/Release_Notes.html b/src/port_stm32f7/common/bsp_drivers/Components/exc7200/Release_Notes.html
new file mode 100644
index 00000000..aa64c3fa
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/exc7200/Release_Notes.html
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Release Notes for STM32 BSP EXC7200 Components Drivers
+
+
+
+
+
+
+
+
+
+
+
Update the I2C slave read address within exc7200_TS_DetectTouch() function.
Update exc7200_TS_GetXY() function to return correct Touch Screen positions.
V1.0.0
+/ 28-April-2015
+
Main
+Changes
+
+
+
+
+
+
+
+
+
+
First official
+release of EXC7200 TS component driver
License
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/exc7200/exc7200.c b/src/port_stm32f7/common/bsp_drivers/Components/exc7200/exc7200.c
new file mode 100644
index 00000000..9e2dbb93
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/exc7200/exc7200.c
@@ -0,0 +1,240 @@
+/**
+ ******************************************************************************
+ * @file exc7200.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the EXC7200
+ * Touch-screen controller.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "exc7200.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Component
+ * @{
+ */
+
+/** @defgroup EXC7200
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+
+/** @defgroup EXC7200_Private_Types_Definitions
+ * @{
+ */
+
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup EXC7200_Private_Defines
+ * @{
+ */
+
+/* Private macro -------------------------------------------------------------*/
+
+/** @defgroup EXC7200_Private_Macros
+ * @{
+ */
+
+/* Private variables ---------------------------------------------------------*/
+
+/** @defgroup EXC7200_Private_Variables
+ * @{
+ */
+
+/* Touch screen driver structure initialization */
+TS_DrvTypeDef exc7200_ts_drv =
+{
+ exc7200_Init,
+ exc7200_ReadID,
+ exc7200_Reset,
+
+ exc7200_TS_Start,
+ exc7200_TS_DetectTouch,
+ exc7200_TS_GetXY,
+
+ exc7200_TS_EnableIT,
+ exc7200_TS_ClearIT,
+ exc7200_TS_ITStatus,
+ exc7200_TS_DisableIT,
+};
+
+uint8_t aBufferTS[10];
+
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+
+/** @defgroup exc7200_Private_Function_Prototypes
+ * @{
+ */
+
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup exc7200_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Initialize the exc7200 and configure the needed hardware resources
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void exc7200_Init(uint16_t DeviceAddr)
+{
+ /* Initialize IO BUS layer */
+ IOE_Init();
+
+}
+
+/**
+ * @brief Reset the exc7200 by Software.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void exc7200_Reset(uint16_t DeviceAddr)
+{
+
+}
+
+/**
+ * @brief Read the exc7200 IO Expander device ID.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval The Device ID (two bytes).
+ */
+uint16_t exc7200_ReadID(uint16_t DeviceAddr)
+{
+ return 0;
+}
+
+/**
+ * @brief Configures the touch Screen Controller (Single point detection)
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None.
+ */
+void exc7200_TS_Start(uint16_t DeviceAddr)
+{
+}
+
+/**
+ * @brief Return if there is touch detected or not.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Touch detected state.
+ */
+uint8_t exc7200_TS_DetectTouch(uint16_t DeviceAddr)
+{
+ /* Read TS data : Send I2C Slave address + 1 Bit0=1 for:read */
+ IOE_ReadMultiple(DeviceAddr | 1, EXC7200_READ_CMD, aBufferTS, 10);
+
+ /* check for first byte */
+ if (aBufferTS[1]==0x83)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Get the touch screen X and Y positions values
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param X: Pointer to X position value
+ * @param Y: Pointer to Y position value
+ * @retval None.
+ */
+void exc7200_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y)
+{
+ /* Calculate positions */
+ *X = (((aBufferTS[3]&0x00ff) << 4) | ((aBufferTS[2]&0x00f0) >> 4)) << 1;
+ *Y = (((aBufferTS[5]&0x00ff) << 4) | ((aBufferTS[4]&0x00f0) >> 4)) << 1;
+
+ /* Dummy Read to deactivate read mode */
+ IOE_ReadMultiple(DeviceAddr, EXC7200_READ_CMD, aBufferTS, 10);
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void exc7200_TS_EnableIT(uint16_t DeviceAddr)
+{
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void exc7200_TS_DisableIT(uint16_t DeviceAddr)
+{
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval TS interrupts status
+ */
+uint8_t exc7200_TS_ITStatus(uint16_t DeviceAddr)
+{
+ return 0;
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void exc7200_TS_ClearIT(uint16_t DeviceAddr)
+{
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/exc7200/exc7200.h b/src/port_stm32f7/common/bsp_drivers/Components/exc7200/exc7200.h
new file mode 100644
index 00000000..a03b89fa
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/exc7200/exc7200.h
@@ -0,0 +1,135 @@
+/**
+ ******************************************************************************
+ * @file exc7200.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for the
+ * exc7200.c IO expander driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __EXC7200_H
+#define __EXC7200_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "../Common/ts.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Component
+ * @{
+ */
+
+/** @defgroup EXC7200
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/** @defgroup EXC7200_Exported_Types
+ * @{
+ */
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup EXC7200_Exported_Constants
+ * @{
+ */
+
+/* */
+#define EXC7200_READ_CMD 0x09
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+
+/** @defgroup exc7200_Exported_Macros
+ * @{
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup exc7200_Exported_Functions
+ * @{
+ */
+
+/**
+ * @brief exc7200 Control functions
+ */
+void exc7200_Init(uint16_t DeviceAddr);
+void exc7200_Reset(uint16_t DeviceAddr);
+uint16_t exc7200_ReadID(uint16_t DeviceAddr);
+void exc7200_TS_Start(uint16_t DeviceAddr);
+uint8_t exc7200_TS_DetectTouch(uint16_t DeviceAddr);
+void exc7200_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y);
+void exc7200_TS_EnableIT(uint16_t DeviceAddr);
+void exc7200_TS_DisableIT(uint16_t DeviceAddr);
+uint8_t exc7200_TS_ITStatus (uint16_t DeviceAddr);
+void exc7200_TS_ClearIT (uint16_t DeviceAddr);
+
+void IOE_Init(void);
+void IOE_Delay(uint32_t delay);
+uint8_t IOE_Read(uint8_t addr, uint8_t reg);
+uint16_t IOE_ReadMultiple(uint8_t addr, uint8_t reg, uint8_t *buffer, uint16_t length);
+void IOE_WriteMultiple(uint8_t addr, uint8_t reg, uint8_t *buffer, uint16_t length);
+
+/* Touch screen driver structure */
+extern TS_DrvTypeDef exc7200_ts_drv;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __EXC7200_H */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/ft5336/Release_Notes.html b/src/port_stm32f7/common/bsp_drivers/Components/ft5336/Release_Notes.html
new file mode 100644
index 00000000..46e33a51
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/ft5336/Release_Notes.html
@@ -0,0 +1,215 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Release Notes for FT5336GQQ Component Driver
+
+
+
+
+
+
+
+
+
+
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/ft5336/ft5336.c b/src/port_stm32f7/common/bsp_drivers/Components/ft5336/ft5336.c
new file mode 100644
index 00000000..1cd70343
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/ft5336/ft5336.c
@@ -0,0 +1,623 @@
+/**
+ ******************************************************************************
+ * @file ft5336.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the FT5336
+ * touch screen devices.
+ ******************************************************************************
+ * @attention
+ *
+ *
First official release of FT6X06 TS component driver
License
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/ft6x06/ft6x06.c b/src/port_stm32f7/common/bsp_drivers/Components/ft6x06/ft6x06.c
new file mode 100644
index 00000000..56cb4300
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/ft6x06/ft6x06.c
@@ -0,0 +1,512 @@
+/**
+ ******************************************************************************
+ * @file ft6x06.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the FT6X06
+ * IO Expander devices.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "ft6x06.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Component
+ * @{
+ */
+
+/** @defgroup FT6X06
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+
+/** @defgroup FT6X06_Private_Defines FT6X06 Private Defines
+ * @{
+ */
+#define FT6x06_MAX_INSTANCE 2
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+
+/** @defgroup FT6X06_Private_Variables FT6X06 Private Variables
+ * @{
+ */
+
+/* Touch screen driver structure initialization */
+TS_DrvTypeDef ft6x06_ts_drv =
+{
+ ft6x06_Init,
+ ft6x06_ReadID,
+ ft6x06_Reset,
+
+ ft6x06_TS_Start,
+ ft6x06_TS_DetectTouch,
+ ft6x06_TS_GetXY,
+
+ ft6x06_TS_EnableIT,
+ ft6x06_TS_ClearIT,
+ ft6x06_TS_ITStatus,
+ ft6x06_TS_DisableIT
+};
+
+/* ft6x06 instances by address */
+uint8_t ft6x06[FT6x06_MAX_INSTANCE] = {0};
+
+/* Global ft6x06 handle */
+static ft6x06_handle_TypeDef ft6x06_handle = { FT6206_I2C_NOT_INITIALIZED, 0, 0};
+
+/**
+ * @}
+ */
+
+/** @defgroup ft6x06_Private_Function_Prototypes ft6x06 Private Function Prototypes
+ * @{
+ */
+static uint8_t ft6x06_GetInstance(uint16_t DeviceAddr);
+/* Private functions prototypes-----------------------------------------------*/
+#if (TS_AUTO_CALIBRATION_SUPPORTED == 1)
+/**
+ * @brief Start TouchScreen calibration phase
+ * @param DeviceAddr: FT6206 Device address for communication on I2C Bus.
+ * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK.
+ */
+static uint32_t ft6x06_TS_Calibration(uint16_t DeviceAddr);
+#endif /* TS_AUTO_CALIBRATION_SUPPORTED == 1 */
+
+/**
+ * @brief Basic static configuration of TouchScreen
+ * @param DeviceAddr: FT6206 Device address for communication on I2C Bus.
+ * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK.
+ */
+static uint32_t ft6x06_TS_Configure(uint16_t DeviceAddr);
+
+/**
+ * @}
+ */
+
+/** @defgroup ft6x06_Private_Functions ft6x06 Private Functions
+ * @{
+ */
+
+/**
+ * @brief Initialize the ft6x06 communication bus
+ * from MCU to FT6206 : ie I2C channel initialization (if required).
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval None
+ */
+void ft6x06_Init(uint16_t DeviceAddr)
+{
+ uint8_t instance;
+ uint8_t empty;
+
+ /* Check if device instance already exists */
+ instance = ft6x06_GetInstance(DeviceAddr);
+
+ /* To prevent double initialization */
+ if(instance == 0xFF)
+ {
+ /* Look for empty instance */
+ empty = ft6x06_GetInstance(0);
+
+ if(empty < FT6x06_MAX_INSTANCE)
+ {
+ /* Register the current device instance */
+ ft6x06[empty] = DeviceAddr;
+
+ /* Initialize IO BUS layer */
+ TS_IO_Init();
+ }
+ }
+}
+
+/**
+ * @brief Software Reset the ft6x06.
+ * @note : Not applicable to FT6206.
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval None
+ */
+void ft6x06_Reset(uint16_t DeviceAddr)
+{
+ /* Do nothing */
+ /* No software reset sequence available in FT6206 IC */
+}
+
+/**
+ * @brief Read the ft6x06 device ID, pre initialize I2C in case of need to be
+ * able to read the FT6206 device ID, and verify this is a FT6206.
+ * @param DeviceAddr: I2C FT6x06 Slave address.
+ * @retval The Device ID (two bytes).
+ */
+uint16_t ft6x06_ReadID(uint16_t DeviceAddr)
+{
+ /* Initialize I2C link if needed */
+ TS_IO_Init();
+
+ /* Return the device ID value */
+ return (TS_IO_Read(DeviceAddr, FT6206_CHIP_ID_REG));
+}
+
+/**
+ * @brief Configures the touch Screen IC device to start detecting touches
+ * It goes through an internal calibration process (Hw calibration sequence of
+ * the touch screen).
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address).
+ * @retval None.
+ */
+void ft6x06_TS_Start(uint16_t DeviceAddr)
+{
+#if (TS_AUTO_CALIBRATION_SUPPORTED == 1)
+ /* Hw Calibration sequence start : should be done once after each power up */
+ /* This is called internal calibration of the touch screen */
+ ft6x06_TS_Calibration(DeviceAddr);
+#endif
+ /* Minimum static configuration of FT6206 */
+ ft6x06_TS_Configure(DeviceAddr);
+
+ /* By default set FT6206 IC in Polling mode : no INT generation on FT6206 for new touch available */
+ /* Note TS_INT is active low */
+ ft6x06_TS_DisableIT(DeviceAddr);
+}
+
+/**
+ * @brief Return if there is touches detected or not.
+ * Try to detect new touches and forget the old ones (reset internal global
+ * variables).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval : Number of active touches detected (can be 0, 1 or 2).
+ */
+uint8_t ft6x06_TS_DetectTouch(uint16_t DeviceAddr)
+{
+ volatile uint8_t nbTouch = 0;
+
+ /* Read register FT6206_TD_STAT_REG to check number of touches detection */
+ nbTouch = TS_IO_Read(DeviceAddr, FT6206_TD_STAT_REG);
+ nbTouch &= FT6206_TD_STAT_MASK;
+
+ if(nbTouch > FT6206_MAX_DETECTABLE_TOUCH)
+ {
+ /* If invalid number of touch detected, set it to zero */
+ nbTouch = 0;
+ }
+
+ /* Update ft6x06 driver internal global : current number of active touches */
+ ft6x06_handle.currActiveTouchNb = nbTouch;
+
+ /* Reset current active touch index on which to work on */
+ ft6x06_handle.currActiveTouchIdx = 0;
+
+ return(nbTouch);
+}
+
+/**
+ * @brief Get the touch screen X and Y positions values
+ * Manage multi touch thanks to touch Index global
+ * variable 'ft6x06_handle.currActiveTouchIdx'.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param X: Pointer to X position value
+ * @param Y: Pointer to Y position value
+ * @retval None.
+ */
+void ft6x06_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y)
+{
+ uint8_t regAddress = 0;
+ uint8_t dataxy[4];
+
+ if(ft6x06_handle.currActiveTouchIdx < ft6x06_handle.currActiveTouchNb)
+ {
+ switch(ft6x06_handle.currActiveTouchIdx)
+ {
+ case 0 :
+ regAddress = FT6206_P1_XH_REG;
+ break;
+ case 1 :
+ regAddress = FT6206_P2_XH_REG;
+ break;
+
+ default :
+ break;
+ }
+
+ /* Read X and Y positions */
+ TS_IO_ReadMultiple(DeviceAddr, regAddress, dataxy, sizeof(dataxy));
+
+ /* Send back ready X position to caller */
+ *X = ((dataxy[0] & FT6206_MSB_MASK) << 8) | (dataxy[1] & FT6206_LSB_MASK);
+
+ /* Send back ready Y position to caller */
+ *Y = ((dataxy[2] & FT6206_MSB_MASK) << 8) | (dataxy[3] & FT6206_LSB_MASK);
+
+ ft6x06_handle.currActiveTouchIdx++;
+ }
+}
+
+/**
+ * @brief Configure the FT6206 device to generate IT on given INT pin
+ * connected to MCU as EXTI.
+ * @param DeviceAddr: Device address on communication Bus (Slave I2C address of FT6206).
+ * @retval None
+ */
+void ft6x06_TS_EnableIT(uint16_t DeviceAddr)
+{
+ uint8_t regValue = 0;
+ regValue = (FT6206_G_MODE_INTERRUPT_TRIGGER & (FT6206_G_MODE_INTERRUPT_MASK >> FT6206_G_MODE_INTERRUPT_SHIFT)) << FT6206_G_MODE_INTERRUPT_SHIFT;
+
+ /* Set interrupt trigger mode in FT6206_GMODE_REG */
+ TS_IO_Write(DeviceAddr, FT6206_GMODE_REG, regValue);
+}
+
+/**
+ * @brief Configure the FT6206 device to stop generating IT on the given INT pin
+ * connected to MCU as EXTI.
+ * @param DeviceAddr: Device address on communication Bus (Slave I2C address of FT6206).
+ * @retval None
+ */
+void ft6x06_TS_DisableIT(uint16_t DeviceAddr)
+{
+ uint8_t regValue = 0;
+ regValue = (FT6206_G_MODE_INTERRUPT_POLLING & (FT6206_G_MODE_INTERRUPT_MASK >> FT6206_G_MODE_INTERRUPT_SHIFT)) << FT6206_G_MODE_INTERRUPT_SHIFT;
+
+ /* Set interrupt polling mode in FT6206_GMODE_REG */
+ TS_IO_Write(DeviceAddr, FT6206_GMODE_REG, regValue);
+}
+
+/**
+ * @brief Get IT status from FT6206 interrupt status registers
+ * Should be called Following an EXTI coming to the MCU to know the detailed
+ * reason of the interrupt.
+ * @note : This feature is not applicable to FT6206.
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval TS interrupts status : always return 0 here
+ */
+uint8_t ft6x06_TS_ITStatus(uint16_t DeviceAddr)
+{
+ /* Always return 0 as feature not applicable to FT6206 */
+ return 0;
+}
+
+/**
+ * @brief Clear IT status in FT6206 interrupt status clear registers
+ * Should be called Following an EXTI coming to the MCU.
+ * @note : This feature is not applicable to FT6206.
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval None
+ */
+void ft6x06_TS_ClearIT(uint16_t DeviceAddr)
+{
+ /* Nothing to be done here for FT6206 */
+}
+
+/**** NEW FEATURES enabled when Multi-touch support is enabled ****/
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+/**
+ * @brief Get the last touch gesture identification (zoom, move up/down...).
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6x06).
+ * @param pGestureId : Pointer to get last touch gesture Identification.
+ * @retval None.
+ */
+void ft6x06_TS_GetGestureID(uint16_t DeviceAddr, uint32_t * pGestureId)
+{
+ volatile uint8_t ucReadData = 0;
+
+ ucReadData = TS_IO_Read(DeviceAddr, FT6206_GEST_ID_REG);
+
+ * pGestureId = ucReadData;
+}
+
+/**
+ * @brief Get the touch detailed informations on touch number 'touchIdx' (0..1)
+ * This touch detailed information contains :
+ * - weight that was applied to this touch
+ * - sub-area of the touch in the touch panel
+ * - event of linked to the touch (press down, lift up, ...)
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6x06).
+ * @param touchIdx : Passed index of the touch (0..1) on which we want to get the
+ * detailed information.
+ * @param pWeight : Pointer to to get the weight information of 'touchIdx'.
+ * @param pArea : Pointer to to get the sub-area information of 'touchIdx'.
+ * @param pEvent : Pointer to to get the event information of 'touchIdx'.
+
+ * @retval None.
+ */
+void ft6x06_TS_GetTouchInfo(uint16_t DeviceAddr,
+ uint32_t touchIdx,
+ uint32_t * pWeight,
+ uint32_t * pArea,
+ uint32_t * pEvent)
+{
+ uint8_t regAddress = 0;
+ uint8_t dataxy[3];
+
+ if(touchIdx < ft6x06_handle.currActiveTouchNb)
+ {
+ switch(touchIdx)
+ {
+ case 0 :
+ regAddress = FT6206_P1_WEIGHT_REG;
+ break;
+
+ case 1 :
+ regAddress = FT6206_P2_WEIGHT_REG;
+ break;
+
+ default :
+ break;
+
+ } /* end switch(touchIdx) */
+
+ /* Read weight, area and Event Id of touch index */
+ TS_IO_ReadMultiple(DeviceAddr, regAddress, dataxy, sizeof(dataxy));
+
+ /* Return weight of touch index */
+ * pWeight = (dataxy[0] & FT6206_TOUCH_WEIGHT_MASK) >> FT6206_TOUCH_WEIGHT_SHIFT;
+ /* Return area of touch index */
+ * pArea = (dataxy[1] & FT6206_TOUCH_AREA_MASK) >> FT6206_TOUCH_AREA_SHIFT;
+ /* Return Event Id of touch index */
+ * pEvent = (dataxy[2] & FT6206_TOUCH_EVT_FLAG_MASK) >> FT6206_TOUCH_EVT_FLAG_SHIFT;
+
+ } /* of if(touchIdx < ft6x06_handle.currActiveTouchNb) */
+}
+
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+#if (TS_AUTO_CALIBRATION_SUPPORTED == 1)
+/**
+ * @brief Start TouchScreen calibration phase
+ * @param DeviceAddr: FT6206 Device address for communication on I2C Bus.
+ * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK.
+ */
+static uint32_t ft6x06_TS_Calibration(uint16_t DeviceAddr)
+{
+ uint32_t nbAttempt = 0;
+ volatile uint8_t ucReadData;
+ volatile uint8_t regValue;
+ uint32_t status = FT6206_STATUS_OK;
+ uint8_t bEndCalibration = 0;
+
+ /* >> Calibration sequence start */
+
+ /* Switch FT6206 back to factory mode to calibrate */
+ regValue = (FT6206_DEV_MODE_FACTORY & FT6206_DEV_MODE_MASK) << FT6206_DEV_MODE_SHIFT;
+ TS_IO_Write(DeviceAddr, FT6206_DEV_MODE_REG, regValue); /* 0x40 */
+
+ /* Read back the same register FT6206_DEV_MODE_REG */
+ ucReadData = TS_IO_Read(DeviceAddr, FT6206_DEV_MODE_REG);
+ TS_IO_Delay(300); /* Wait 300 ms */
+
+ if(((ucReadData & (FT6206_DEV_MODE_MASK << FT6206_DEV_MODE_SHIFT)) >> FT6206_DEV_MODE_SHIFT) != FT6206_DEV_MODE_FACTORY )
+ {
+ /* Return error to caller */
+ return(FT6206_STATUS_NOT_OK);
+ }
+
+ /* Start calibration command */
+ TS_IO_Write(DeviceAddr, FT6206_TD_STAT_REG, 0x04);
+ TS_IO_Delay(300); /* Wait 300 ms */
+
+ /* 100 attempts to wait switch from factory mode (calibration) to working mode */
+ for (nbAttempt=0; ((nbAttempt < 100) && (!bEndCalibration)) ; nbAttempt++)
+ {
+ ucReadData = TS_IO_Read(DeviceAddr, FT6206_DEV_MODE_REG);
+ ucReadData = (ucReadData & (FT6206_DEV_MODE_MASK << FT6206_DEV_MODE_SHIFT)) >> FT6206_DEV_MODE_SHIFT;
+ if(ucReadData == FT6206_DEV_MODE_WORKING)
+ {
+ /* Auto Switch to FT6206_DEV_MODE_WORKING : means calibration have ended */
+ bEndCalibration = 1; /* exit for loop */
+ }
+
+ TS_IO_Delay(200); /* Wait 200 ms */
+ }
+
+ /* Calibration sequence end << */
+
+ return(status);
+}
+#endif /* TS_AUTO_CALIBRATION_SUPPORTED == 1 */
+
+/**
+ * @brief Basic static configuration of TouchScreen
+ * @param DeviceAddr: FT6206 Device address for communication on I2C Bus.
+ * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK.
+ */
+static uint32_t ft6x06_TS_Configure(uint16_t DeviceAddr)
+{
+ uint32_t status = FT6206_STATUS_OK;
+
+ /* Nothing special to be done for FT6206 */
+
+ return(status);
+}
+
+/**
+ * @brief Check if the device instance of the selected address is already registered
+ * and return its index
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Index of the device instance if registered, 0xFF if not.
+ */
+static uint8_t ft6x06_GetInstance(uint16_t DeviceAddr)
+{
+ uint8_t idx = 0;
+
+ /* Check all the registered instances */
+ for(idx = 0; idx < FT6x06_MAX_INSTANCE ; idx ++)
+ {
+ if(ft6x06[idx] == DeviceAddr)
+ {
+ return idx;
+ }
+ }
+
+ return 0xFF;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/ft6x06/ft6x06.h b/src/port_stm32f7/common/bsp_drivers/Components/ft6x06/ft6x06.h
new file mode 100644
index 00000000..67ac74c5
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/ft6x06/ft6x06.h
@@ -0,0 +1,469 @@
+/**
+ ******************************************************************************
+ * @file ft6x06.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for the
+ * ft6x06.c IO expander driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __FT6X06_H
+#define __FT6X06_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Set Multi-touch as non supported */
+#ifndef TS_MULTI_TOUCH_SUPPORTED
+ #define TS_MULTI_TOUCH_SUPPORTED 0
+#endif
+
+/* Set Auto-calibration as non supported */
+#ifndef TS_AUTO_CALIBRATION_SUPPORTED
+ #define TS_AUTO_CALIBRATION_SUPPORTED 0
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "../Common/ts.h"
+
+/* Macros --------------------------------------------------------------------*/
+
+/** @typedef ft6x06_handle_TypeDef
+ * ft6x06 Handle definition.
+ */
+typedef struct
+{
+ uint8_t i2cInitialized;
+
+ /* field holding the current number of simultaneous active touches */
+ uint8_t currActiveTouchNb;
+
+ /* field holding the touch index currently managed */
+ uint8_t currActiveTouchIdx;
+
+} ft6x06_handle_TypeDef;
+
+ /** @addtogroup BSP
+ * @{
+ */
+
+ /** @addtogroup Component
+ * @{
+ */
+
+ /** @defgroup FT6X06
+ * @{
+ */
+
+ /* Exported types ------------------------------------------------------------*/
+
+ /** @defgroup FT6X06_Exported_Types
+ * @{
+ */
+
+ /* Exported constants --------------------------------------------------------*/
+
+ /** @defgroup FT6X06_Exported_Constants
+ * @{
+ */
+
+ /* Maximum border values of the touchscreen pad */
+#define FT_6206_MAX_WIDTH ((uint16_t)800) /* Touchscreen pad max width */
+#define FT_6206_MAX_HEIGHT ((uint16_t)480) /* Touchscreen pad max height */
+
+ /* Touchscreen pad max width and height values for FT6x36 Touch*/
+#define FT_6206_MAX_WIDTH_HEIGHT ((uint16_t)240)
+
+ /* Possible values of driver functions return status */
+#define FT6206_STATUS_OK 0
+#define FT6206_STATUS_NOT_OK 1
+
+ /* Possible values of global variable 'TS_I2C_Initialized' */
+#define FT6206_I2C_NOT_INITIALIZED 0
+#define FT6206_I2C_INITIALIZED 1
+
+ /* Max detectable simultaneous touches */
+#define FT6206_MAX_DETECTABLE_TOUCH 2
+
+ /**
+ * @brief : Definitions for FT6206 I2C register addresses on 8 bit
+ **/
+
+ /* Current mode register of the FT6206 (R/W) */
+#define FT6206_DEV_MODE_REG 0x00
+
+ /* Possible values of FT6206_DEV_MODE_REG */
+#define FT6206_DEV_MODE_WORKING 0x00
+#define FT6206_DEV_MODE_FACTORY 0x04
+
+#define FT6206_DEV_MODE_MASK 0x7
+#define FT6206_DEV_MODE_SHIFT 4
+
+ /* Gesture ID register */
+#define FT6206_GEST_ID_REG 0x01
+
+ /* Possible values of FT6206_GEST_ID_REG */
+#define FT6206_GEST_ID_NO_GESTURE 0x00
+#define FT6206_GEST_ID_MOVE_UP 0x10
+#define FT6206_GEST_ID_MOVE_RIGHT 0x14
+#define FT6206_GEST_ID_MOVE_DOWN 0x18
+#define FT6206_GEST_ID_MOVE_LEFT 0x1C
+#define FT6206_GEST_ID_ZOOM_IN 0x48
+#define FT6206_GEST_ID_ZOOM_OUT 0x49
+
+ /* Touch Data Status register : gives number of active touch points (0..2) */
+#define FT6206_TD_STAT_REG 0x02
+
+ /* Values related to FT6206_TD_STAT_REG */
+#define FT6206_TD_STAT_MASK 0x0F
+#define FT6206_TD_STAT_SHIFT 0x00
+
+ /* Values Pn_XH and Pn_YH related */
+#define FT6206_TOUCH_EVT_FLAG_PRESS_DOWN 0x00
+#define FT6206_TOUCH_EVT_FLAG_LIFT_UP 0x01
+#define FT6206_TOUCH_EVT_FLAG_CONTACT 0x02
+#define FT6206_TOUCH_EVT_FLAG_NO_EVENT 0x03
+
+#define FT6206_TOUCH_EVT_FLAG_SHIFT 6
+#define FT6206_TOUCH_EVT_FLAG_MASK (3 << FT6206_TOUCH_EVT_FLAG_SHIFT)
+
+#define FT6206_MSB_MASK 0x0F
+#define FT6206_MSB_SHIFT 0
+
+ /* Values Pn_XL and Pn_YL related */
+#define FT6206_LSB_MASK 0xFF
+#define FT6206_LSB_SHIFT 0
+
+#define FT6206_P1_XH_REG 0x03
+#define FT6206_P1_XL_REG 0x04
+#define FT6206_P1_YH_REG 0x05
+#define FT6206_P1_YL_REG 0x06
+
+ /* Touch Pressure register value (R) */
+#define FT6206_P1_WEIGHT_REG 0x07
+
+ /* Values Pn_WEIGHT related */
+#define FT6206_TOUCH_WEIGHT_MASK 0xFF
+#define FT6206_TOUCH_WEIGHT_SHIFT 0
+
+ /* Touch area register */
+#define FT6206_P1_MISC_REG 0x08
+
+ /* Values related to FT6206_Pn_MISC_REG */
+#define FT6206_TOUCH_AREA_MASK (0x04 << 4)
+#define FT6206_TOUCH_AREA_SHIFT 0x04
+
+#define FT6206_P2_XH_REG 0x09
+#define FT6206_P2_XL_REG 0x0A
+#define FT6206_P2_YH_REG 0x0B
+#define FT6206_P2_YL_REG 0x0C
+#define FT6206_P2_WEIGHT_REG 0x0D
+#define FT6206_P2_MISC_REG 0x0E
+
+ /* Threshold for touch detection */
+#define FT6206_TH_GROUP_REG 0x80
+
+ /* Values FT6206_TH_GROUP_REG : threshold related */
+#define FT6206_THRESHOLD_MASK 0xFF
+#define FT6206_THRESHOLD_SHIFT 0
+
+ /* Filter function coefficients */
+#define FT6206_TH_DIFF_REG 0x85
+
+ /* Control register */
+#define FT6206_CTRL_REG 0x86
+
+ /* Values related to FT6206_CTRL_REG */
+
+ /* Will keep the Active mode when there is no touching */
+#define FT6206_CTRL_KEEP_ACTIVE_MODE 0x00
+
+ /* Switching from Active mode to Monitor mode automatically when there is no touching */
+#define FT6206_CTRL_KEEP_AUTO_SWITCH_MONITOR_MODE 0x01
+
+ /* The time period of switching from Active mode to Monitor mode when there is no touching */
+#define FT6206_TIMEENTERMONITOR_REG 0x87
+
+ /* Report rate in Active mode */
+#define FT6206_PERIODACTIVE_REG 0x88
+
+ /* Report rate in Monitor mode */
+#define FT6206_PERIODMONITOR_REG 0x89
+
+ /* The value of the minimum allowed angle while Rotating gesture mode */
+#define FT6206_RADIAN_VALUE_REG 0x91
+
+ /* Maximum offset while Moving Left and Moving Right gesture */
+#define FT6206_OFFSET_LEFT_RIGHT_REG 0x92
+
+ /* Maximum offset while Moving Up and Moving Down gesture */
+#define FT6206_OFFSET_UP_DOWN_REG 0x93
+
+ /* Minimum distance while Moving Left and Moving Right gesture */
+#define FT6206_DISTANCE_LEFT_RIGHT_REG 0x94
+
+ /* Minimum distance while Moving Up and Moving Down gesture */
+#define FT6206_DISTANCE_UP_DOWN_REG 0x95
+
+ /* Maximum distance while Zoom In and Zoom Out gesture */
+#define FT6206_DISTANCE_ZOOM_REG 0x96
+
+ /* High 8-bit of LIB Version info */
+#define FT6206_LIB_VER_H_REG 0xA1
+
+ /* Low 8-bit of LIB Version info */
+#define FT6206_LIB_VER_L_REG 0xA2
+
+ /* Chip Selecting */
+#define FT6206_CIPHER_REG 0xA3
+
+ /* Interrupt mode register (used when in interrupt mode) */
+#define FT6206_GMODE_REG 0xA4
+
+#define FT6206_G_MODE_INTERRUPT_MASK 0x03
+#define FT6206_G_MODE_INTERRUPT_SHIFT 0x00
+
+ /* Possible values of FT6206_GMODE_REG */
+#define FT6206_G_MODE_INTERRUPT_POLLING 0x00
+#define FT6206_G_MODE_INTERRUPT_TRIGGER 0x01
+
+ /* Current power mode the FT6206 system is in (R) */
+#define FT6206_PWR_MODE_REG 0xA5
+
+ /* FT6206 firmware version */
+#define FT6206_FIRMID_REG 0xA6
+
+ /* FT6206 Chip identification register */
+#define FT6206_CHIP_ID_REG 0xA8
+
+ /* Possible values of FT6206_CHIP_ID_REG */
+#define FT6206_ID_VALUE 0x11
+#define FT6x36_ID_VALUE 0xCD
+
+ /* Release code version */
+#define FT6206_RELEASE_CODE_ID_REG 0xAF
+
+ /* Current operating mode the FT6206 system is in (R) */
+#define FT6206_STATE_REG 0xBC
+
+ /**
+ * @}
+ */
+
+ /* Exported macro ------------------------------------------------------------*/
+
+ /** @defgroup ft6x06_Exported_Macros
+ * @{
+ */
+
+ /* Exported functions --------------------------------------------------------*/
+
+ /** @defgroup ft6x06_Exported_Functions
+ * @{
+ */
+
+ /**
+ * @brief ft6x06 Control functions
+ */
+
+
+/**
+ * @brief Initialize the ft6x06 communication bus
+ * from MCU to FT6206 : ie I2C channel initialization (if required).
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval None
+ */
+void ft6x06_Init(uint16_t DeviceAddr);
+
+/**
+ * @brief Software Reset the ft6x06.
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval None
+ */
+void ft6x06_Reset(uint16_t DeviceAddr);
+
+/**
+ * @brief Read the ft6x06 device ID, pre intitalize I2C in case of need to be
+ * able to read the FT6206 device ID, and verify this is a FT6206.
+ * @param DeviceAddr: I2C FT6x06 Slave address.
+ * @retval The Device ID (two bytes).
+ */
+uint16_t ft6x06_ReadID(uint16_t DeviceAddr);
+
+/**
+ * @brief Configures the touch Screen IC device to start detecting touches
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address).
+ * @retval None.
+ */
+void ft6x06_TS_Start(uint16_t DeviceAddr);
+
+/**
+ * @brief Return if there is touches detected or not.
+ * Try to detect new touches and forget the old ones (reset internal global
+ * variables).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval : Number of active touches detected (can be 0, 1 or 2).
+ */
+uint8_t ft6x06_TS_DetectTouch(uint16_t DeviceAddr);
+
+/**
+ * @brief Get the touch screen X and Y positions values
+ * Manage multi touch thanks to touch Index global
+ * variable 'ft6x06_handle.currActiveTouchIdx'.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param X: Pointer to X position value
+ * @param Y: Pointer to Y position value
+ * @retval None.
+ */
+void ft6x06_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y);
+
+/**
+ * @brief Configure the FT6206 device to generate IT on given INT pin
+ * connected to MCU as EXTI.
+ * @param DeviceAddr: Device address on communication Bus (Slave I2C address of FT6206).
+ * @retval None
+ */
+void ft6x06_TS_EnableIT(uint16_t DeviceAddr);
+
+/**
+ * @brief Configure the FT6206 device to stop generating IT on the given INT pin
+ * connected to MCU as EXTI.
+ * @param DeviceAddr: Device address on communication Bus (Slave I2C address of FT6206).
+ * @retval None
+ */
+void ft6x06_TS_DisableIT(uint16_t DeviceAddr);
+
+/**
+ * @brief Get IT status from FT6206 interrupt status registers
+ * Should be called Following an EXTI coming to the MCU to know the detailed
+ * reason of the interrupt.
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval TS interrupts status
+ */
+uint8_t ft6x06_TS_ITStatus (uint16_t DeviceAddr);
+
+/**
+ * @brief Clear IT status in FT6206 interrupt status clear registers
+ * Should be called Following an EXTI coming to the MCU.
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval TS interrupts status
+ */
+void ft6x06_TS_ClearIT (uint16_t DeviceAddr);
+
+/**** NEW FEATURES enabled when Multi-touch support is enabled ****/
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+
+/**
+ * @brief Get the last touch gesture identification (zoom, move up/down...).
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6x06).
+ * @param pGestureId : Pointer to get last touch gesture Identification.
+ * @retval None.
+ */
+void ft6x06_TS_GetGestureID(uint16_t DeviceAddr, uint32_t * pGestureId);
+
+/**
+ * @brief Get the touch detailed informations on touch number 'touchIdx' (0..1)
+ * This touch detailed information contains :
+ * - weight that was applied to this touch
+ * - sub-area of the touch in the touch panel
+ * - event of linked to the touch (press down, lift up, ...)
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6x06).
+ * @param touchIdx : Passed index of the touch (0..1) on which we want to get the
+ * detailed information.
+ * @param pWeight : Pointer to to get the weight information of 'touchIdx'.
+ * @param pArea : Pointer to to get the sub-area information of 'touchIdx'.
+ * @param pEvent : Pointer to to get the event information of 'touchIdx'.
+
+ * @retval None.
+ */
+void ft6x06_TS_GetTouchInfo(uint16_t DeviceAddr,
+ uint32_t touchIdx,
+ uint32_t * pWeight,
+ uint32_t * pArea,
+ uint32_t * pEvent);
+
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+/* Imported TS IO functions --------------------------------------------------------*/
+
+/** @defgroup ft6x06_Imported_Functions
+ * @{
+ */
+
+/* TouchScreen (TS) external IO functions */
+extern void TS_IO_Init(void);
+extern void TS_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value);
+extern uint8_t TS_IO_Read(uint8_t Addr, uint8_t Reg);
+extern uint16_t TS_IO_ReadMultiple(uint8_t Addr, uint8_t Reg, uint8_t *Buffer, uint16_t Length);
+extern void TS_IO_Delay(uint32_t Delay);
+
+ /**
+ * @}
+ */
+
+ /* Imported global variables --------------------------------------------------------*/
+
+ /** @defgroup ft6x06_Imported_Globals
+ * @{
+ */
+
+
+/* Touch screen driver structure */
+extern TS_DrvTypeDef ft6x06_ts_drv;
+
+ /**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __FT6X06_H */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/mfxstm32l152/Release_Notes.html b/src/port_stm32f7/common/bsp_drivers/Components/mfxstm32l152/Release_Notes.html
new file mode 100644
index 00000000..ae8ec0e6
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/mfxstm32l152/Release_Notes.html
@@ -0,0 +1,295 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Release Notes for MFXSTM32L152 Component Driver
+
+
+
+
+
+
+
+
+
+
+
First official release of MFXSTM32L152 IO Expander component driver.
NOTE: This release must be used with BSP Common driver V2.1.0 or later.
License
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/mfxstm32l152/mfxstm32l152.c b/src/port_stm32f7/common/bsp_drivers/Components/mfxstm32l152/mfxstm32l152.c
new file mode 100644
index 00000000..faadf68b
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/mfxstm32l152/mfxstm32l152.c
@@ -0,0 +1,1602 @@
+/**
+ ******************************************************************************
+ * @file mfxstm32l152.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the MFXSTM32L152
+ * IO Expander devices.
+ ******************************************************************************
+ * @attention
+ *
+ *
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/mx25l512/mx25l512.h b/src/port_stm32f7/common/bsp_drivers/Components/mx25l512/mx25l512.h
new file mode 100644
index 00000000..3cb99ff5
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/mx25l512/mx25l512.h
@@ -0,0 +1,227 @@
+/**
+ ******************************************************************************
+ * @file mx25l512.h
+ * @author MCD Application Team
+ * @brief This file contains all the description of the MX25L51245G QSPI memory.
+ ******************************************************************************
+ * @attention
+ *
+ *
First official
+release of N25Q128A QuadSPI Flash Component driver
License
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/n25q128a/n25q128a.h b/src/port_stm32f7/common/bsp_drivers/Components/n25q128a/n25q128a.h
new file mode 100644
index 00000000..977fa795
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/n25q128a/n25q128a.h
@@ -0,0 +1,217 @@
+/**
+ ******************************************************************************
+ * @file n25q128a.h
+ * @author MCD Application Team
+ * @brief This file contains all the description of the N25Q128A QSPI memory.
+ ******************************************************************************
+ * @attention
+ *
+ *
First official
+release N25Q512A QSPI component driver
+
License
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/n25q512a/n25q512a.h b/src/port_stm32f7/common/bsp_drivers/Components/n25q512a/n25q512a.h
new file mode 100644
index 00000000..ec7006e8
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/n25q512a/n25q512a.h
@@ -0,0 +1,259 @@
+/**
+ ******************************************************************************
+ * @file n25q512a.h
+ * @author MCD Application Team
+ * @brief This file contains all the description of the N25Q512A QSPI memory.
+ ******************************************************************************
+ * @attention
+ *
+ *
Set the PWM
+ backlight frequency to over 22KHz to avoid audible noise.
+
+
V1.0.4 / 23-November-2020
+
+
Main Changes
+
+
Update
+ otm8009a.h to support ARM compiler Keil V6
+
+
V1.0.3 /
+ 07-April-2017
+
Main Changes
+
+
Update
+ comments to be used for PDSC generation
+
+
V1.0.2 /
+ 27-January-2017
+
Main Changes
+
+
Update DSI
+ controller timings
+
CABC LEDPWM frequency
+ adjusted to 19,5kHz
+
+
V1.0.1 /
+ 04-August-2016
+
Main Changes
+
+
Update DSI
+ controller timings
+
+
V1.0.0 /
+ 03-August-2015
+
Main Changes
+
+
First
+ official release of OTM8009A LCD component driver
+
+
License
+
Redistribution and use in source and
+ binary forms, with or without modification, are permitted provided that the
+ following conditions are met:
+
+
Redistributions
+ of source code must retain the above copyright notice, this list of
+ conditions and the following disclaimer.
+
Redistributions
+ in binary form must reproduce the above copyright notice, this list of
+ conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
Neither the
+ name of STMicroelectronics nor the names of its contributors may be
+ used to endorse or promote products derived
+
+
from
+ this software without specific prior written permission.
+
+ THIS
+ SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
For complete documentation on STM32 Microcontrollers
+ visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/otm8009a/otm8009a.c b/src/port_stm32f7/common/bsp_drivers/Components/otm8009a/otm8009a.c
new file mode 100644
index 00000000..f2183d2d
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/otm8009a/otm8009a.c
@@ -0,0 +1,452 @@
+/**
+ ******************************************************************************
+ * @file otm8009a.c
+ * @author MCD Application Team
+ * @brief This file provides the LCD Driver for KoD KM-040TMP-02-0621 (WVGA)
+ * DSI LCD Display OTM8009A.
+ ******************************************************************************
+ * @attention
+ *
+ *
+This software component is licensed by ST under BSD 3-Clause license, the “License”; You may not use this component except in compliance with the License. You may obtain a copy of the License at:
+
First official release of OV9655 CAMERA component driver
+
License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/ov9655/ov9655.c b/src/port_stm32f7/common/bsp_drivers/Components/ov9655/ov9655.c
new file mode 100644
index 00000000..e82d07f7
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/ov9655/ov9655.c
@@ -0,0 +1,859 @@
+/**
+ ******************************************************************************
+ * @file ov9655.c
+ * @author MCD Application Team
+ * @brief This file provides the OV9655 camera driver
+ ******************************************************************************
+ * @attention
+ *
+ *
+
+ First official release of RK043FN48H LCD component driver
+
License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/rk043fn48h/rk043fn48h.h b/src/port_stm32f7/common/bsp_drivers/Components/rk043fn48h/rk043fn48h.h
new file mode 100644
index 00000000..b8319158
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/rk043fn48h/rk043fn48h.h
@@ -0,0 +1,119 @@
+/**
+ ******************************************************************************
+ * @file rk043fn48h.h
+ * @author MCD Application Team
+ * @brief This file contains all the constants parameters for the RK043FN48H-CT672B
+ * LCD component.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __RK043FN48H_H
+#define __RK043FN48H_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup rk043fn48h
+ * @{
+ */
+
+/** @defgroup RK043FN48H_Exported_Types
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup RK043FN48H_Exported_Constants
+ * @{
+ */
+
+/**
+ * @brief RK043FN48H Size
+ */
+#define RK043FN48H_WIDTH ((uint16_t)480) /* LCD PIXEL WIDTH */
+#define RK043FN48H_HEIGHT ((uint16_t)272) /* LCD PIXEL HEIGHT */
+
+/**
+ * @brief RK043FN48H Timing
+ */
+#define RK043FN48H_HSYNC ((uint16_t)41) /* Horizontal synchronization */
+#define RK043FN48H_HBP ((uint16_t)13) /* Horizontal back porch */
+#define RK043FN48H_HFP ((uint16_t)32) /* Horizontal front porch */
+#define RK043FN48H_VSYNC ((uint16_t)10) /* Vertical synchronization */
+#define RK043FN48H_VBP ((uint16_t)2) /* Vertical back porch */
+#define RK043FN48H_VFP ((uint16_t)2) /* Vertical front porch */
+
+/**
+ * @brief RK043FN48H frequency divider
+ */
+#define RK043FN48H_FREQUENCY_DIVIDER 5 /* LCD Frequency divider */
+/**
+ * @}
+ */
+
+/** @defgroup RK043FN48H_Exported_Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RK043FN48H_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/s5k5cag/Release_Notes.html b/src/port_stm32f7/common/bsp_drivers/Components/s5k5cag/Release_Notes.html
new file mode 100644
index 00000000..c7dd932e
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/s5k5cag/Release_Notes.html
@@ -0,0 +1,1096 @@
+
+
+
+
+
+
+
+
+Release Notes for S5K5CAG Component Driver
+
+
+
+
+
+
+
+
+
+
+
+
+
First official
+release of S5K5CAG CAMERA component driver
+
+
License
+
Redistribution and use in source and
+ binary forms, with or without modification, are permitted provided that the
+ following conditions are met:
+
+
Redistributions
+ of source code must retain the above copyright notice, this list of
+ conditions and the following disclaimer.
+
Redistributions
+ in binary form must reproduce the above copyright notice, this list of
+ conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+
Neither
+ the name of STMicroelectronics nor the names of its contributors may
+ be used to endorse or promote products derived
+
+
from this software without specific prior written
+ permission.
+
+ THIS
+ SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
For
+ complete documentation on STM32 Microcontrollers
+ visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/s5k5cag/s5k5cag.c b/src/port_stm32f7/common/bsp_drivers/Components/s5k5cag/s5k5cag.c
new file mode 100644
index 00000000..806969a4
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/s5k5cag/s5k5cag.c
@@ -0,0 +1,3448 @@
+/**
+ ******************************************************************************
+ * @file s5k5cag.c
+ * @author MCD Application Team
+ * @brief This file provides the S5K5CAG camera driver
+ ******************************************************************************
+ * @attention
+ *
+ *
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/st7735/st7735.c b/src/port_stm32f7/common/bsp_drivers/Components/st7735/st7735.c
new file mode 100644
index 00000000..3581fb2a
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/st7735/st7735.c
@@ -0,0 +1,469 @@
+/**
+ ******************************************************************************
+ * @file st7735.c
+ * @author MCD Application Team
+ * @brief This file includes the driver for ST7735 LCD mounted on the Adafruit
+ * 1.8" TFT LCD shield (reference ID 802).
+ ******************************************************************************
+ * @attention
+ *
+ *
First official release of ST7789H2 LCD component driver
+
License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/st7789h2/st7789h2.c b/src/port_stm32f7/common/bsp_drivers/Components/st7789h2/st7789h2.c
new file mode 100644
index 00000000..19f17f34
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/st7789h2/st7789h2.c
@@ -0,0 +1,723 @@
+/**
+ ******************************************************************************
+ * @file st7789h2.c
+ * @author MCD Application Team
+ * @brief This file includes the LCD driver for st7789h2 LCD.
+ ******************************************************************************
+ * @attention
+ *
+ *
First official release STMPE811 IOExpander component driver
+
License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/stmpe811/stmpe811.c b/src/port_stm32f7/common/bsp_drivers/Components/stmpe811/stmpe811.c
new file mode 100644
index 00000000..c4b88f6c
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/stmpe811/stmpe811.c
@@ -0,0 +1,975 @@
+/**
+ ******************************************************************************
+ * @file stmpe811.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the STMPE811
+ * IO Expander devices.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stmpe811.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @defgroup STMPE811
+ * @{
+ */
+
+/** @defgroup STMPE811_Private_Types_Definitions
+ * @{
+ */
+
+/** @defgroup STMPE811_Private_Defines
+ * @{
+ */
+#define STMPE811_MAX_INSTANCE 2
+/**
+ * @}
+ */
+
+/** @defgroup STMPE811_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STMPE811_Private_Variables
+ * @{
+ */
+
+/* Touch screen driver structure initialization */
+TS_DrvTypeDef stmpe811_ts_drv =
+{
+ stmpe811_Init,
+ stmpe811_ReadID,
+ stmpe811_Reset,
+ stmpe811_TS_Start,
+ stmpe811_TS_DetectTouch,
+ stmpe811_TS_GetXY,
+ stmpe811_TS_EnableIT,
+ stmpe811_TS_ClearIT,
+ stmpe811_TS_ITStatus,
+ stmpe811_TS_DisableIT,
+};
+
+/* IO driver structure initialization */
+IO_DrvTypeDef stmpe811_io_drv =
+{
+ stmpe811_Init,
+ stmpe811_ReadID,
+ stmpe811_Reset,
+ stmpe811_IO_Start,
+ stmpe811_IO_Config,
+ stmpe811_IO_WritePin,
+ stmpe811_IO_ReadPin,
+ stmpe811_IO_EnableIT,
+ stmpe811_IO_DisableIT,
+ stmpe811_IO_ITStatus,
+ stmpe811_IO_ClearIT,
+};
+
+/* stmpe811 instances by address */
+uint8_t stmpe811[STMPE811_MAX_INSTANCE] = {0};
+/**
+ * @}
+ */
+
+/** @defgroup STMPE811_Private_Function_Prototypes
+ * @{
+ */
+static uint8_t stmpe811_GetInstance(uint16_t DeviceAddr);
+/**
+ * @}
+ */
+
+/** @defgroup STMPE811_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Initialize the stmpe811 and configure the needed hardware resources
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void stmpe811_Init(uint16_t DeviceAddr)
+{
+ uint8_t instance;
+ uint8_t empty;
+
+ /* Check if device instance already exists */
+ instance = stmpe811_GetInstance(DeviceAddr);
+
+ /* To prevent double initialization */
+ if(instance == 0xFF)
+ {
+ /* Look for empty instance */
+ empty = stmpe811_GetInstance(0);
+
+ if(empty < STMPE811_MAX_INSTANCE)
+ {
+ /* Register the current device instance */
+ stmpe811[empty] = DeviceAddr;
+
+ /* Initialize IO BUS layer */
+ IOE_Init();
+
+ /* Generate stmpe811 Software reset */
+ stmpe811_Reset(DeviceAddr);
+ }
+ }
+}
+
+/**
+ * @brief Reset the stmpe811 by Software.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void stmpe811_Reset(uint16_t DeviceAddr)
+{
+ /* Power Down the stmpe811 */
+ IOE_Write(DeviceAddr, STMPE811_REG_SYS_CTRL1, 2);
+
+ /* Wait for a delay to ensure registers erasing */
+ IOE_Delay(10);
+
+ /* Power On the Codec after the power off => all registers are reinitialized */
+ IOE_Write(DeviceAddr, STMPE811_REG_SYS_CTRL1, 0);
+
+ /* Wait for a delay to ensure registers erasing */
+ IOE_Delay(2);
+}
+
+/**
+ * @brief Read the stmpe811 IO Expander device ID.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval The Device ID (two bytes).
+ */
+uint16_t stmpe811_ReadID(uint16_t DeviceAddr)
+{
+ /* Initialize IO BUS layer */
+ IOE_Init();
+
+ /* Return the device ID value */
+ return ((IOE_Read(DeviceAddr, STMPE811_REG_CHP_ID_LSB) << 8) |\
+ (IOE_Read(DeviceAddr, STMPE811_REG_CHP_ID_MSB)));
+}
+
+/**
+ * @brief Enable the Global interrupt.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void stmpe811_EnableGlobalIT(uint16_t DeviceAddr)
+{
+ uint8_t tmp = 0;
+
+ /* Read the Interrupt Control register */
+ tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_CTRL);
+
+ /* Set the global interrupts to be Enabled */
+ tmp |= (uint8_t)STMPE811_GIT_EN;
+
+ /* Write Back the Interrupt Control register */
+ IOE_Write(DeviceAddr, STMPE811_REG_INT_CTRL, tmp);
+}
+
+/**
+ * @brief Disable the Global interrupt.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void stmpe811_DisableGlobalIT(uint16_t DeviceAddr)
+{
+ uint8_t tmp = 0;
+
+ /* Read the Interrupt Control register */
+ tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_CTRL);
+
+ /* Set the global interrupts to be Disabled */
+ tmp &= ~(uint8_t)STMPE811_GIT_EN;
+
+ /* Write Back the Interrupt Control register */
+ IOE_Write(DeviceAddr, STMPE811_REG_INT_CTRL, tmp);
+
+}
+
+/**
+ * @brief Enable the interrupt mode for the selected IT source
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Source: The interrupt source to be configured, could be:
+ * @arg STMPE811_GIT_IO: IO interrupt
+ * @arg STMPE811_GIT_ADC : ADC interrupt
+ * @arg STMPE811_GIT_FE : Touch Screen Controller FIFO Error interrupt
+ * @arg STMPE811_GIT_FF : Touch Screen Controller FIFO Full interrupt
+ * @arg STMPE811_GIT_FOV : Touch Screen Controller FIFO Overrun interrupt
+ * @arg STMPE811_GIT_FTH : Touch Screen Controller FIFO Threshold interrupt
+ * @arg STMPE811_GIT_TOUCH : Touch Screen Controller Touch Detected interrupt
+ * @retval None
+ */
+void stmpe811_EnableITSource(uint16_t DeviceAddr, uint8_t Source)
+{
+ uint8_t tmp = 0;
+
+ /* Get the current value of the INT_EN register */
+ tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_EN);
+
+ /* Set the interrupts to be Enabled */
+ tmp |= Source;
+
+ /* Set the register */
+ IOE_Write(DeviceAddr, STMPE811_REG_INT_EN, tmp);
+}
+
+/**
+ * @brief Disable the interrupt mode for the selected IT source
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Source: The interrupt source to be configured, could be:
+ * @arg STMPE811_GIT_IO: IO interrupt
+ * @arg STMPE811_GIT_ADC : ADC interrupt
+ * @arg STMPE811_GIT_FE : Touch Screen Controller FIFO Error interrupt
+ * @arg STMPE811_GIT_FF : Touch Screen Controller FIFO Full interrupt
+ * @arg STMPE811_GIT_FOV : Touch Screen Controller FIFO Overrun interrupt
+ * @arg STMPE811_GIT_FTH : Touch Screen Controller FIFO Threshold interrupt
+ * @arg STMPE811_GIT_TOUCH : Touch Screen Controller Touch Detected interrupt
+ * @retval None
+ */
+void stmpe811_DisableITSource(uint16_t DeviceAddr, uint8_t Source)
+{
+ uint8_t tmp = 0;
+
+ /* Get the current value of the INT_EN register */
+ tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_EN);
+
+ /* Set the interrupts to be Enabled */
+ tmp &= ~Source;
+
+ /* Set the register */
+ IOE_Write(DeviceAddr, STMPE811_REG_INT_EN, tmp);
+}
+
+/**
+ * @brief Set the global interrupt Polarity.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Polarity: the IT mode polarity, could be one of the following values:
+ * @arg STMPE811_POLARITY_LOW: Interrupt line is active Low/Falling edge
+ * @arg STMPE811_POLARITY_HIGH: Interrupt line is active High/Rising edge
+ * @retval None
+ */
+void stmpe811_SetITPolarity(uint16_t DeviceAddr, uint8_t Polarity)
+{
+ uint8_t tmp = 0;
+
+ /* Get the current register value */
+ tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_CTRL);
+
+ /* Mask the polarity bits */
+ tmp &= ~(uint8_t)0x04;
+
+ /* Modify the Interrupt Output line configuration */
+ tmp |= Polarity;
+
+ /* Set the new register value */
+ IOE_Write(DeviceAddr, STMPE811_REG_INT_CTRL, tmp);
+
+}
+
+/**
+ * @brief Set the global interrupt Type.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Type: Interrupt line activity type, could be one of the following values:
+ * @arg STMPE811_TYPE_LEVEL: Interrupt line is active in level model
+ * @arg STMPE811_TYPE_EDGE: Interrupt line is active in edge model
+ * @retval None
+ */
+void stmpe811_SetITType(uint16_t DeviceAddr, uint8_t Type)
+{
+ uint8_t tmp = 0;
+
+ /* Get the current register value */
+ tmp = IOE_Read(DeviceAddr, STMPE811_REG_INT_CTRL);
+
+ /* Mask the type bits */
+ tmp &= ~(uint8_t)0x02;
+
+ /* Modify the Interrupt Output line configuration */
+ tmp |= Type;
+
+ /* Set the new register value */
+ IOE_Write(DeviceAddr, STMPE811_REG_INT_CTRL, tmp);
+
+}
+
+/**
+ * @brief Check the selected Global interrupt source pending bit
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Source: the Global interrupt source to be checked, could be:
+ * @arg STMPE811_GIT_IO: IO interrupt
+ * @arg STMPE811_GIT_ADC : ADC interrupt
+ * @arg STMPE811_GIT_FE : Touch Screen Controller FIFO Error interrupt
+ * @arg STMPE811_GIT_FF : Touch Screen Controller FIFO Full interrupt
+ * @arg STMPE811_GIT_FOV : Touch Screen Controller FIFO Overrun interrupt
+ * @arg STMPE811_GIT_FTH : Touch Screen Controller FIFO Threshold interrupt
+ * @arg STMPE811_GIT_TOUCH : Touch Screen Controller Touch Detected interrupt
+ * @retval The checked Global interrupt source status.
+ */
+uint8_t stmpe811_GlobalITStatus(uint16_t DeviceAddr, uint8_t Source)
+{
+ /* Return the global IT source status */
+ return((IOE_Read(DeviceAddr, STMPE811_REG_INT_STA) & Source) == Source);
+}
+
+/**
+ * @brief Return the Global interrupts status
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Source: the Global interrupt source to be checked, could be:
+ * @arg STMPE811_GIT_IO: IO interrupt
+ * @arg STMPE811_GIT_ADC : ADC interrupt
+ * @arg STMPE811_GIT_FE : Touch Screen Controller FIFO Error interrupt
+ * @arg STMPE811_GIT_FF : Touch Screen Controller FIFO Full interrupt
+ * @arg STMPE811_GIT_FOV : Touch Screen Controller FIFO Overrun interrupt
+ * @arg STMPE811_GIT_FTH : Touch Screen Controller FIFO Threshold interrupt
+ * @arg STMPE811_GIT_TOUCH : Touch Screen Controller Touch Detected interrupt
+ * @retval The checked Global interrupt source status.
+ */
+uint8_t stmpe811_ReadGITStatus(uint16_t DeviceAddr, uint8_t Source)
+{
+ /* Return the global IT source status */
+ return((IOE_Read(DeviceAddr, STMPE811_REG_INT_STA) & Source));
+}
+
+/**
+ * @brief Clear the selected Global interrupt pending bit(s)
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Source: the Global interrupt source to be cleared, could be any combination
+ * of the following values:
+ * @arg STMPE811_GIT_IO: IO interrupt
+ * @arg STMPE811_GIT_ADC : ADC interrupt
+ * @arg STMPE811_GIT_FE : Touch Screen Controller FIFO Error interrupt
+ * @arg STMPE811_GIT_FF : Touch Screen Controller FIFO Full interrupt
+ * @arg STMPE811_GIT_FOV : Touch Screen Controller FIFO Overrun interrupt
+ * @arg STMPE811_GIT_FTH : Touch Screen Controller FIFO Threshold interrupt
+ * @arg STMPE811_GIT_TOUCH : Touch Screen Controller Touch Detected interrupt
+ * @retval None
+ */
+void stmpe811_ClearGlobalIT(uint16_t DeviceAddr, uint8_t Source)
+{
+ /* Write 1 to the bits that have to be cleared */
+ IOE_Write(DeviceAddr, STMPE811_REG_INT_STA, Source);
+}
+
+/**
+ * @brief Start the IO functionality use and disable the AF for selected IO pin(s).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO pin(s) to put in AF. This parameter can be one
+ * of the following values:
+ * @arg STMPE811_PIN_x: where x can be from 0 to 7.
+ * @retval None
+ */
+void stmpe811_IO_Start(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ uint8_t mode;
+
+ /* Get the current register value */
+ mode = IOE_Read(DeviceAddr, STMPE811_REG_SYS_CTRL2);
+
+ /* Set the Functionalities to be Disabled */
+ mode &= ~(STMPE811_IO_FCT | STMPE811_ADC_FCT);
+
+ /* Write the new register value */
+ IOE_Write(DeviceAddr, STMPE811_REG_SYS_CTRL2, mode);
+
+ /* Disable AF for the selected IO pin(s) */
+ stmpe811_IO_DisableAF(DeviceAddr, (uint8_t)IO_Pin);
+}
+
+/**
+ * @brief Configures the IO pin(s) according to IO mode structure value.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The output pin to be set or reset. This parameter can be one
+ * of the following values:
+ * @arg STMPE811_PIN_x: where x can be from 0 to 7.
+ * @param IO_Mode: The IO pin mode to configure, could be one of the following values:
+ * @arg IO_MODE_INPUT
+ * @arg IO_MODE_OUTPUT
+ * @arg IO_MODE_IT_RISING_EDGE
+ * @arg IO_MODE_IT_FALLING_EDGE
+ * @arg IO_MODE_IT_LOW_LEVEL
+ * @arg IO_MODE_IT_HIGH_LEVEL
+ * @retval 0 if no error, IO_Mode if error
+ */
+uint8_t stmpe811_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode)
+{
+ uint8_t error_code = 0;
+
+ /* Configure IO pin according to selected IO mode */
+ switch(IO_Mode)
+ {
+ case IO_MODE_INPUT: /* Input mode */
+ stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_IN);
+ break;
+
+ case IO_MODE_OUTPUT: /* Output mode */
+ stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_OUT);
+ break;
+
+ case IO_MODE_IT_RISING_EDGE: /* Interrupt rising edge mode */
+ stmpe811_IO_EnableIT(DeviceAddr);
+ stmpe811_IO_EnablePinIT(DeviceAddr, IO_Pin);
+ stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_IN);
+ stmpe811_SetITType(DeviceAddr, STMPE811_TYPE_EDGE);
+ stmpe811_IO_SetEdgeMode(DeviceAddr, IO_Pin, STMPE811_EDGE_RISING);
+ break;
+
+ case IO_MODE_IT_FALLING_EDGE: /* Interrupt falling edge mode */
+ stmpe811_IO_EnableIT(DeviceAddr);
+ stmpe811_IO_EnablePinIT(DeviceAddr, IO_Pin);
+ stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_IN);
+ stmpe811_SetITType(DeviceAddr, STMPE811_TYPE_EDGE);
+ stmpe811_IO_SetEdgeMode(DeviceAddr, IO_Pin, STMPE811_EDGE_FALLING);
+ break;
+
+ case IO_MODE_IT_LOW_LEVEL: /* Low level interrupt mode */
+ stmpe811_IO_EnableIT(DeviceAddr);
+ stmpe811_IO_EnablePinIT(DeviceAddr, IO_Pin);
+ stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_IN);
+ stmpe811_SetITType(DeviceAddr, STMPE811_TYPE_LEVEL);
+ stmpe811_SetITPolarity(DeviceAddr, STMPE811_POLARITY_LOW);
+ break;
+
+ case IO_MODE_IT_HIGH_LEVEL: /* High level interrupt mode */
+ stmpe811_IO_EnableIT(DeviceAddr);
+ stmpe811_IO_EnablePinIT(DeviceAddr, IO_Pin);
+ stmpe811_IO_InitPin(DeviceAddr, IO_Pin, STMPE811_DIRECTION_IN);
+ stmpe811_SetITType(DeviceAddr, STMPE811_TYPE_LEVEL);
+ stmpe811_SetITPolarity(DeviceAddr, STMPE811_POLARITY_HIGH);
+ break;
+
+ default:
+ error_code = (uint8_t) IO_Mode;
+ break;
+ }
+ return error_code;
+}
+
+/**
+ * @brief Initialize the selected IO pin direction.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO pin to be configured. This parameter could be any
+ * combination of the following values:
+ * @arg STMPE811_PIN_x: Where x can be from 0 to 7.
+ * @param Direction: could be STMPE811_DIRECTION_IN or STMPE811_DIRECTION_OUT.
+ * @retval None
+ */
+void stmpe811_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction)
+{
+ uint8_t tmp = 0;
+
+ /* Get all the Pins direction */
+ tmp = IOE_Read(DeviceAddr, STMPE811_REG_IO_DIR);
+
+ /* Set the selected pin direction */
+ if (Direction != STMPE811_DIRECTION_IN)
+ {
+ tmp |= (uint8_t)IO_Pin;
+ }
+ else
+ {
+ tmp &= ~(uint8_t)IO_Pin;
+ }
+
+ /* Write the register new value */
+ IOE_Write(DeviceAddr, STMPE811_REG_IO_DIR, tmp);
+}
+
+/**
+ * @brief Disable the AF for the selected IO pin(s).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO pin to be configured. This parameter could be any
+ * combination of the following values:
+ * @arg STMPE811_PIN_x: Where x can be from 0 to 7.
+ * @retval None
+ */
+void stmpe811_IO_DisableAF(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ uint8_t tmp = 0;
+
+ /* Get the current state of the IO_AF register */
+ tmp = IOE_Read(DeviceAddr, STMPE811_REG_IO_AF);
+
+ /* Enable the selected pins alternate function */
+ tmp |= (uint8_t)IO_Pin;
+
+ /* Write back the new value in IO AF register */
+ IOE_Write(DeviceAddr, STMPE811_REG_IO_AF, tmp);
+
+}
+
+/**
+ * @brief Enable the AF for the selected IO pin(s).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO pin to be configured. This parameter could be any
+ * combination of the following values:
+ * @arg STMPE811_PIN_x: Where x can be from 0 to 7.
+ * @retval None
+ */
+void stmpe811_IO_EnableAF(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ uint8_t tmp = 0;
+
+ /* Get the current register value */
+ tmp = IOE_Read(DeviceAddr, STMPE811_REG_IO_AF);
+
+ /* Enable the selected pins alternate function */
+ tmp &= ~(uint8_t)IO_Pin;
+
+ /* Write back the new register value */
+ IOE_Write(DeviceAddr, STMPE811_REG_IO_AF, tmp);
+}
+
+/**
+ * @brief Configure the Edge for which a transition is detectable for the
+ * selected pin.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO pin to be configured. This parameter could be any
+ * combination of the following values:
+ * @arg STMPE811_PIN_x: Where x can be from 0 to 7.
+ * @param Edge: The edge which will be detected. This parameter can be one or
+ * a combination of following values: STMPE811_EDGE_FALLING and STMPE811_EDGE_RISING .
+ * @retval None
+ */
+void stmpe811_IO_SetEdgeMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Edge)
+{
+ uint8_t tmp1 = 0, tmp2 = 0;
+
+ /* Get the current registers values */
+ tmp1 = IOE_Read(DeviceAddr, STMPE811_REG_IO_FE);
+ tmp2 = IOE_Read(DeviceAddr, STMPE811_REG_IO_RE);
+
+ /* Disable the Falling Edge */
+ tmp1 &= ~(uint8_t)IO_Pin;
+
+ /* Disable the Falling Edge */
+ tmp2 &= ~(uint8_t)IO_Pin;
+
+ /* Enable the Falling edge if selected */
+ if (Edge & STMPE811_EDGE_FALLING)
+ {
+ tmp1 |= (uint8_t)IO_Pin;
+ }
+
+ /* Enable the Rising edge if selected */
+ if (Edge & STMPE811_EDGE_RISING)
+ {
+ tmp2 |= (uint8_t)IO_Pin;
+ }
+
+ /* Write back the new registers values */
+ IOE_Write(DeviceAddr, STMPE811_REG_IO_FE, tmp1);
+ IOE_Write(DeviceAddr, STMPE811_REG_IO_RE, tmp2);
+}
+
+/**
+ * @brief Write a new IO pin state.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The output pin to be set or reset. This parameter can be one
+ * of the following values:
+ * @arg STMPE811_PIN_x: where x can be from 0 to 7.
+ * @param PinState: The new IO pin state.
+ * @retval None
+ */
+void stmpe811_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState)
+{
+ /* Apply the bit value to the selected pin */
+ if (PinState != 0)
+ {
+ /* Set the register */
+ IOE_Write(DeviceAddr, STMPE811_REG_IO_SET_PIN, (uint8_t)IO_Pin);
+ }
+ else
+ {
+ /* Set the register */
+ IOE_Write(DeviceAddr, STMPE811_REG_IO_CLR_PIN, (uint8_t)IO_Pin);
+ }
+}
+
+/**
+ * @brief Return the state of the selected IO pin(s).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The output pin to be set or reset. This parameter can be one
+ * of the following values:
+ * @arg STMPE811_PIN_x: where x can be from 0 to 7.
+ * @retval IO pin(s) state.
+ */
+uint32_t stmpe811_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ return((uint32_t)(IOE_Read(DeviceAddr, STMPE811_REG_IO_MP_STA) & (uint8_t)IO_Pin));
+}
+
+/**
+ * @brief Enable the global IO interrupt source.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void stmpe811_IO_EnableIT(uint16_t DeviceAddr)
+{
+ IOE_ITConfig();
+
+ /* Enable global IO IT source */
+ stmpe811_EnableITSource(DeviceAddr, STMPE811_GIT_IO);
+
+ /* Enable global interrupt */
+ stmpe811_EnableGlobalIT(DeviceAddr);
+}
+
+/**
+ * @brief Disable the global IO interrupt source.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void stmpe811_IO_DisableIT(uint16_t DeviceAddr)
+{
+ /* Disable the global interrupt */
+ stmpe811_DisableGlobalIT(DeviceAddr);
+
+ /* Disable global IO IT source */
+ stmpe811_DisableITSource(DeviceAddr, STMPE811_GIT_IO);
+}
+
+/**
+ * @brief Enable interrupt mode for the selected IO pin(s).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO interrupt to be enabled. This parameter could be any
+ * combination of the following values:
+ * @arg STMPE811_PIN_x: where x can be from 0 to 7.
+ * @retval None
+ */
+void stmpe811_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ uint8_t tmp = 0;
+
+ /* Get the IO interrupt state */
+ tmp = IOE_Read(DeviceAddr, STMPE811_REG_IO_INT_EN);
+
+ /* Set the interrupts to be enabled */
+ tmp |= (uint8_t)IO_Pin;
+
+ /* Write the register new value */
+ IOE_Write(DeviceAddr, STMPE811_REG_IO_INT_EN, tmp);
+}
+
+/**
+ * @brief Disable interrupt mode for the selected IO pin(s).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO interrupt to be disabled. This parameter could be any
+ * combination of the following values:
+ * @arg STMPE811_PIN_x: where x can be from 0 to 7.
+ * @retval None
+ */
+void stmpe811_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ uint8_t tmp = 0;
+
+ /* Get the IO interrupt state */
+ tmp = IOE_Read(DeviceAddr, STMPE811_REG_IO_INT_EN);
+
+ /* Set the interrupts to be Disabled */
+ tmp &= ~(uint8_t)IO_Pin;
+
+ /* Write the register new value */
+ IOE_Write(DeviceAddr, STMPE811_REG_IO_INT_EN, tmp);
+}
+
+/**
+ * @brief Check the status of the selected IO interrupt pending bit
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO interrupt to be checked could be:
+ * @arg STMPE811_PIN_x Where x can be from 0 to 7.
+ * @retval Status of the checked IO pin(s).
+ */
+uint32_t stmpe811_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ /* Get the Interrupt status */
+ return(IOE_Read(DeviceAddr, STMPE811_REG_IO_INT_STA) & (uint8_t)IO_Pin);
+}
+
+/**
+ * @brief Clear the selected IO interrupt pending bit(s).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: the IO interrupt to be cleared, could be:
+ * @arg STMPE811_PIN_x: Where x can be from 0 to 7.
+ * @retval None
+ */
+void stmpe811_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ /* Clear the global IO IT pending bit */
+ stmpe811_ClearGlobalIT(DeviceAddr, STMPE811_GIT_IO);
+
+ /* Clear the IO IT pending bit(s) */
+ IOE_Write(DeviceAddr, STMPE811_REG_IO_INT_STA, (uint8_t)IO_Pin);
+
+ /* Clear the Edge detection pending bit*/
+ IOE_Write(DeviceAddr, STMPE811_REG_IO_ED, (uint8_t)IO_Pin);
+
+ /* Clear the Rising edge pending bit */
+ IOE_Write(DeviceAddr, STMPE811_REG_IO_RE, (uint8_t)IO_Pin);
+
+ /* Clear the Falling edge pending bit */
+ IOE_Write(DeviceAddr, STMPE811_REG_IO_FE, (uint8_t)IO_Pin);
+}
+
+/**
+ * @brief Configures the touch Screen Controller (Single point detection)
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None.
+ */
+void stmpe811_TS_Start(uint16_t DeviceAddr)
+{
+ uint8_t mode;
+
+ /* Get the current register value */
+ mode = IOE_Read(DeviceAddr, STMPE811_REG_SYS_CTRL2);
+
+ /* Set the Functionalities to be Enabled */
+ mode &= ~(STMPE811_IO_FCT);
+
+ /* Write the new register value */
+ IOE_Write(DeviceAddr, STMPE811_REG_SYS_CTRL2, mode);
+
+ /* Select TSC pins in TSC alternate mode */
+ stmpe811_IO_EnableAF(DeviceAddr, STMPE811_TOUCH_IO_ALL);
+
+ /* Set the Functionalities to be Enabled */
+ mode &= ~(STMPE811_TS_FCT | STMPE811_ADC_FCT);
+
+ /* Set the new register value */
+ IOE_Write(DeviceAddr, STMPE811_REG_SYS_CTRL2, mode);
+
+ /* Select Sample Time, bit number and ADC Reference */
+ IOE_Write(DeviceAddr, STMPE811_REG_ADC_CTRL1, 0x49);
+
+ /* Wait for 2 ms */
+ IOE_Delay(2);
+
+ /* Select the ADC clock speed: 3.25 MHz */
+ IOE_Write(DeviceAddr, STMPE811_REG_ADC_CTRL2, 0x01);
+
+ /* Select 2 nF filter capacitor */
+ /* Configuration:
+ - Touch average control : 4 samples
+ - Touch delay time : 500 uS
+ - Panel driver setting time: 500 uS
+ */
+ IOE_Write(DeviceAddr, STMPE811_REG_TSC_CFG, 0x9A);
+
+ /* Configure the Touch FIFO threshold: single point reading */
+ IOE_Write(DeviceAddr, STMPE811_REG_FIFO_TH, 0x01);
+
+ /* Clear the FIFO memory content. */
+ IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x01);
+
+ /* Put the FIFO back into operation mode */
+ IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x00);
+
+ /* Set the range and accuracy pf the pressure measurement (Z) :
+ - Fractional part :7
+ - Whole part :1
+ */
+ IOE_Write(DeviceAddr, STMPE811_REG_TSC_FRACT_XYZ, 0x01);
+
+ /* Set the driving capability (limit) of the device for TSC pins: 50mA */
+ IOE_Write(DeviceAddr, STMPE811_REG_TSC_I_DRIVE, 0x01);
+
+ /* Touch screen control configuration (enable TSC):
+ - No window tracking index
+ - XYZ acquisition mode
+ */
+ IOE_Write(DeviceAddr, STMPE811_REG_TSC_CTRL, 0x01);
+
+ /* Clear all the status pending bits if any */
+ IOE_Write(DeviceAddr, STMPE811_REG_INT_STA, 0xFF);
+
+ /* Wait for 2 ms delay */
+ IOE_Delay(2);
+}
+
+/**
+ * @brief Return if there is touch detected or not.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Touch detected state.
+ */
+uint8_t stmpe811_TS_DetectTouch(uint16_t DeviceAddr)
+{
+ uint8_t state;
+ uint8_t ret = 0;
+
+ state = ((IOE_Read(DeviceAddr, STMPE811_REG_TSC_CTRL) & (uint8_t)STMPE811_TS_CTRL_STATUS) == (uint8_t)0x80);
+
+ if(state > 0)
+ {
+ if(IOE_Read(DeviceAddr, STMPE811_REG_FIFO_SIZE) > 0)
+ {
+ ret = 1;
+ }
+ }
+ else
+ {
+ /* Reset FIFO */
+ IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x01);
+ /* Enable the FIFO again */
+ IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x00);
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Get the touch screen X and Y positions values
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param X: Pointer to X position value
+ * @param Y: Pointer to Y position value
+ * @retval None.
+ */
+void stmpe811_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y)
+{
+ uint8_t dataXYZ[4];
+ uint32_t uldataXYZ;
+
+ IOE_ReadMultiple(DeviceAddr, STMPE811_REG_TSC_DATA_NON_INC, dataXYZ, sizeof(dataXYZ)) ;
+
+ /* Calculate positions values */
+ uldataXYZ = (dataXYZ[0] << 24)|(dataXYZ[1] << 16)|(dataXYZ[2] << 8)|(dataXYZ[3] << 0);
+ *X = (uldataXYZ >> 20) & 0x00000FFF;
+ *Y = (uldataXYZ >> 8) & 0x00000FFF;
+
+ /* Reset FIFO */
+ IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x01);
+ /* Enable the FIFO again */
+ IOE_Write(DeviceAddr, STMPE811_REG_FIFO_STA, 0x00);
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void stmpe811_TS_EnableIT(uint16_t DeviceAddr)
+{
+ IOE_ITConfig();
+
+ /* Enable global TS IT source */
+ stmpe811_EnableITSource(DeviceAddr, STMPE811_TS_IT);
+
+ /* Enable global interrupt */
+ stmpe811_EnableGlobalIT(DeviceAddr);
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void stmpe811_TS_DisableIT(uint16_t DeviceAddr)
+{
+ /* Disable global interrupt */
+ stmpe811_DisableGlobalIT(DeviceAddr);
+
+ /* Disable global TS IT source */
+ stmpe811_DisableITSource(DeviceAddr, STMPE811_TS_IT);
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval TS interrupts status
+ */
+uint8_t stmpe811_TS_ITStatus(uint16_t DeviceAddr)
+{
+ /* Return TS interrupts status */
+ return(stmpe811_ReadGITStatus(DeviceAddr, STMPE811_TS_IT));
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void stmpe811_TS_ClearIT(uint16_t DeviceAddr)
+{
+ /* Clear the global TS IT source */
+ stmpe811_ClearGlobalIT(DeviceAddr, STMPE811_TS_IT);
+}
+
+/**
+ * @brief Check if the device instance of the selected address is already registered
+ * and return its index
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Index of the device instance if registered, 0xFF if not.
+ */
+static uint8_t stmpe811_GetInstance(uint16_t DeviceAddr)
+{
+ uint8_t idx = 0;
+
+ /* Check all the registered instances */
+ for(idx = 0; idx < STMPE811_MAX_INSTANCE ; idx ++)
+ {
+ if(stmpe811[idx] == DeviceAddr)
+ {
+ return idx;
+ }
+ }
+
+ return 0xFF;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/stmpe811/stmpe811.h b/src/port_stm32f7/common/bsp_drivers/Components/stmpe811/stmpe811.h
new file mode 100644
index 00000000..0ef182ec
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/stmpe811/stmpe811.h
@@ -0,0 +1,289 @@
+/**
+ ******************************************************************************
+ * @file stmpe811.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for the
+ * stmpe811.c IO expander driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
ts3510.h: change "\" by "/" in the include path to fix compilation issue under Linux
+
+
+
V1.0.0 / 18-February-2014
+
+
+
+
+
+
+
+
+
Main
+Changes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
First official release of TS3510 TS component driver
+
License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/ts3510/ts3510.c b/src/port_stm32f7/common/bsp_drivers/Components/ts3510/ts3510.c
new file mode 100644
index 00000000..2c1da8bd
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/ts3510/ts3510.c
@@ -0,0 +1,254 @@
+/**
+ ******************************************************************************
+ * @file ts3510.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the TS3510
+ * IO Expander devices.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TS3510_H
+#define __TS3510_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "../Common/ts.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Component
+ * @{
+ */
+
+/** @defgroup TS3510
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/** @defgroup TS3510_Exported_Types
+ * @{
+ */
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup TS3510_Exported_Constants
+ * @{
+ */
+
+/* */
+#define TS3510_READ_BLOCK_REG 0x8A
+#define TS3510_SEND_CMD_REG 0x00
+#define TS3510_READ_CMD 0x81
+#define TS3510_WRITE_CMD 0x08
+
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+
+/** @defgroup ts3510_Exported_Macros
+ * @{
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup ts3510_Exported_Functions
+ * @{
+ */
+
+/**
+ * @brief ts3510 Control functions
+ */
+void ts3510_Init(uint16_t DeviceAddr);
+void ts3510_Reset(uint16_t DeviceAddr);
+uint16_t ts3510_ReadID(uint16_t DeviceAddr);
+void ts3510_TS_Start(uint16_t DeviceAddr);
+uint8_t ts3510_TS_DetectTouch(uint16_t DeviceAddr);
+void ts3510_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y);
+void ts3510_TS_EnableIT(uint16_t DeviceAddr);
+void ts3510_TS_DisableIT(uint16_t DeviceAddr);
+uint8_t ts3510_TS_ITStatus (uint16_t DeviceAddr);
+void ts3510_TS_ClearIT (uint16_t DeviceAddr);
+
+void IOE_Init(void);
+void IOE_Delay(uint32_t delay);
+uint8_t IOE_Read(uint8_t addr, uint8_t reg);
+uint16_t IOE_ReadMultiple(uint8_t addr, uint8_t reg, uint8_t *buffer, uint16_t length);
+void IOE_WriteMultiple(uint8_t addr, uint8_t reg, uint8_t *buffer, uint16_t length);
+
+/* Touch screen driver structure */
+extern TS_DrvTypeDef ts3510_ts_drv;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __TS3510_H */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/wm8994/Release_Notes.html b/src/port_stm32f7/common/bsp_drivers/Components/wm8994/Release_Notes.html
new file mode 100644
index 00000000..d9137a5e
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/wm8994/Release_Notes.html
@@ -0,0 +1,304 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Release Notes for WM8994 Component Driver
+
+
+
+
+
+
+
+
+
+
+
Unmute is performed in a gradual way to minimize pop noise.
Update wm8994_SetFrequency to support AUDIO_FREQUENCY_32K
Update comments to be used for PDSC generation
V2.1.0 / 22-February-2016
+
+
+
+
+
+
+
+
+
+
Main
+Changes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
wm8994.c
+
+
Update wm8994_Init() by adding the support of analog microphone connected to INPUT LINE 1, INPUT_DEVICE_DIGITAL_MICROPHONE_1 and INPUT_DEVICE_DIGITAL_MIC1_MIC2
+
Add AUDIO_FREQUENCY_32K as possible AudioFreq value
Add Audio IO de-initialization function prototype: AUDIO_IO_DeInit()
Add INPUT_DEVICE_INPUT_LINE_1 and INPUT_DEVICE_INPUT_LINE_1 support for AUDIO IN
Add Input audio volume control support
wm8994.c
Update wm8994_Init() function to support the Audio IN
Update wm8994_Stop() function to only stop the codec if it was configured
Enable VMID_BUF_ENA bit in R57 ANTIPOP register (address 0x39) for all configurations
NOTE: This release must be used with BSP Common
+driver V4.0.0 or later
V1.0.2 / 12-February-2015
+
+
+
+
+
+
+
+
Main
+Changes
+
+
+
+
+
+
+
+
+
+
+
wm8994.c: Update the wm8994_Init() function to set the volume after enabling the dynamic charge pump power control mode
V1.0.1 / 28-November-2014
+
+
+
+
+
+
+
+
Main
+Changes
+
+
+
+
+
+
+
+
+
+
+
wm8994.h: change "\" by "/" in the include path to fix compilation issue with Linux
V1.0.0 / 18-February-2014
+
+
+
+
+
+
+
+
Main
+Changes
+
+
+
+
+
+
+
+
+
+
+
First official release of WM8994 AUDIO component driver
+
License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/Components/wm8994/wm8994.c b/src/port_stm32f7/common/bsp_drivers/Components/wm8994/wm8994.c
new file mode 100644
index 00000000..44226fa4
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/Components/wm8994/wm8994.c
@@ -0,0 +1,1075 @@
+/**
+ ******************************************************************************
+ * @file wm8994.c
+ * @author MCD Application Team
+ * @brief This file provides the WM8994 Audio Codec driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
The BSP (Board Specific
+Package) drivers are parts of the STM32Cube package based on the HAL
+drivers and provide a set of high level APIs relative to the hardware
+components and features in the evaluation boards, discovery kits and nucleo
+boards coming with the STM32Cube package for a given STM32 serie.
+
The BSP drivers allow a quick access to the boards’
+services using high level APIs and without any specific configuration as the
+link with the HAL and the external components is done in intrinsic within the drivers.
+
+
From project settings points of view, user has only
+to add the necessary driver’s files in the workspace and call the needed
+functions from examples. However some low level
+configuration functions are weak and can be overridden by the applications if user
+wants to change some BSP drivers default behavior.
Update overall drivers
+by removing BSP_PPP_IRQHandler, BSP_PPP_DMA_TX_IRQHandler and BSP_PPP_DMA_RX_IRQHandler to
+avoid possible conflict when the same Handler is used by different
+IPs.
These Handlers should be
+defined by user at application level, inducing a break of compatibility versus
+V1.0.0 of the STM32F46G-Discovery BSP drivers
Update NVIC priority configuration to the lowest priority 0x0F in overall drivers
stm32f746g_discovery_camera.c:
Update BSP_CAMERA_Suspend() and BSP_CAMERA_Resume() APIs to use HAL API HAL_DCMI_Suspend() and HAL_DCMI_Resume()
stm32746g_discovery_lcd.c: Add the following APIs:
First official release
+of the STM32746G-DISCO board BSP
+drivers
+
Dependencies
+
+
+
+
+
+
+
STM32F7xx_HAL_Driver V1.2.0
+
BSP Common V4.0.1
License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery.c b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery.c
new file mode 100644
index 00000000..916e3653
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery.c
@@ -0,0 +1,902 @@
+/**
+ ******************************************************************************
+ * @file stm32746g_discovery.c
+ * @author MCD Application Team
+ * @brief This file provides a set of firmware functions to manage LEDs,
+ * push-buttons and COM ports available on STM32746G-Discovery
+ * board(MB1191) from STMicroelectronics.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32746G_DISCOVERY_H
+#define __STM32746G_DISCOVERY_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32746G_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32746G_DISCOVERY_LOW_LEVEL
+ * @{
+ */
+
+/** @defgroup STM32746G_DISCOVERY_LOW_LEVEL_Exported_Types STM32746G_DISCOVERY_LOW_LEVEL Exported Types
+ * @{
+ */
+typedef enum
+{
+LED1 = 0,
+LED_GREEN = LED1,
+}Led_TypeDef;
+
+typedef enum
+{
+ BUTTON_WAKEUP = 0,
+ BUTTON_TAMPER = 1,
+ BUTTON_KEY = 2
+}Button_TypeDef;
+
+typedef enum
+{
+ BUTTON_MODE_GPIO = 0,
+ BUTTON_MODE_EXTI = 1
+}ButtonMode_TypeDef;
+
+typedef enum
+{
+ COM1 = 0,
+ COM2 = 1
+}COM_TypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_LOW_LEVEL_Exported_Constants STM32746G_DISCOVERY_LOW_LEVEL Exported Constants
+ * @{
+ */
+
+/**
+ * @brief Define for STM32746G_DISCOVERY board
+ */
+#if !defined (USE_STM32746G_DISCO)
+ #define USE_STM32746G_DISCO
+#endif
+
+/** @addtogroup STM32746G_DISCOVERY_LOW_LEVEL_LED
+ * @{
+ */
+
+#define LEDn ((uint8_t)1)
+
+#define LED1_GPIO_PORT GPIOI
+#define LED1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define LED1_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define LED1_PIN GPIO_PIN_1
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32746G_DISCOVERY_LOW_LEVEL_BUTTON
+ * @{
+ */
+#define BUTTONn ((uint8_t)3)
+
+/**
+ * @brief Wakeup push-button
+ */
+#define WAKEUP_BUTTON_PIN GPIO_PIN_11
+#define WAKEUP_BUTTON_GPIO_PORT GPIOI
+#define WAKEUP_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define WAKEUP_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define WAKEUP_BUTTON_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @brief Tamper push-button
+ */
+#define TAMPER_BUTTON_PIN GPIO_PIN_11
+#define TAMPER_BUTTON_GPIO_PORT GPIOI
+#define TAMPER_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define TAMPER_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define TAMPER_BUTTON_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @brief Key push-button
+ */
+#define KEY_BUTTON_PIN GPIO_PIN_11
+#define KEY_BUTTON_GPIO_PORT GPIOI
+#define KEY_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define KEY_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define KEY_BUTTON_EXTI_IRQn EXTI15_10_IRQn
+
+#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == 0) WAKEUP_BUTTON_GPIO_CLK_ENABLE(); else\
+ if((__INDEX__) == 1) TAMPER_BUTTON_GPIO_CLK_ENABLE(); else\
+ KEY_BUTTON_GPIO_CLK_ENABLE(); } while(0)
+
+#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? WAKEUP_BUTTON_GPIO_CLK_DISABLE() :\
+ ((__INDEX__) == 1) ? TAMPER_BUTTON_GPIO_CLK_DISABLE() : KEY_BUTTON_GPIO_CLK_DISABLE())
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32746G_DISCOVERY_LOW_LEVEL_SIGNAL
+ * @{
+ */
+#define SIGNALn ((uint8_t)1)
+
+/**
+ * @brief SD-detect signal
+ */
+#define SD_DETECT_PIN GPIO_PIN_13
+#define SD_DETECT_GPIO_PORT GPIOC
+#define SD_DETECT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define SD_DETECT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
+#define SD_DETECT_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @brief Touch screen interrupt signal
+ */
+#define TS_INT_PIN GPIO_PIN_13
+#define TS_INT_GPIO_PORT GPIOI
+#define TS_INT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define TS_INT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define TS_INT_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32746G_DISCOVERY_LOW_LEVEL_COM
+ * @{
+ */
+#define COMn ((uint8_t)1)
+
+/**
+ * @brief Definition for COM port1, connected to USART1
+ */
+#define DISCOVERY_COM1 USART1
+#define DISCOVERY_COM1_CLK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE()
+#define DISCOVERY_COM1_CLK_DISABLE() __HAL_RCC_USART1_CLK_DISABLE()
+
+#define DISCOVERY_COM1_TX_PIN GPIO_PIN_9
+#define DISCOVERY_COM1_TX_GPIO_PORT GPIOA
+#define DISCOVERY_COM1_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define DISCOVERY_COM1_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define DISCOVERY_COM1_TX_AF GPIO_AF7_USART1
+
+#define DISCOVERY_COM1_RX_PIN GPIO_PIN_7
+#define DISCOVERY_COM1_RX_GPIO_PORT GPIOB
+#define DISCOVERY_COM1_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define DISCOVERY_COM1_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
+#define DISCOVERY_COM1_RX_AF GPIO_AF7_USART1
+
+#define DISCOVERY_COM1_IRQn USART1_IRQn
+
+#define DISCOVERY_COMx_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) DISCOVERY_COM1_CLK_ENABLE(); } while(0)
+#define DISCOVERY_COMx_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? DISCOVERY_COM1_CLK_DISABLE() : 0)
+
+#define DISCOVERY_COMx_TX_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) DISCOVERY_COM1_TX_GPIO_CLK_ENABLE(); } while(0)
+#define DISCOVERY_COMx_TX_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? DISCOVERY_COM1_TX_GPIO_CLK_DISABLE() : 0)
+
+#define DISCOVERY_COMx_RX_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) DISCOVERY_COM1_RX_GPIO_CLK_ENABLE(); } while(0)
+#define DISCOVERY_COMx_RX_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? DISCOVERY_COM1_RX_GPIO_CLK_DISABLE() : 0)
+
+/* Exported constant IO ------------------------------------------------------*/
+
+#define LCD_I2C_ADDRESS ((uint16_t)0x70)
+#define CAMERA_I2C_ADDRESS ((uint16_t)0x60)
+#define AUDIO_I2C_ADDRESS ((uint16_t)0x34)
+#define EEPROM_I2C_ADDRESS_A01 ((uint16_t)0xA0)
+#define EEPROM_I2C_ADDRESS_A02 ((uint16_t)0xA6)
+#define TS_I2C_ADDRESS ((uint16_t)0x70)
+
+/* I2C clock speed configuration (in Hz)
+ WARNING:
+ Make sure that this define is not already declared in other files (ie.
+ stm32746g_discovery.h file). It can be used in parallel by other modules. */
+#ifndef I2C_SPEED
+ #define I2C_SPEED ((uint32_t)100000)
+#endif /* I2C_SPEED */
+
+/* User can use this section to tailor I2Cx/I2Cx instance used and associated
+ resources */
+/* Definition for AUDIO and LCD I2Cx resources */
+#define DISCOVERY_AUDIO_I2Cx I2C3
+#define DISCOVERY_AUDIO_I2Cx_CLK_ENABLE() __HAL_RCC_I2C3_CLK_ENABLE()
+#define DISCOVERY_AUDIO_DMAx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
+#define DISCOVERY_AUDIO_I2Cx_SCL_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+
+#define DISCOVERY_AUDIO_I2Cx_FORCE_RESET() __HAL_RCC_I2C3_FORCE_RESET()
+#define DISCOVERY_AUDIO_I2Cx_RELEASE_RESET() __HAL_RCC_I2C3_RELEASE_RESET()
+
+/* Definition for I2Cx Pins */
+#define DISCOVERY_AUDIO_I2Cx_SCL_PIN GPIO_PIN_7
+#define DISCOVERY_AUDIO_I2Cx_SCL_SDA_GPIO_PORT GPIOH
+#define DISCOVERY_AUDIO_I2Cx_SCL_SDA_AF GPIO_AF4_I2C3
+#define DISCOVERY_AUDIO_I2Cx_SDA_PIN GPIO_PIN_8
+
+/* I2C interrupt requests */
+#define DISCOVERY_AUDIO_I2Cx_EV_IRQn I2C3_EV_IRQn
+#define DISCOVERY_AUDIO_I2Cx_ER_IRQn I2C3_ER_IRQn
+
+/* Definition for external, camera and Arduino connector I2Cx resources */
+#define DISCOVERY_EXT_I2Cx I2C1
+#define DISCOVERY_EXT_I2Cx_CLK_ENABLE() __HAL_RCC_I2C1_CLK_ENABLE()
+#define DISCOVERY_EXT_DMAx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
+#define DISCOVERY_EXT_I2Cx_SCL_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+
+#define DISCOVERY_EXT_I2Cx_FORCE_RESET() __HAL_RCC_I2C1_FORCE_RESET()
+#define DISCOVERY_EXT_I2Cx_RELEASE_RESET() __HAL_RCC_I2C1_RELEASE_RESET()
+
+/* Definition for I2Cx Pins */
+#define DISCOVERY_EXT_I2Cx_SCL_PIN GPIO_PIN_8
+#define DISCOVERY_EXT_I2Cx_SCL_SDA_GPIO_PORT GPIOB
+#define DISCOVERY_EXT_I2Cx_SCL_SDA_AF GPIO_AF4_I2C1
+#define DISCOVERY_EXT_I2Cx_SDA_PIN GPIO_PIN_9
+
+/* I2C interrupt requests */
+#define DISCOVERY_EXT_I2Cx_EV_IRQn I2C1_EV_IRQn
+#define DISCOVERY_EXT_I2Cx_ER_IRQn I2C1_ER_IRQn
+
+/* I2C TIMING Register define when I2C clock source is SYSCLK */
+/* I2C TIMING is calculated from APB1 source clock = 50 MHz */
+/* Due to the big MOFSET capacity for adapting the camera level the rising time is very large (>1us) */
+/* 0x40912732 takes in account the big rising and aims a clock of 100khz */
+#ifndef DISCOVERY_I2Cx_TIMING
+#define DISCOVERY_I2Cx_TIMING ((uint32_t)0x40912732)
+#endif /* DISCOVERY_I2Cx_TIMING */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_LOW_LEVEL_Exported_Macros STM32746G_DISCOVERY_LOW_LEVEL Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @addtogroup STM32746G_DISCOVERY_LOW_LEVEL_Exported_Functions
+ * @{
+ */
+uint32_t BSP_GetVersion(void);
+void BSP_LED_Init(Led_TypeDef Led);
+void BSP_LED_DeInit(Led_TypeDef Led);
+void BSP_LED_On(Led_TypeDef Led);
+void BSP_LED_Off(Led_TypeDef Led);
+void BSP_LED_Toggle(Led_TypeDef Led);
+void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode);
+void BSP_PB_DeInit(Button_TypeDef Button);
+uint32_t BSP_PB_GetState(Button_TypeDef Button);
+void BSP_COM_Init(COM_TypeDef COM, UART_HandleTypeDef *husart);
+void BSP_COM_DeInit(COM_TypeDef COM, UART_HandleTypeDef *huart);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32746G_DISCOVERY_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_audio.c b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_audio.c
new file mode 100644
index 00000000..4f64ebd5
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_audio.c
@@ -0,0 +1,1380 @@
+/**
+ ******************************************************************************
+ * @file stm32746g_discovery_audio.c
+ * @author MCD Application Team
+ * @brief This file provides the Audio driver for the STM32746G-Discovery board.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ + This driver supports STM32F7xx devices on STM32746G-Discovery (MB1191) board.
+ + Call the function BSP_AUDIO_OUT_Init(
+ OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER,
+ OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
+ Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
+ AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...)
+ this parameter is relative to the audio file/stream type.
+ )
+ This function configures all the hardware required for the audio application (codec, I2C, SAI,
+ GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
+ If the returned value is different from AUDIO_OK or the function is stuck then the communication with
+ the codec or the MFX has failed (try to un-plug the power or reset device in this case).
+ - OUTPUT_DEVICE_SPEAKER : only speaker will be set as output for the audio stream.
+ - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
+ - OUTPUT_DEVICE_BOTH : both Speaker and Headphone are used as outputs for the audio stream
+ at the same time.
+ Note. On STM32746G-Discovery SAI_DMA is configured in CIRCULAR mode. Due to this the application
+ does NOT need to call BSP_AUDIO_OUT_ChangeBuffer() to assure streaming.
+ + Call the function BSP_DISCOVERY_AUDIO_OUT_Play(
+ pBuffer: pointer to the audio data file address
+ Size : size of the buffer to be sent in Bytes
+ )
+ to start playing (for the first time) from the audio file/stream.
+ + Call the function BSP_AUDIO_OUT_Pause() to pause playing
+ + Call the function BSP_AUDIO_OUT_Resume() to resume playing.
+ Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
+ for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
+ Note. This function should be called only when the audio file is played or paused (not stopped).
+ + For each mode, you may need to implement the relative callback functions into your code.
+ The Callback functions are named AUDIO_OUT_XXX_CallBack() and only their prototypes are declared in
+ the stm32746g_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
+ + To Stop playing, to modify the volume level, the frequency, the audio frame slot,
+ the device output mode the mute or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(),
+ AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetAudioFrameSlot(), BSP_AUDIO_OUT_SetOutputMode(),
+ BSP_AUDIO_OUT_SetMute() and BSP_AUDIO_OUT_Stop().
+ + The driver API and the callback functions are at the end of the stm32746g_discovery_audio.h file.
+
+ Driver architecture:
+ --------------------
+ + This driver provides the High Audio Layer: consists of the function API exported in the stm32746g_discovery_audio.h file
+ (BSP_AUDIO_OUT_Init(), BSP_AUDIO_OUT_Play() ...)
+ + This driver provide also the Media Access Layer (MAL): which consists of functions allowing to access the media containing/
+ providing the audio file/stream. These functions are also included as local functions into
+ the stm32746g_discovery_audio_codec.c file (SAIx_Out_Init() and SAIx_Out_DeInit(), SAIx_In_Init() and SAIx_In_DeInit())
+
+ Known Limitations:
+ ------------------
+ 1- If the TDM Format used to play in parallel 2 audio Stream (the first Stream is configured in codec SLOT0 and second
+ Stream in SLOT1) the Pause/Resume, volume and mute feature will control the both streams.
+ 2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size,
+ File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
+ 3- Supports only Stereo audio streaming.
+ 4- Supports only 16-bits audio data size.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32746G_DISCOVERY_AUDIO_H
+#define __STM32746G_DISCOVERY_AUDIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include audio component Driver */
+#include "../Components/wm8994/wm8994.h"
+#include "stm32746g_discovery.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32746G_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32746G_DISCOVERY_AUDIO STM32746G_DISCOVERY_AUDIO
+ * @{
+ */
+
+/** @defgroup STM32746G_DISCOVERY_AUDIO_Exported_Types STM32746G_DISCOVERY_AUDIO Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_AUDIO_Exported_Constants STM32746G_DISCOVERY_AUDIO Exported Constants
+ * @{
+ */
+
+/*------------------------------------------------------------------------------
+ USER SAI defines parameters
+ -----------------------------------------------------------------------------*/
+/* CODEC_AudioFrame_SLOT_TDMMode
+ In W8994 codec the Audio frame contains 4 slots : TDM Mode
+ TDM format :
+ +------------------|------------------|--------------------|-------------------+
+ | CODEC_SLOT0 Left | CODEC_SLOT1 Left | CODEC_SLOT0 Right | CODEC_SLOT1 Right |
+ +------------------------------------------------------------------------------+
+ */
+/* To have 2 separate audio stream in Both headphone and speaker the 4 slot must be activated */
+#define CODEC_AUDIOFRAME_SLOT_0123 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_2 | SAI_SLOTACTIVE_3
+/* To have an audio stream in headphone only SAI Slot 0 and Slot 2 must be activated */
+#define CODEC_AUDIOFRAME_SLOT_02 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_2
+/* To have an audio stream in speaker only SAI Slot 1 and Slot 3 must be activated */
+#define CODEC_AUDIOFRAME_SLOT_13 SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_3
+
+/* SAI OUT peripheral configuration defines */
+#define AUDIO_OUT_SAIx SAI2_Block_A
+#define AUDIO_OUT_SAIx_CLK_ENABLE() __HAL_RCC_SAI2_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_CLK_DISABLE() __HAL_RCC_SAI2_CLK_DISABLE()
+#define AUDIO_OUT_SAIx_SCK_AF GPIO_AF10_SAI2
+#define AUDIO_OUT_SAIx_FS_SD_MCLK_AF GPIO_AF10_SAI2
+
+#define AUDIO_OUT_SAIx_MCLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_MCLK_GPIO_PORT GPIOI
+#define AUDIO_OUT_SAIx_MCLK_PIN GPIO_PIN_4
+#define AUDIO_OUT_SAIx_SCK_SD_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT GPIOI
+#define AUDIO_OUT_SAIx_SCK_PIN GPIO_PIN_5
+#define AUDIO_OUT_SAIx_SD_PIN GPIO_PIN_6
+#define AUDIO_OUT_SAIx_FS_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_FS_GPIO_PORT GPIOI
+#define AUDIO_OUT_SAIx_FS_PIN GPIO_PIN_7
+
+/* SAI DMA Stream definitions */
+#define AUDIO_OUT_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_DMAx_STREAM DMA2_Stream4
+#define AUDIO_OUT_SAIx_DMAx_CHANNEL DMA_CHANNEL_3
+#define AUDIO_OUT_SAIx_DMAx_IRQ DMA2_Stream4_IRQn
+#define AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
+#define AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
+#define DMA_MAX_SZE ((uint16_t)0xFFFF)
+
+#define AUDIO_OUT_SAIx_DMAx_IRQHandler DMA2_Stream4_IRQHandler
+
+/* Select the interrupt preemption priority for the DMA interrupt */
+#define AUDIO_OUT_IRQ_PREPRIO ((uint32_t)0x0E) /* Select the preemption priority level(0 is the highest) */
+
+/*------------------------------------------------------------------------------
+ AUDIO IN CONFIGURATION
+------------------------------------------------------------------------------*/
+/* SAI IN peripheral configuration defines */
+#define AUDIO_IN_SAIx SAI2_Block_B
+#define AUDIO_IN_SAIx_CLK_ENABLE() __HAL_RCC_SAI2_CLK_ENABLE()
+#define AUDIO_IN_SAIx_CLK_DISABLE() __HAL_RCC_SAI2_CLK_DISABLE()
+#define AUDIO_IN_SAIx_SD_AF GPIO_AF10_SAI2
+
+#define AUDIO_IN_SAIx_SD_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
+#define AUDIO_IN_SAIx_SD_GPIO_PORT GPIOG
+#define AUDIO_IN_SAIx_SD_PIN GPIO_PIN_10
+
+#define AUDIO_IN_INT_GPIO_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+#define AUDIO_IN_INT_GPIO_PORT GPIOH
+#define AUDIO_IN_INT_GPIO_PIN GPIO_PIN_15
+#define AUDIO_IN_INT_IRQ EXTI15_10_IRQn
+
+/* SAI DMA Stream definitions */
+#define AUDIO_IN_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
+#define AUDIO_IN_SAIx_DMAx_STREAM DMA2_Stream7
+#define AUDIO_IN_SAIx_DMAx_CHANNEL DMA_CHANNEL_0
+#define AUDIO_IN_SAIx_DMAx_IRQ DMA2_Stream7_IRQn
+#define AUDIO_IN_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
+#define AUDIO_IN_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
+
+#define AUDIO_IN_SAIx_DMAx_IRQHandler DMA2_Stream7_IRQHandler
+#define AUDIO_IN_INT_IRQHandler EXTI15_10_IRQHandler
+
+/* Select the interrupt preemption priority and subpriority for the IT/DMA interrupt */
+#define AUDIO_IN_IRQ_PREPRIO ((uint32_t)0x0F) /* Select the preemption priority level(0 is the highest) */
+
+/*------------------------------------------------------------------------------
+ CONFIGURATION: Audio Driver Configuration parameters
+------------------------------------------------------------------------------*/
+
+#define AUDIODATA_SIZE ((uint16_t)2) /* 16-bits audio data size */
+
+/* Audio status definition */
+#define AUDIO_OK ((uint8_t)0)
+#define AUDIO_ERROR ((uint8_t)1)
+#define AUDIO_TIMEOUT ((uint8_t)2)
+
+/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */
+#define DEFAULT_AUDIO_IN_FREQ I2S_AUDIOFREQ_16K
+#define DEFAULT_AUDIO_IN_BIT_RESOLUTION ((uint8_t)16)
+#define DEFAULT_AUDIO_IN_CHANNEL_NBR ((uint8_t)2) /* Mono = 1, Stereo = 2 */
+#define DEFAULT_AUDIO_IN_VOLUME ((uint16_t)64)
+
+/*------------------------------------------------------------------------------
+ OPTIONAL Configuration defines parameters
+------------------------------------------------------------------------------*/
+
+/* Delay for the Codec to be correctly reset */
+#define CODEC_RESET_DELAY ((uint8_t)5)
+
+
+/*------------------------------------------------------------------------------
+ OUTPUT DEVICES definition
+------------------------------------------------------------------------------*/
+/* Alias on existing output devices to adapt for 2 headphones output */
+#define OUTPUT_DEVICE_HEADPHONE1 OUTPUT_DEVICE_HEADPHONE
+#define OUTPUT_DEVICE_HEADPHONE2 OUTPUT_DEVICE_SPEAKER /* Headphone2 is connected to Speaker output of the wm8994 */
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_AUDIO_Exported_Variables STM32746G_DISCOVERY_AUDIO Exported Variables
+ * @{
+ */
+extern __IO uint16_t AudioInVolume;
+ /**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_AUDIO_Exported_Macros STM32746G_DISCOVERY_AUDIO Exported Macros
+ * @{
+ */
+#define DMA_MAX(x) (((x) <= DMA_MAX_SZE)? (x):DMA_MAX_SZE)
+/**
+ * @}
+ */
+
+/** @addtogroup STM32746G_DISCOVERY_AUDIO_OUT_Exported_Functions
+ * @{
+ */
+uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq);
+uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size);
+void BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size);
+uint8_t BSP_AUDIO_OUT_Pause(void);
+uint8_t BSP_AUDIO_OUT_Resume(void);
+uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option);
+uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume);
+void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq);
+void BSP_AUDIO_OUT_SetAudioFrameSlot(uint32_t AudioFrameSlot);
+uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd);
+uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output);
+void BSP_AUDIO_OUT_DeInit(void);
+
+/* User Callbacks: user has to implement these functions in his code if they are needed. */
+/* This function is called when the requested data has been completely transferred.*/
+void BSP_AUDIO_OUT_TransferComplete_CallBack(void);
+
+/* This function is called when half of the requested buffer has been transferred. */
+void BSP_AUDIO_OUT_HalfTransfer_CallBack(void);
+
+/* This function is called when an Interrupt due to transfer error on or peripheral
+ error occurs. */
+void BSP_AUDIO_OUT_Error_CallBack(void);
+
+/* These function can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_AUDIO_OUT_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params);
+void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params);
+void BSP_AUDIO_OUT_MspDeInit(SAI_HandleTypeDef *hsai, void *Params);
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_AUDIO_IN_Exported_Functions STM32746G_DISCOVERY_AUDIO_IN Exported Functions
+ * @{
+ */
+uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_InitEx(uint16_t InputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_OUT_Init(uint16_t InputDevice, uint16_t OutputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_Record(uint16_t *pData, uint32_t Size);
+uint8_t BSP_AUDIO_IN_Stop(uint32_t Option);
+uint8_t BSP_AUDIO_IN_Pause(void);
+uint8_t BSP_AUDIO_IN_Resume(void);
+uint8_t BSP_AUDIO_IN_SetVolume(uint8_t Volume);
+void BSP_AUDIO_IN_DeInit(void);
+/* User Callbacks: user has to implement these functions in his code if they are needed. */
+/* This function should be implemented by the user application.
+ It is called into this driver when the current buffer is filled to prepare the next
+ buffer pointer and its size. */
+void BSP_AUDIO_IN_TransferComplete_CallBack(void);
+void BSP_AUDIO_IN_HalfTransfer_CallBack(void);
+
+/* This function is called when an Interrupt due to transfer error on or peripheral
+ error occurs. */
+void BSP_AUDIO_IN_Error_CallBack(void);
+
+/* These function can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_AUDIO_IN_MspInit(SAI_HandleTypeDef *hsai, void *Params);
+void BSP_AUDIO_IN_MspDeInit(SAI_HandleTypeDef *hsai, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32746G_DISCOVERY_AUDIO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_camera.c b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_camera.c
new file mode 100644
index 00000000..e73977c8
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_camera.c
@@ -0,0 +1,659 @@
+/**
+ ******************************************************************************
+ * @file stm32746g_discovery_camera.c
+ * @author MCD Application Team
+ * @brief This file includes the driver for Camera modules mounted on
+ * STM32746G-Discovery board.
+ @verbatim
+ How to use this driver:
+ ------------------------
+ - This driver is used to drive the camera.
+ - The OV9655 component driver MUST be included with this driver.
+
+ Driver description:
+ -------------------
+ + Initialization steps:
+ o Initialize the camera using the BSP_CAMERA_Init() function.
+ o Start the camera capture/snapshot using the CAMERA_Start() function.
+ o Suspend, resume or stop the camera capture using the following functions:
+ - BSP_CAMERA_Suspend()
+ - BSP_CAMERA_Resume()
+ - BSP_CAMERA_Stop()
+
+ + Options
+ o Increase or decrease on the fly the brightness and/or contrast
+ using the following function:
+ - BSP_CAMERA_ContrastBrightnessConfig
+ o Add a special effect on the fly using the following functions:
+ - BSP_CAMERA_BlackWhiteConfig()
+ - BSP_CAMERA_ColorEffectConfig()
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32746G_DISCOVERY_CAMERA_H
+#define __STM32746G_DISCOVERY_CAMERA_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include Camera component Driver */
+#include "../Components/ov9655/ov9655.h"
+#include "stm32746g_discovery.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32746G_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32746G_DISCOVERY_CAMERA
+ * @{
+ */
+
+/** @defgroup STM32746G_DISCOVERY_CAMERA_Exported_Types STM32746G_DISCOVERY_CAMERA Exported Types
+ * @{
+ */
+
+/**
+ * @brief Camera State structures definition
+ */
+typedef enum
+{
+ CAMERA_OK = 0x00,
+ CAMERA_ERROR = 0x01,
+ CAMERA_TIMEOUT = 0x02,
+ CAMERA_NOT_DETECTED = 0x03,
+ CAMERA_NOT_SUPPORTED = 0x04
+
+} Camera_StatusTypeDef;
+
+#define RESOLUTION_R160x120 CAMERA_R160x120 /* QQVGA Resolution */
+#define RESOLUTION_R320x240 CAMERA_R320x240 /* QVGA Resolution */
+#define RESOLUTION_R480x272 CAMERA_R480x272 /* 480x272 Resolution */
+#define RESOLUTION_R640x480 CAMERA_R640x480 /* VGA Resolution */
+/**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_CAMERA_Exported_Constants STM32746G_DISCOVERY_CAMERA Exported Constants
+ * @{
+ */
+#define BSP_CAMERA_IRQHandler DCMI_IRQHandler
+#define BSP_CAMERA_DMA_IRQHandler DMA2_Stream1_IRQHandler
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32746G_DISCOVERY_CAMERA_Exported_Functions
+ * @{
+ */
+uint8_t BSP_CAMERA_Init(uint32_t Resolution);
+uint8_t BSP_CAMERA_DeInit(void);
+void BSP_CAMERA_ContinuousStart(uint8_t *buff);
+void BSP_CAMERA_SnapshotStart(uint8_t *buff);
+void BSP_CAMERA_Suspend(void);
+void BSP_CAMERA_Resume(void);
+uint8_t BSP_CAMERA_Stop(void);
+void BSP_CAMERA_PwrUp(void);
+void BSP_CAMERA_PwrDown(void);
+void BSP_CAMERA_LineEventCallback(void);
+void BSP_CAMERA_VsyncEventCallback(void);
+void BSP_CAMERA_FrameEventCallback(void);
+void BSP_CAMERA_ErrorCallback(void);
+
+/* Camera features functions prototype */
+void BSP_CAMERA_ContrastBrightnessConfig(uint32_t contrast_level, uint32_t brightness_level);
+void BSP_CAMERA_BlackWhiteConfig(uint32_t Mode);
+void BSP_CAMERA_ColorEffectConfig(uint32_t Effect);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_CAMERA_MspInit(DCMI_HandleTypeDef *hdcmi, void *Params);
+void BSP_CAMERA_MspDeInit(DCMI_HandleTypeDef *hdcmi, void *Params);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32746G_DISCOVERY_CAMERA_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_eeprom.c b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_eeprom.c
new file mode 100644
index 00000000..4c4871c8
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_eeprom.c
@@ -0,0 +1,477 @@
+/**
+ ******************************************************************************
+ * @file stm32746g_discovery_eeprom.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage an I2C M24LR64
+ * EEPROM memory.
+ @verbatim
+ To be able to use this driver, the switch EE_M24LR64 must be defined
+ in your toolchain compiler preprocessor
+
+ ===================================================================
+ Notes:
+ - The I2C EEPROM memory (M24LR64) is available on separate daughter
+ board ANT7-M24LR-A, which is not provided with the STM32746G_DISCOVERY
+ board.
+ To use this driver you have to connect the ANT7-M24LR-A to CN3
+ connector of STM32746G_DISCOVERY board.
+ ===================================================================
+
+ It implements a high level communication layer for read and write
+ from/to this memory. The needed STM32F7xx hardware resources (I2C and
+ GPIO) are defined in stm32746g_discovery.h file, and the initialization is
+ performed in EEPROM_IO_Init() function declared in stm32746g_discovery.c
+ file.
+ You can easily tailor this driver to any other development board,
+ by just adapting the defines for hardware resources and
+ EEPROM_IO_Init() function.
+
+ @note In this driver, basic read and write functions (BSP_EEPROM_ReadBuffer()
+ and BSP_EEPROM_WritePage()) use DMA mode to perform the data
+ transfer to/from EEPROM memory.
+
+ @note Regarding BSP_EEPROM_WritePage(), it is an optimized function to perform
+ small write (less than 1 page) BUT the number of bytes (combined to write start address) must not
+ cross the EEPROM page boundary. This function can only writes into
+ the boundaries of an EEPROM page.
+ This function doesn't check on boundaries condition (in this driver
+ the function BSP_EEPROM_WriteBuffer() which calls BSP_EEPROM_WritePage() is
+ responsible of checking on Page boundaries).
+
+
+ +-----------------------------------------------------------------+
+ | Pin assignment for M24LR64 EEPROM |
+ +---------------------------------------+-----------+-------------+
+ | STM32F7xx I2C Pins | EEPROM | Pin |
+ +---------------------------------------+-----------+-------------+
+ | . | E0(GND) | 1 (0V) |
+ | . | AC0 | 2 |
+ | . | AC1 | 3 |
+ | . | VSS | 4 (0V) |
+ | SDA | SDA | 5 |
+ | SCL | SCL | 6 |
+ | . | E1(GND) | 7 (0V) |
+ | . | VDD | 8 (3.3V) |
+ +---------------------------------------+-----------+-------------+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Dependencies
+- stm32746g_discovery.c
+EndDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32746g_discovery_eeprom.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32746G_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32746G_DISCOVERY_EEPROM
+ * @brief This file includes the I2C EEPROM driver of STM32746G-Discovery board.
+ * @{
+ */
+
+/** @defgroup STM32746G_DISCOVERY_EEPROM_Private_Types STM32746G_DISCOVERY_EEPROM Private Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_EEPROM_Private_Defines STM32746G_DISCOVERY_EEPROM Private Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_EEPROM_Private_Macros STM32746G_DISCOVERY_EEPROM Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_EEPROM_Private_Variables STM32746G_DISCOVERY_EEPROM Private Variables
+ * @{
+ */
+__IO uint16_t EEPROMAddress = 0;
+__IO uint16_t EEPROMDataRead;
+__IO uint8_t EEPROMDataWrite;
+/**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_EEPROM_Private_Function_Prototypes STM32746G_DISCOVERY_EEPROM Private Function Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_EEPROM_Exported_Functions STM32746G_DISCOVERY_EEPROM Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes peripherals used by the I2C EEPROM driver.
+ *
+ * @note There are 2 different versions of M24LR64 (A01 & A02).
+ * Then try to connect on 1st one (EEPROM_I2C_ADDRESS_A01)
+ * and if problem, check the 2nd one (EEPROM_I2C_ADDRESS_A02)
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0)
+ */
+uint32_t BSP_EEPROM_Init(void)
+{
+ /* I2C Initialization */
+ EEPROM_IO_Init();
+
+ /* Select the EEPROM address for A01 and check if OK */
+ EEPROMAddress = EEPROM_I2C_ADDRESS_A01;
+ if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
+ {
+ /* Select the EEPROM address for A02 and check if OK */
+ EEPROMAddress = EEPROM_I2C_ADDRESS_A02;
+ if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
+ {
+ return EEPROM_FAIL;
+ }
+ }
+ return EEPROM_OK;
+}
+
+/**
+ * @brief DeInitializes the EEPROM.
+ * @retval EEPROM state
+ */
+uint8_t BSP_EEPROM_DeInit(void)
+{
+ /* I2C won't be disabled because common to other functionalities */
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Reads a block of data from the EEPROM.
+ * @param pBuffer: pointer to the buffer that receives the data read from
+ * the EEPROM.
+ * @param ReadAddr: EEPROM's internal address to start reading from.
+ * @param NumByteToRead: pointer to the variable holding number of bytes to
+ * be read from the EEPROM.
+ *
+ * @note The variable pointed by NumByteToRead is reset to 0 when all the
+ * data are read from the EEPROM. Application should monitor this
+ * variable in order know when the transfer is complete.
+ *
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
+{
+ uint32_t buffersize = *NumByteToRead;
+
+ /* Set the pointer to the Number of data to be read. This pointer will be used
+ by the DMA Transfer Completer interrupt Handler in order to reset the
+ variable to 0. User should check on this variable in order to know if the
+ DMA transfer has been complete or not. */
+ EEPROMDataRead = *NumByteToRead;
+
+ if(EEPROM_IO_ReadData(EEPROMAddress, ReadAddr, pBuffer, buffersize) != HAL_OK)
+ {
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ return EEPROM_FAIL;
+ }
+
+ /* If all operations OK, return EEPROM_OK (0) */
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Writes more than one byte to the EEPROM with a single WRITE cycle.
+ *
+ * @note The number of bytes (combined to write start address) must not
+ * cross the EEPROM page boundary. This function can only write into
+ * the boundaries of an EEPROM page.
+ * This function doesn't check on boundaries condition (in this driver
+ * the function BSP_EEPROM_WriteBuffer() which calls BSP_EEPROM_WritePage() is
+ * responsible of checking on Page boundaries).
+ *
+ * @param pBuffer: pointer to the buffer containing the data to be written to
+ * the EEPROM.
+ * @param WriteAddr: EEPROM's internal address to write to.
+ * @param NumByteToWrite: pointer to the variable holding number of bytes to
+ * be written into the EEPROM.
+ *
+ * @note The variable pointed by NumByteToWrite is reset to 0 when all the
+ * data are written to the EEPROM. Application should monitor this
+ * variable in order know when the transfer is complete.
+ *
+ * @note This function just configure the communication and enable the DMA
+ * channel to transfer data. Meanwhile, the user application may perform
+ * other tasks in parallel.
+ *
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite)
+{
+ uint32_t buffersize = *NumByteToWrite;
+ uint32_t status = EEPROM_OK;
+
+ /* Set the pointer to the Number of data to be written. This pointer will be used
+ by the DMA Transfer Completer interrupt Handler in order to reset the
+ variable to 0. User should check on this variable in order to know if the
+ DMA transfer has been complete or not. */
+ EEPROMDataWrite = *NumByteToWrite;
+
+ if(EEPROM_IO_WriteData(EEPROMAddress, WriteAddr, pBuffer, buffersize) != HAL_OK)
+ {
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ status = EEPROM_FAIL;
+ }
+
+ if(BSP_EEPROM_WaitEepromStandbyState() != EEPROM_OK)
+ {
+ return EEPROM_FAIL;
+ }
+
+ /* If all operations OK, return EEPROM_OK (0) */
+ return status;
+}
+
+/**
+ * @brief Writes buffer of data to the I2C EEPROM.
+ * @param pBuffer: pointer to the buffer containing the data to be written
+ * to the EEPROM.
+ * @param WriteAddr: EEPROM's internal address to write to.
+ * @param NumByteToWrite: number of bytes to write to the EEPROM.
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_WriteBuffer(uint8_t *pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
+{
+ uint16_t numofpage = 0, numofsingle = 0, count = 0;
+ uint16_t addr = 0;
+ uint8_t dataindex = 0;
+ uint32_t status = EEPROM_OK;
+
+ addr = WriteAddr % EEPROM_PAGESIZE;
+ count = EEPROM_PAGESIZE - addr;
+ numofpage = NumByteToWrite / EEPROM_PAGESIZE;
+ numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
+
+ /* If WriteAddr is EEPROM_PAGESIZE aligned */
+ if(addr == 0)
+ {
+ /* If NumByteToWrite < EEPROM_PAGESIZE */
+ if(numofpage == 0)
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ /* Start writing data */
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ /* If NumByteToWrite > EEPROM_PAGESIZE */
+ else
+ {
+ while(numofpage--)
+ {
+ /* Store the number of data to be written */
+ dataindex = EEPROM_PAGESIZE;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+
+ WriteAddr += EEPROM_PAGESIZE;
+ pBuffer += EEPROM_PAGESIZE;
+ }
+
+ if(numofsingle!=0)
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ }
+ }
+ /* If WriteAddr is not EEPROM_PAGESIZE aligned */
+ else
+ {
+ /* If NumByteToWrite < EEPROM_PAGESIZE */
+ if(numofpage== 0)
+ {
+ /* If the number of data to be written is more than the remaining space
+ in the current page: */
+ if(NumByteToWrite > count)
+ {
+ /* Store the number of data to be written */
+ dataindex = count;
+ /* Write the data contained in same page */
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+
+ /* Store the number of data to be written */
+ dataindex = (NumByteToWrite - count);
+ /* Write the remaining data in the following page */
+ status = BSP_EEPROM_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ else
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ }
+ /* If NumByteToWrite > EEPROM_PAGESIZE */
+ else
+ {
+ NumByteToWrite -= count;
+ numofpage = NumByteToWrite / EEPROM_PAGESIZE;
+ numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
+
+ if(count != 0)
+ {
+ /* Store the number of data to be written */
+ dataindex = count;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ WriteAddr += count;
+ pBuffer += count;
+ }
+
+ while(numofpage--)
+ {
+ /* Store the number of data to be written */
+ dataindex = EEPROM_PAGESIZE;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ WriteAddr += EEPROM_PAGESIZE;
+ pBuffer += EEPROM_PAGESIZE;
+ }
+ if(numofsingle != 0)
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ }
+ }
+
+ /* If all operations OK, return EEPROM_OK (0) */
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Wait for EEPROM Standby state.
+ *
+ * @note This function allows to wait and check that EEPROM has finished the
+ * last operation. It is mostly used after Write operation: after receiving
+ * the buffer to be written, the EEPROM may need additional time to actually
+ * perform the write operation. During this time, it doesn't answer to
+ * I2C packets addressed to it. Once the write operation is complete
+ * the EEPROM responds to its address.
+ *
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_WaitEepromStandbyState(void)
+{
+ /* Check if the maximum allowed number of trials has bee reached */
+ if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
+ {
+ /* If the maximum number of trials has been reached, exit the function */
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ return EEPROM_TIMEOUT;
+ }
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Basic management of the timeout situation.
+ * @retval None
+ */
+__weak void BSP_EEPROM_TIMEOUT_UserCallback(void)
+{
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_eeprom.h b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_eeprom.h
new file mode 100644
index 00000000..20c4cf31
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_eeprom.h
@@ -0,0 +1,138 @@
+/**
+ ******************************************************************************
+ * @file stm32746g_discovery_eeprom.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for
+ * the stm32746g_discovery_eeprom.c firmware driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32746G_DISCOVERY_EEPROM_H
+#define __STM32746G_DISCOVERY_EEPROM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32746g_discovery.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32746G_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32746G_DISCOVERY_EEPROM
+ * @brief This file includes the I2C EEPROM driver of STM32746G-Discovery board.
+ * @{
+ */
+
+/** @defgroup STM32746G_DISCOVERY_EEPROM_Exported_Types STM32746G_DISCOVERY_EEPROM Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_EEPROM_Exported_Constants STM32746G_DISCOVERY_EEPROM Exported Constants
+ * @{
+ */
+/* EEPROM hardware address and page size */
+#define EEPROM_PAGESIZE ((uint8_t)4)
+#define EEPROM_MAX_SIZE ((uint16_t)0x2000) /* 64Kbit */
+
+
+/* Maximum number of trials for EEPROM_WaitEepromStandbyState() function */
+#define EEPROM_MAX_TRIALS ((uint32_t)3000)
+
+#define EEPROM_OK ((uint32_t)0)
+#define EEPROM_FAIL ((uint32_t)1)
+#define EEPROM_TIMEOUT ((uint32_t)2)
+/**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_EEPROM_Exported_Macros STM32746G_DISCOVERY_EEPROM Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @addtogroup STM32746G_DISCOVERY_EEPROM_Exported_Functions
+ * @{
+ */
+uint32_t BSP_EEPROM_Init(void);
+uint8_t BSP_EEPROM_DeInit(void);
+uint32_t BSP_EEPROM_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead);
+uint32_t BSP_EEPROM_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite);
+uint32_t BSP_EEPROM_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite);
+uint32_t BSP_EEPROM_WaitEepromStandbyState(void);
+
+/* USER Callbacks: This function is declared as __weak in EEPROM driver and
+ should be implemented into user application.
+ BSP_EEPROM_TIMEOUT_UserCallback() function is called whenever a timeout condition
+ occurs during communication (waiting on an event that doesn't occur, bus
+ errors, busy devices ...). */
+void BSP_EEPROM_TIMEOUT_UserCallback(void);
+
+/* Link function for I2C EEPROM peripheral */
+void EEPROM_IO_Init(void);
+HAL_StatusTypeDef EEPROM_IO_WriteData(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef EEPROM_IO_ReadData(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef EEPROM_IO_IsDeviceReady(uint16_t DevAddress, uint32_t Trials);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32746G_DISCOVERY_EEPROM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_lcd.c b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_lcd.c
new file mode 100644
index 00000000..527f3aac
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_lcd.c
@@ -0,0 +1,1663 @@
+/**
+ ******************************************************************************
+ * @file stm32746g_discovery_lcd.c
+ * @author MCD Application Team
+ * @brief This file includes the driver for Liquid Crystal Display (LCD) module
+ * mounted on STM32746G-Discovery board.
+ @verbatim
+ 1. How To use this driver:
+ --------------------------
+ - This driver is used to drive directly an LCD TFT using the LTDC controller.
+ - This driver uses timing and setting for RK043FN48H LCD.
+
+ 2. Driver description:
+ ---------------------
+ + Initialization steps:
+ o Initialize the LCD using the BSP_LCD_Init() function.
+ o Apply the Layer configuration using the BSP_LCD_LayerDefaultInit() function.
+ o Select the LCD layer to be used using the BSP_LCD_SelectLayer() function.
+ o Enable the LCD display using the BSP_LCD_DisplayOn() function.
+
+ + Options
+ o Configure and enable the color keying functionality using the
+ BSP_LCD_SetColorKeying() function.
+ o Modify in the fly the transparency and/or the frame buffer address
+ using the following functions:
+ - BSP_LCD_SetTransparency()
+ - BSP_LCD_SetLayerAddress()
+
+ + Display on LCD
+ o Clear the hole LCD using BSP_LCD_Clear() function or only one specified string
+ line using the BSP_LCD_ClearStringLine() function.
+ o Display a character on the specified line and column using the BSP_LCD_DisplayChar()
+ function or a complete string line using the BSP_LCD_DisplayStringAtLine() function.
+ o Display a string line on the specified position (x,y in pixel) and align mode
+ using the BSP_LCD_DisplayStringAtLine() function.
+ o Draw and fill a basic shapes (dot, line, rectangle, circle, ellipse, .. bitmap)
+ on LCD using the available set of functions.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32746G_DISCOVERY
+ * @{
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32746G_DISCOVERY_QSPI_H
+#define __STM32746G_DISCOVERY_QSPI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+#include "../Components/n25q128a/n25q128a.h"
+
+/** @addtogroup STM32746G_DISCOVERY_QSPI
+ * @{
+ */
+
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup STM32746G_DISCOVERY_QSPI_Exported_Constants STM32746G_DISCOVERY_QSPI Exported Constants
+ * @{
+ */
+/* QSPI Error codes */
+#define QSPI_OK ((uint8_t)0x00)
+#define QSPI_ERROR ((uint8_t)0x01)
+#define QSPI_BUSY ((uint8_t)0x02)
+#define QSPI_NOT_SUPPORTED ((uint8_t)0x04)
+#define QSPI_SUSPENDED ((uint8_t)0x08)
+
+
+/* Definition for QSPI clock resources */
+#define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE()
+#define QSPI_CLK_DISABLE() __HAL_RCC_QSPI_CLK_DISABLE()
+#define QSPI_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define QSPI_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define QSPI_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
+#define QSPI_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
+#define QSPI_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
+#define QSPI_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
+
+#define QSPI_FORCE_RESET() __HAL_RCC_QSPI_FORCE_RESET()
+#define QSPI_RELEASE_RESET() __HAL_RCC_QSPI_RELEASE_RESET()
+
+/* Definition for QSPI Pins */
+#define QSPI_CS_PIN GPIO_PIN_6
+#define QSPI_CS_GPIO_PORT GPIOB
+#define QSPI_CLK_PIN GPIO_PIN_2
+#define QSPI_CLK_GPIO_PORT GPIOB
+#define QSPI_D0_PIN GPIO_PIN_11
+#define QSPI_D0_GPIO_PORT GPIOD
+#define QSPI_D1_PIN GPIO_PIN_12
+#define QSPI_D1_GPIO_PORT GPIOD
+#define QSPI_D2_PIN GPIO_PIN_2
+#define QSPI_D2_GPIO_PORT GPIOE
+#define QSPI_D3_PIN GPIO_PIN_13
+#define QSPI_D3_GPIO_PORT GPIOD
+
+/* N25Q128A13EF840E Micron memory */
+/* Size of the flash */
+#define QSPI_FLASH_SIZE 23 /* Address bus width to access whole memory space */
+#define QSPI_PAGE_SIZE 256
+
+/* This alias is added as the name of Memory mapped fucntion changed */
+#define BSP_QSPI_MemoryMappedMode BSP_QSPI_EnableMemoryMappedMode
+/**
+ * @}
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup STM32746G_DISCOVERY_QSPI_Exported_Types STM32746G_DISCOVERY_QSPI Exported Types
+ * @{
+ */
+/* QSPI Info */
+typedef struct {
+ uint32_t FlashSize; /*!< Size of the flash */
+ uint32_t EraseSectorSize; /*!< Size of sectors for the erase operation */
+ uint32_t EraseSectorsNumber; /*!< Number of sectors for the erase operation */
+ uint32_t ProgPageSize; /*!< Size of pages for the program operation */
+ uint32_t ProgPagesNumber; /*!< Number of pages for the program operation */
+} QSPI_Info;
+
+/**
+ * @}
+ */
+
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup STM32746G_DISCOVERY_QSPI_Exported_Functions
+ * @{
+ */
+uint8_t BSP_QSPI_Init (void);
+uint8_t BSP_QSPI_DeInit (void);
+uint8_t BSP_QSPI_Read (uint8_t* pData, uint32_t ReadAddr, uint32_t Size);
+uint8_t BSP_QSPI_Write (uint8_t* pData, uint32_t WriteAddr, uint32_t Size);
+uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress);
+uint8_t BSP_QSPI_Erase_Chip (void);
+uint8_t BSP_QSPI_GetStatus (void);
+uint8_t BSP_QSPI_GetInfo (QSPI_Info* pInfo);
+uint8_t BSP_QSPI_EnableMemoryMappedMode(void);
+
+/* These functions can be modified in case the current settings
+ need to be changed for specific application needs */
+void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params);
+void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32746G_DISCOVERY_QSPI_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_sd.c b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_sd.c
new file mode 100644
index 00000000..e5f686c0
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_sd.c
@@ -0,0 +1,606 @@
+/**
+ ******************************************************************************
+ * @file stm32746g_discovery_sd.c
+ * @author MCD Application Team
+ * @brief This file includes the uSD card driver mounted on STM32746G-Discovery
+ * board.
+ @verbatim
+ 1. How To use this driver:
+ --------------------------
+ - This driver is used to drive the micro SD external card mounted on STM32746G-Discovery
+ board.
+ - This driver does not need a specific component driver for the micro SD device
+ to be included with.
+
+ 2. Driver description:
+ ---------------------
+ + Initialization steps:
+ o Initialize the micro SD card using the BSP_SD_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ SDIO interface configuration to interface with the external micro SD. It
+ also includes the micro SD initialization sequence.
+ o To check the SD card presence you can use the function BSP_SD_IsDetected() which
+ returns the detection status
+ o If SD presence detection interrupt mode is desired, you must configure the
+ SD detection interrupt mode by calling the function BSP_SD_ITConfig(). The interrupt
+ is generated as an external interrupt whenever the micro SD card is
+ plugged/unplugged in/from the board.
+ o The function BSP_SD_GetCardInfo() is used to get the micro SD card information
+ which is stored in the structure "HAL_SD_CardInfoTypedef".
+
+ + Micro SD card operations
+ o The micro SD card can be accessed with read/write block(s) operations once
+ it is ready for access. The access can be performed whether using the polling
+ mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks(), or by DMA
+ transfer using the functions BSP_SD_ReadBlocks_DMA()/BSP_SD_WriteBlocks_DMA()
+ o The DMA transfer complete is used with interrupt mode. Once the SD transfer
+ is complete, the SD interrupt is handled using the function BSP_SD_IRQHandler(),
+ the DMA Tx/Rx transfer complete are handled using the functions
+ BSP_SD_DMA_Tx_IRQHandler()/BSP_SD_DMA_Rx_IRQHandler(). The corresponding user callbacks
+ are implemented by the user at application level.
+ o The SD erase block(s) is performed using the function BSP_SD_Erase() with specifying
+ the number of blocks to erase.
+ o The SD runtime status is returned when calling the function BSP_SD_GetCardState().
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32746G_DISCOVERY_SD_H
+#define __STM32746G_DISCOVERY_SD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32746g_discovery.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32746G_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32746G_DISCOVERY_SD
+ * @{
+ */
+
+/** @defgroup STM32746G_DISCOVERY_SD_Exported_Types STM32746G_DISCOVERY_SD Exported Types
+ * @{
+ */
+
+/**
+ * @brief SD Card information structure
+ */
+#define BSP_SD_CardInfo HAL_SD_CardInfoTypeDef
+/**
+ * @}
+ */
+
+/**
+ * @brief SD status structure definition
+ */
+#define MSD_OK ((uint8_t)0x00)
+#define MSD_ERROR ((uint8_t)0x01)
+#define MSD_ERROR_SD_NOT_PRESENT ((uint8_t)0x02)
+
+/**
+ * @brief SD transfer state definition
+ */
+#define SD_TRANSFER_OK ((uint8_t)0x00)
+#define SD_TRANSFER_BUSY ((uint8_t)0x01)
+
+/** @defgroup STM32746G_DISCOVERY_SD_Exported_Constants STM32746G_DISCOVERY_SD Exported Constants
+ * @{
+ */
+#define SD_PRESENT ((uint8_t)0x01)
+#define SD_NOT_PRESENT ((uint8_t)0x00)
+
+#define SD_DATATIMEOUT ((uint32_t)100000000)
+
+/* DMA definitions for SD DMA transfer */
+#define __DMAx_TxRx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
+#define SD_DMAx_Tx_CHANNEL DMA_CHANNEL_4
+#define SD_DMAx_Rx_CHANNEL DMA_CHANNEL_4
+#define SD_DMAx_Tx_STREAM DMA2_Stream6
+#define SD_DMAx_Rx_STREAM DMA2_Stream3
+#define SD_DMAx_Tx_IRQn DMA2_Stream6_IRQn
+#define SD_DMAx_Rx_IRQn DMA2_Stream3_IRQn
+#define BSP_SDMMC_IRQHandler SDMMC1_IRQHandler
+#define BSP_SDMMC_DMA_Tx_IRQHandler DMA2_Stream6_IRQHandler
+#define BSP_SDMMC_DMA_Rx_IRQHandler DMA2_Stream3_IRQHandler
+#define SD_DetectIRQHandler() HAL_GPIO_EXTI_IRQHandler(SD_DETECT_PIN)
+/**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_SD_Exported_Macro STM32746G_DISCOVERY_SD Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @addtogroup STM32746G_DISCOVERY_SD_Exported_Functions
+ * @{
+ */
+uint8_t BSP_SD_Init(void);
+uint8_t BSP_SD_DeInit(void);
+uint8_t BSP_SD_ITConfig(void);
+uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout);
+uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout);
+uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks);
+uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks);
+uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr);
+uint8_t BSP_SD_GetCardState(void);
+void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypeDef *CardInfo);
+uint8_t BSP_SD_IsDetected(void);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params);
+void BSP_SD_Detect_MspInit(SD_HandleTypeDef *hsd, void *Params);
+void BSP_SD_MspDeInit(SD_HandleTypeDef *hsd, void *Params);
+void BSP_SD_AbortCallback(void);
+void BSP_SD_WriteCpltCallback(void);
+void BSP_SD_ReadCpltCallback(void);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32746G_DISCOVERY_SD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_sdram.c b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_sdram.c
new file mode 100644
index 00000000..80e4370a
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_sdram.c
@@ -0,0 +1,497 @@
+/**
+ ******************************************************************************
+ * @file stm32746g_discovery_sdram.c
+ * @author MCD Application Team
+ * @brief This file includes the SDRAM driver for the MT48LC4M32B2B5-7 memory
+ * device mounted on STM32746G-Discovery board.
+ @verbatim
+ 1. How To use this driver:
+ --------------------------
+ - This driver is used to drive the MT48LC4M32B2B5-7 SDRAM external memory mounted
+ on STM32746G-Discovery board.
+ - This driver does not need a specific component driver for the SDRAM device
+ to be included with.
+
+ 2. Driver description:
+ ---------------------
+ + Initialization steps:
+ o Initialize the SDRAM external memory using the BSP_SDRAM_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ FMC controller configuration to interface with the external SDRAM memory.
+ o It contains the SDRAM initialization sequence to program the SDRAM external
+ device using the function BSP_SDRAM_Initialization_sequence(). Note that this
+ sequence is standard for all SDRAM devices, but can include some differences
+ from a device to another. If it is the case, the right sequence should be
+ implemented separately.
+
+ + SDRAM read/write operations
+ o SDRAM external memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_SDRAM_ReadData()/BSP_SDRAM_WriteData(), or by DMA transfer using the functions
+ BSP_SDRAM_ReadData_DMA()/BSP_SDRAM_WriteData_DMA().
+ o The AHB access is performed with 32-bit width transaction, the DMA transfer
+ configuration is fixed at single (no burst) word transfer (see the
+ SDRAM_MspInit() static function).
+ o User can implement his own functions for read/write access with his desired
+ configurations.
+ o If interrupt mode is used for DMA transfer, the function BSP_SDRAM_DMA_IRQHandler()
+ is called in IRQ handler file, to serve the generated interrupt once the DMA
+ transfer is complete.
+ o You can send a command to the SDRAM device in runtime using the function
+ BSP_SDRAM_Sendcmd(), and giving the desired command as parameter chosen between
+ the predefined commands of the "FMC_SDRAM_CommandTypeDef" structure.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32746G_DISCOVERY_SDRAM_H
+#define __STM32746G_DISCOVERY_SDRAM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32746G_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32746G_DISCOVERY_SDRAM
+ * @{
+ */
+
+/** @defgroup STM32746G_DISCOVERY_SDRAM_Exported_Types STM32746G_DISCOVERY_SDRAM Exported Types
+ * @{
+ */
+
+/**
+ * @brief SDRAM status structure definition
+ */
+#define SDRAM_OK ((uint8_t)0x00)
+#define SDRAM_ERROR ((uint8_t)0x01)
+
+/** @defgroup STM32746G_DISCOVERY_SDRAM_Exported_Constants STM32746G_DISCOVERY_SDRAM Exported Constants
+ * @{
+ */
+#define SDRAM_DEVICE_ADDR ((uint32_t)0xC0000000)
+#define SDRAM_DEVICE_SIZE ((uint32_t)0x800000) /* SDRAM device size in MBytes */
+
+/* #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_8 */
+#define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16
+
+#define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_2
+/* #define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_3 */
+
+#define REFRESH_COUNT ((uint32_t)0x0603) /* SDRAM refresh counter (100Mhz SD clock) */
+
+#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
+
+/* DMA definitions for SDRAM DMA transfer */
+#define __DMAx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
+#define __DMAx_CLK_DISABLE __HAL_RCC_DMA2_CLK_DISABLE
+#define SDRAM_DMAx_CHANNEL DMA_CHANNEL_0
+#define SDRAM_DMAx_STREAM DMA2_Stream0
+#define SDRAM_DMAx_IRQn DMA2_Stream0_IRQn
+#define BSP_SDRAM_DMA_IRQHandler DMA2_Stream0_IRQHandler
+/**
+ * @}
+ */
+
+/**
+ * @brief FMC SDRAM Mode definition register defines
+ */
+#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
+#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
+#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
+#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
+#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
+#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
+#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
+#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
+#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
+#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
+#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
+/**
+ * @}
+ */
+
+/** @defgroup STM32746G_DISCOVERY_SDRAM_Exported_Macro STM32746G_DISCOVERY_SDRAM Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @addtogroup STM32746G_DISCOVERY_SDRAM_Exported_Functions
+ * @{
+ */
+uint8_t BSP_SDRAM_Init(void);
+uint8_t BSP_SDRAM_DeInit(void);
+void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount);
+uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram, void *Params);
+void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram, void *Params);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32746G_DISCOVERY_SDRAM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_ts.c b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_ts.c
new file mode 100644
index 00000000..3bcc5617
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32746G-Discovery/stm32746g_discovery_ts.c
@@ -0,0 +1,450 @@
+/**
+ ******************************************************************************
+ * @file stm32746g_discovery_ts.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the Touch
+ * Screen on STM32746G-Discovery board.
+ @verbatim
+ 1. How To use this driver:
+ --------------------------
+ - This driver is used to drive the touch screen module of the STM32746G-Discovery
+ board on the RK043FN48H-CT672B 480x272 LCD screen with capacitive touch screen.
+ - The FT5336 component driver must be included in project files according to
+ the touch screen driver present on this board.
+
+ 2. Driver description:
+ ---------------------
+ + Initialization steps:
+ o Initialize the TS module using the BSP_TS_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ communication layer configuration to start the TS use. The LCD size properties
+ (x and y) are passed as parameters.
+ o If TS interrupt mode is desired, you must configure the TS interrupt mode
+ by calling the function BSP_TS_ITConfig(). The TS interrupt mode is generated
+ as an external interrupt whenever a touch is detected.
+ The interrupt mode internally uses the IO functionalities driver driven by
+ the IO expander, to configure the IT line.
+
+ + Touch screen use
+ o The touch screen state is captured whenever the function BSP_TS_GetState() is
+ used. This function returns information about the last LCD touch occurred
+ in the TS_StateTypeDef structure.
+ o If TS interrupt mode is used, the function BSP_TS_ITGetStatus() is needed to get
+ the interrupt status. To clear the IT pending bits, you should call the
+ function BSP_TS_ITClear().
+ o The IT is handled using the corresponding external interrupt IRQ handler,
+ the user IT callback treatment is implemented on the same external interrupt
+ callback.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+This software component is licensed by ST under BSD 3-Clause license, the “License”; You may not use this component except in compliance with the License. You may obtain a copy of the License at:
+
The BSP (Board Specific Package) drivers are parts of the STM32Cube package based on the HAL drivers and provide a set of high level APIs relative to the hardware components and features in the evaluation boards, discovery kits and nucleo boards coming with the STM32Cube package for a given STM32 serie.
+
The BSP drivers allow a quick access to the boards’ services using high level APIs and without any specific configuration as the link with the HAL and the external components is done in intrinsic within the drivers.
+
From project settings points of view, user has only to add the necessary driver’s files in the workspace and call the needed functions from examples. However some low level configuration functions are weak and can be overridden by the applications if user wants to change some BSP drivers default behavior.
+
+
+
Update History
+
+
+
+
Main Changes
+
+
stm32756g_eval_camera.c/.h:
+
+
Support ov5640 camera sensor
+
+
stm32756g_eval.c/.h:
+
+
Add OV5640 I2C address
+
Update CAMERA IO Read/Write to support ov5640 camera sensor
+
+
stm32756g_eval_nor.c:
+
+
Support MT28EW128ABA1LPC NOR Flash
+
+
+
+
+
+
+
+
Main Changes
+
+
stm32756g_eval_audio.c:
+
+
Aligned with PDM library v3.0.0
+
+
+
Dependencies
+
+
This version must be used with v3.0.0 of PDM library
+
+
+
+
+
+
+
Main Changes
+
+
stm32756g_eval_lcd.c:
+
+
Fix compilation errors with SW4STM32 toolchain.
+
+
stm32756g_eval.c:
+
+
Upgrade version to v2.0.2
+
+
+
+
+
+
+
+
Main Changes
+
+
Add general description of BSP drivers
+
Add Dependencies section
+
Support of PDSC
+
+
+
+
+
+
+
Main Changes
+
+
stm32756g_eval_sd.c/.h:
+
+
Update BSP SD APIs following new HAL SD drivers implementation
+
Fix BlockSize to 512 bytes
+
+
stm32756g_eval_ts.c/.h:
+
+
Update TS_INT_PIN define
+
+
stm32756g_eval_lcd.c/.h:
+
+
Update BSP_LCD_ReadPixel to read correctly ARGB8888 and RGB888 pixels
+
+
stm32756g_eval_qspi.c/.h:
+
+
QSPI write operation improvement
+
Update CS High Time
+
+
+
Backward compatibility
+
+
These BSP drivers break the compatibility with previous versions.
+
+
Dependencies
+
+
If FatFs is required, “FatFS R0.11 ST modified 20161223” must be used with this version of BSP drivers.
+
+
+
+
+
+
+
Main Changes
+
+
Update typos in drivers comments.
+
+
+
+
+
+
+
Main Changes
+
+
Update overall drivers by removing BSP_PPP_IRQHandler, BSP_PPP_DMA_TX_IRQHandler and BSP_PPP_DMA_RX_IRQHandler to avoid possible conflict when the same Handler is used by different IPs.
+
These Handlers should be defined by user at application level, inducing a break of compatibility versus V1.0.1 of the STM32756G-EVAL BSP drivers
+
Add new functions BSP_POTENTIOMETER_Init() and BSP_POTENTIOMETER_GetLevel()
+
Update NVIC priority configuration to the lowest priority 0x0F
+
stm32756g_eval_lcd.c: Add the following APIs:
+
+
BSP_LCD_SetTransparency_NoReload()
+
BSP_LCD_SetLayerAddress_NoReload()
+
BSP_LCD_SetColorKeying_NoReload()
+
BSP_LCD_ResetColorKeying_NoReload()
+
BSP_LCD_SetLayerWindow_NoReload()
+
BSP_LCD_SetLayerVisible_NoReload()
+
BSP_LCD_Reload()
+
+
stm32756g_eval_camera.c:
+
+
Update BSP_CAMERA_Suspend() and BSP_CAMERA_Resume() APIs to use HAL API HAL_DCMI_Suspend() and HAL_DCMI_Resume()
+
+
+
+
+
+
+
+
Main Changes
+
+
stm32756g_eval.c
+
+
Add AUDIO_IO_DeInit() function to be compatible with common version 4.0.0 or later
+
+
+
+
+
+
+
+
Main Changes
+
+
First official release of the STM32756G-EVAL and STM32746G-EVAL BSP drivers
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32756G_EVAL_H
+#define __STM32756G_EVAL_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* USE_STM32756G_EVAL_REVA must USE USE_IOEXPANDER */
+#if defined(USE_STM32756G_EVAL_REVA)
+#ifndef USE_IOEXPANDER
+#define USE_IOEXPANDER
+#endif /* USE_IOEXPANDER */
+#endif /* USE_STM32756G_EVAL_REVA */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL_LOW_LEVEL
+ * @{
+ */
+
+/** @defgroup STM32756G_EVAL_LOW_LEVEL_Exported_Types LEVEL Exported Types
+ * @{
+ */
+typedef enum
+{
+#if defined(USE_IOEXPANDER)
+LED1 = 0,
+LED_GREEN = LED1,
+LED2 = 1,
+LED_ORANGE = LED2,
+LED3 = 2,
+LED_RED = LED3,
+LED4 = 3,
+LED_BLUE = LED4
+#else
+LED1 = 0,
+LED_GREEN = LED1,
+LED3 = 1,
+LED_RED = LED3,
+#endif /* USE_IOEXPANDER */
+}Led_TypeDef;
+
+typedef enum
+{
+ BUTTON_WAKEUP = 0,
+ BUTTON_TAMPER = 1,
+ BUTTON_KEY = 2
+}Button_TypeDef;
+
+typedef enum
+{
+ BUTTON_MODE_GPIO = 0,
+ BUTTON_MODE_EXTI = 1
+}ButtonMode_TypeDef;
+
+#if defined(USE_IOEXPANDER)
+typedef enum
+{
+ JOY_MODE_GPIO = 0,
+ JOY_MODE_EXTI = 1
+}JOYMode_TypeDef;
+
+typedef enum
+{
+ JOY_NONE = 0,
+ JOY_SEL = 1,
+ JOY_DOWN = 2,
+ JOY_LEFT = 3,
+ JOY_RIGHT = 4,
+ JOY_UP = 5
+}JOYState_TypeDef;
+#endif /* USE_IOEXPANDER */
+
+typedef enum
+{
+ COM1 = 0,
+ COM2 = 1
+}COM_TypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_LOW_LEVEL_Exported_Constants LOW LEVEL Exported Constants
+ * @{
+ */
+
+/**
+ * @brief Define for STM32756G_EVAL board
+ */
+#if !defined (USE_STM32756G_EVAL)
+ #define USE_STM32756G_EVAL
+#endif
+
+/** @addtogroup STM32756G_EVAL_LOW_LEVEL_LED
+ * @{
+ */
+
+#if !defined(USE_STM32756G_EVAL_REVA)
+
+#if defined(USE_IOEXPANDER)
+#define LEDn ((uint8_t)4)
+#define LED2_PIN IO_PIN_17
+#define LED4_PIN IO_PIN_19
+#else
+#define LEDn ((uint8_t)2)
+#endif /* USE_IOEXPANDER */
+
+#define LED1_GPIO_PORT GPIOF
+#define LED1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
+#define LED1_GPIO_CLK_DISABLE() __HAL_RCC_GPIOF_CLK_DISABLE()
+#define LED1_PIN GPIO_PIN_10 /* To use LED1, ensure that JP24 is in position 2-3, potentiometer is then no more usable */
+
+#define LED3_GPIO_PORT GPIOB
+#define LED3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define LED3_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
+#define LED3_PIN GPIO_PIN_7 /* To use LED3, ensure that JP23 is in position 2-3, camera is then no more usable */
+
+#else
+
+#define LEDn ((uint8_t)4)
+#define LED1_PIN IO_PIN_16
+#define LED2_PIN IO_PIN_17
+#define LED3_PIN IO_PIN_18
+#define LED4_PIN IO_PIN_19
+
+#endif /* !USE_STM32756G_EVAL_REVA */
+
+/**
+ * @}
+ */
+
+/**
+ * @brief MFX_IRQOUt pin
+ */
+#define MFX_IRQOUT_PIN GPIO_PIN_8
+#define MFX_IRQOUT_GPIO_PORT GPIOI
+#define MFX_IRQOUT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define MFX_IRQOUT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define MFX_IRQOUT_EXTI_IRQn EXTI9_5_IRQn
+
+/** @addtogroup STM32756G_EVAL_LOW_LEVEL_BUTTON
+ * @{
+ */
+/* Joystick pins are connected to IO Expander (accessible through I2C1 interface) */
+#define BUTTONn ((uint8_t)3)
+
+/**
+ * @brief Wakeup push-button
+ */
+#define WAKEUP_BUTTON_PIN GPIO_PIN_13
+#define WAKEUP_BUTTON_GPIO_PORT GPIOC
+#define WAKEUP_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define WAKEUP_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
+#define WAKEUP_BUTTON_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @brief Tamper push-button
+ */
+#define TAMPER_BUTTON_PIN GPIO_PIN_13
+#define TAMPER_BUTTON_GPIO_PORT GPIOC
+#define TAMPER_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define TAMPER_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
+#define TAMPER_BUTTON_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @brief Key push-button
+ */
+#define KEY_BUTTON_PIN GPIO_PIN_13
+#define KEY_BUTTON_GPIO_PORT GPIOC
+#define KEY_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define KEY_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
+#define KEY_BUTTON_EXTI_IRQn EXTI15_10_IRQn
+
+#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == 0) WAKEUP_BUTTON_GPIO_CLK_ENABLE(); else\
+ if((__INDEX__) == 1) TAMPER_BUTTON_GPIO_CLK_ENABLE(); else\
+ KEY_BUTTON_GPIO_CLK_ENABLE(); } while(0)
+
+#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? WAKEUP_BUTTON_GPIO_CLK_DISABLE() :\
+ ((__INDEX__) == 1) ? TAMPER_BUTTON_GPIO_CLK_DISABLE() : KEY_BUTTON_GPIO_CLK_DISABLE())
+/**
+ * @}
+ */
+
+/** @addtogroup STM32756G_EVAL_LOW_LEVEL_COM
+ * @{
+ */
+#define COMn ((uint8_t)1)
+
+/**
+ * @brief Definition for COM port1, connected to USART1
+ */
+#define EVAL_COM1 USART1
+#define EVAL_COM1_CLK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE()
+#define EVAL_COM1_CLK_DISABLE() __HAL_RCC_USART1_CLK_DISABLE()
+
+#define EVAL_COM1_TX_PIN GPIO_PIN_9
+#define EVAL_COM1_TX_GPIO_PORT GPIOA
+#define EVAL_COM1_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define EVAL_COM1_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define EVAL_COM1_TX_AF GPIO_AF7_USART1
+
+#define EVAL_COM1_RX_PIN GPIO_PIN_10
+#define EVAL_COM1_RX_GPIO_PORT GPIOA
+#define EVAL_COM1_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define EVAL_COM1_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define EVAL_COM1_RX_AF GPIO_AF7_USART1
+
+#define EVAL_COM1_IRQn USART1_IRQn
+
+#define EVAL_COMx_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) EVAL_COM1_CLK_ENABLE(); } while(0)
+#define EVAL_COMx_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? EVAL_COM1_CLK_DISABLE() : 0)
+
+#define EVAL_COMx_TX_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) EVAL_COM1_TX_GPIO_CLK_ENABLE(); } while(0)
+#define EVAL_COMx_TX_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? EVAL_COM1_TX_GPIO_CLK_DISABLE() : 0)
+
+#define EVAL_COMx_RX_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) EVAL_COM1_RX_GPIO_CLK_ENABLE(); } while(0)
+#define EVAL_COMx_RX_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? EVAL_COM1_RX_GPIO_CLK_DISABLE() : 0)
+
+/**
+ * @brief Definition for Potentiometer, connected to ADC3
+ */
+#define ADCx ADC3
+#define ADCx_CLK_ENABLE() __HAL_RCC_ADC3_CLK_ENABLE()
+#define ADCx_CHANNEL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
+
+#define ADCx_FORCE_RESET() __HAL_RCC_ADC_FORCE_RESET()
+#define ADCx_RELEASE_RESET() __HAL_RCC_ADC_RELEASE_RESET()
+
+/* Definition for ADCx Channel Pin */
+#define ADCx_CHANNEL_PIN GPIO_PIN_10
+#define ADCx_CHANNEL_GPIO_PORT GPIOF
+
+/* Definition for ADCx's Channel */
+#define ADCx_CHANNEL ADC_CHANNEL_8
+#define SAMPLINGTIME ADC_SAMPLETIME_3CYCLES
+#define ADCx_POLL_TIMEOUT 10
+
+/**
+ * @brief Joystick Pins definition
+ */
+#if defined(USE_IOEXPANDER)
+#define JOY_SEL_PIN IO_PIN_0
+#define JOY_DOWN_PIN IO_PIN_1
+#define JOY_LEFT_PIN IO_PIN_2
+#define JOY_RIGHT_PIN IO_PIN_3
+#define JOY_UP_PIN IO_PIN_4
+#define JOY_NONE_PIN JOY_ALL_PINS
+#define JOY_ALL_PINS (IO_PIN_0 | IO_PIN_1 | IO_PIN_2 | IO_PIN_3 | IO_PIN_4)
+#endif /* USE_IOEXPANDER */
+/**
+ * @brief Eval Pins definition connected to MFX
+ */
+
+#if defined(USE_IOEXPANDER)
+#define XSDN_PIN IO_PIN_10
+#define MII_INT_PIN IO_PIN_13
+#define RSTI_PIN IO_PIN_11
+#define CAM_PLUG_PIN IO_PIN_12
+#define LCD_INT_PIN IO_PIN_14
+#define AUDIO_INT_PIN IO_PIN_5
+#define OTG_FS1_OVER_CURRENT_PIN IO_PIN_6
+#define OTG_FS1_POWER_SWITCH_PIN IO_PIN_7
+#define OTG_FS2_OVER_CURRENT_PIN IO_PIN_8
+#define OTG_FS2_POWER_SWITCH_PIN IO_PIN_9
+#define SD_DETECT_PIN IO_PIN_15
+
+#endif /* USE_IOEXPANDER */
+
+
+/* Exported constant IO ------------------------------------------------------*/
+
+/* The MFX_I2C_ADDR input pin selects the MFX I2C device address
+ MFX_I2C_ADDR input pin MFX I2C device address
+ 0 b: 1000 010x (0x84)
+ 1 b: 1000 011x (0x86)
+ This input is sampled during the MFX firmware startup. */
+#define IO_I2C_ADDRESS ((uint16_t)0x84) /*mfx MFX_I2C_ADDR 0*/
+#define IO_I2C_ADDRESS_2 ((uint16_t)0x86) /*mfx MFX_I2C_ADDR 1*/
+#define TS_I2C_ADDRESS ((uint16_t)0x82) /*stmpe811 used on MB1046 board */
+#define TS3510_I2C_ADDRESS ((uint16_t)0x80)
+#define EXC7200_I2C_ADDRESS ((uint16_t)0x08)
+#define CAMERA_I2C_ADDRESS ((uint16_t)0x5A)
+#define CAMERA_I2C_ADDRESS_2 ((uint16_t)0x78)
+#define AUDIO_I2C_ADDRESS ((uint16_t)0x34)
+#define EEPROM_I2C_ADDRESS_A01 ((uint16_t)0xA0)
+#define EEPROM_I2C_ADDRESS_A02 ((uint16_t)0xA6)
+/* I2C clock speed configuration (in Hz)
+ WARNING:
+ Make sure that this define is not already declared in other files (ie.
+ stm32756G_eval.h file). It can be used in parallel by other modules. */
+#ifndef I2C_SPEED
+ #define I2C_SPEED ((uint32_t)100000)
+#endif /* I2C_SPEED */
+
+/* User can use this section to tailor I2Cx/I2Cx instance used and associated
+ resources */
+/* Definition for I2Cx clock resources */
+#define EVAL_I2Cx I2C1
+#define EVAL_I2Cx_CLK_ENABLE() __HAL_RCC_I2C1_CLK_ENABLE()
+#define EVAL_DMAx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
+#define EVAL_I2Cx_SCL_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+
+#define EVAL_I2Cx_FORCE_RESET() __HAL_RCC_I2C1_FORCE_RESET()
+#define EVAL_I2Cx_RELEASE_RESET() __HAL_RCC_I2C1_RELEASE_RESET()
+
+/* Definition for I2Cx Pins */
+#define EVAL_I2Cx_SCL_PIN GPIO_PIN_8
+#define EVAL_I2Cx_SCL_SDA_GPIO_PORT GPIOB
+#define EVAL_I2Cx_SCL_SDA_AF GPIO_AF4_I2C1
+#define EVAL_I2Cx_SDA_PIN GPIO_PIN_9
+
+/* I2C interrupt requests */
+#define EVAL_I2Cx_EV_IRQn I2C1_EV_IRQn
+#define EVAL_I2Cx_ER_IRQn I2C1_ER_IRQn
+
+/* I2C TIMING Register define when I2C clock source is SYSCLK */
+/* I2C TIMING is calculated from APB1 source clock = 50 MHz */
+/* Due to the big MOFSET capacity for adapting the camera level the rising time is very large (>1us) */
+/* 0x40912732 takes in account the big rising and aims a clock of 100khz */
+#ifndef EVAL_I2Cx_TIMING
+#define EVAL_I2Cx_TIMING ((uint32_t)0x40912732)
+#endif /* EVAL_I2Cx_TIMING */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_LOW_LEVEL_Exported_Macros LOW LEVEL Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_LOW_LEVEL_Exported_Functions LOW LEVEL Exported Functions
+ * @{
+ */
+uint32_t BSP_GetVersion(void);
+void BSP_LED_Init(Led_TypeDef Led);
+void BSP_LED_DeInit(Led_TypeDef Led);
+void BSP_LED_On(Led_TypeDef Led);
+void BSP_LED_Off(Led_TypeDef Led);
+void BSP_LED_Toggle(Led_TypeDef Led);
+void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode);
+void BSP_PB_DeInit(Button_TypeDef Button);
+uint32_t BSP_PB_GetState(Button_TypeDef Button);
+void BSP_COM_Init(COM_TypeDef COM, UART_HandleTypeDef *husart);
+void BSP_COM_DeInit(COM_TypeDef COM, UART_HandleTypeDef *huart);
+void BSP_POTENTIOMETER_Init(void);
+uint32_t BSP_POTENTIOMETER_GetLevel(void);
+#if defined(USE_IOEXPANDER)
+uint8_t BSP_JOY_Init(JOYMode_TypeDef JoyMode);
+void BSP_JOY_DeInit(void);
+JOYState_TypeDef BSP_JOY_GetState(void);
+uint8_t BSP_TS3510_IsDetected(void);
+#endif /* USE_IOEXPANDER */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32756G_EVAL_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_audio.c b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_audio.c
new file mode 100644
index 00000000..54e7a99e
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_audio.c
@@ -0,0 +1,1396 @@
+/**
+ ******************************************************************************
+ * @file stm32756g_eval_audio.c
+ * @author MCD Application Team
+ * @brief This file provides the Audio driver for the STM32756G-EVAL and
+ * STM32746G_EVAL evaluation board.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ + This driver supports STM32F7xx devices on STM32756G-EVAL (MB1167) Evaluation boards.
+ + Call the function BSP_AUDIO_OUT_Init(
+ OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER,
+ OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
+ Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
+ AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...)
+ this parameter is relative to the audio file/stream type.
+ )
+ This function configures all the hardware required for the audio application (codec, I2C, SAI,
+ GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
+ If the returned value is different from AUDIO_OK or the function is stuck then the communication with
+ the codec or the MFX has failed (try to un-plug the power or reset device in this case).
+ - OUTPUT_DEVICE_SPEAKER : only speaker will be set as output for the audio stream.
+ - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
+ - OUTPUT_DEVICE_BOTH : both Speaker and Headphone are used as outputs for the audio stream
+ at the same time.
+ Note. On STM32756G-EVAL SAI_DMA is configured in CIRCULAR mode. Due to this the application
+ does NOT need to call BSP_AUDIO_OUT_ChangeBuffer() to assure streaming.
+ + Call the function BSP_EVAL_AUDIO_OUT_Play(
+ pBuffer: pointer to the audio data file address
+ Size : size of the buffer to be sent in Bytes
+ )
+ to start playing (for the first time) from the audio file/stream.
+ + Call the function BSP_AUDIO_OUT_Pause() to pause playing
+ + Call the function BSP_AUDIO_OUT_Resume() to resume playing.
+ Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
+ for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
+ Note. This function should be called only when the audio file is played or paused (not stopped).
+ + For each mode, you may need to implement the relative callback functions into your code.
+ The Callback functions are named AUDIO_OUT_XXX_CallBack() and only their prototypes are declared in
+ the stm32756g_eval_audio.h file. (refer to the example for more details on the callbacks implementations)
+ + To Stop playing, to modify the volume level, the frequency, the audio frame slot,
+ the device output mode the mute or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(),
+ AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetAudioFrameSlot(), BSP_AUDIO_OUT_SetOutputMode(),
+ BSP_AUDIO_OUT_SetMute() and BSP_AUDIO_OUT_Stop().
+ + The driver API and the callback functions are at the end of the stm32756g_eval_audio.h file.
+
+ Driver architecture:
+ --------------------
+ + This driver provides the High Audio Layer: consists of the function API exported in the stm32756g_eval_audio.h file
+ (BSP_AUDIO_OUT_Init(), BSP_AUDIO_OUT_Play() ...)
+ + This driver provide also the Media Access Layer (MAL): which consists of functions allowing to access the media containing/
+ providing the audio file/stream. These functions are also included as local functions into
+ the stm32756g_eval_audio.c file (I2Sx_Init(), I2Sx_DeInit(), SAIx_Init() and SAIx_DeInit())
+
+ Known Limitations:
+ ------------------
+ 1- If the TDM Format used to play in parallel 2 audio Stream (the first Stream is configured in codec SLOT0 and second
+ Stream in SLOT1) the Pause/Resume, volume and mute feature will control the both streams.
+ 2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size,
+ File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
+ 3- Supports only Stereo audio streaming.
+ 4- Supports only 16-bits audio data size.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32756G_EVAL_AUDIO_H
+#define __STM32756G_EVAL_AUDIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include audio component Driver */
+#include "../Components/wm8994/wm8994.h"
+#include "stm32756g_eval.h"
+#include "../../../Middlewares/ST/STM32_Audio/Addons/PDM/Inc/pdm2pcm_glo.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL_AUDIO STM32756G_EVAL AUDIO
+ * @{
+ */
+
+/** @defgroup STM32756G_EVAL_AUDIO_Exported_Types STM32756G_EVAL_AUDIO Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_AUDIO_Exported_Constants STM32756G_EVAL_AUDIO Exported Constants
+ * @{
+ */
+
+/*------------------------------------------------------------------------------
+ USER SAI defines parameters
+ -----------------------------------------------------------------------------*/
+/** CODEC_AudioFrame_SLOT_TDMMode In W8994 codec the Audio frame contains 4 slots : TDM Mode
+ * TDM format :
+ * +------------------|------------------|--------------------|-------------------+
+ * | CODEC_SLOT0 Left | CODEC_SLOT1 Left | CODEC_SLOT0 Right | CODEC_SLOT1 Right |
+ * +------------------------------------------------------------------------------+
+ */
+/* To have 2 separate audio stream in Both headphone and speaker the 4 slot must be activated */
+#define CODEC_AUDIOFRAME_SLOT_0123 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_2 | SAI_SLOTACTIVE_3
+/* To have an audio stream in headphone only SAI Slot 0 and Slot 2 must be activated */
+#define CODEC_AUDIOFRAME_SLOT_02 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_2
+/* To have an audio stream in speaker only SAI Slot 1 and Slot 3 must be activated */
+#define CODEC_AUDIOFRAME_SLOT_13 SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_3
+
+/* SAI peripheral configuration defines */
+#define AUDIO_SAIx SAI2_Block_B
+#define AUDIO_SAIx_CLK_ENABLE() __HAL_RCC_SAI2_CLK_ENABLE()
+#define AUDIO_SAIx_CLK_DISABLE() __HAL_RCC_SAI2_CLK_DISABLE()
+#define AUDIO_SAIx_SCK_AF GPIO_AF8_SAI2
+#define AUDIO_SAIx_FS_SD_MCLK_AF GPIO_AF10_SAI2
+
+#define AUDIO_SAIx_MCLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
+#define AUDIO_SAIx_MCLK_GPIO_PORT GPIOE
+#define AUDIO_SAIx_MCLK_PIN GPIO_PIN_6
+#define AUDIO_SAIx_SCK_SD_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define AUDIO_SAIx_SCK_SD_GPIO_PORT GPIOA
+#define AUDIO_SAIx_SCK_PIN GPIO_PIN_2
+#define AUDIO_SAIx_SD_PIN GPIO_PIN_0
+#define AUDIO_SAIx_FS_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
+#define AUDIO_SAIx_FS_GPIO_PORT GPIOG
+#define AUDIO_SAIx_FS_PIN GPIO_PIN_9
+
+
+/* SAI DMA Stream definitions */
+#define AUDIO_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
+#define AUDIO_SAIx_DMAx_STREAM DMA2_Stream6
+#define AUDIO_SAIx_DMAx_CHANNEL DMA_CHANNEL_3
+#define AUDIO_SAIx_DMAx_IRQ DMA2_Stream6_IRQn
+#define AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
+#define AUDIO_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
+#define DMA_MAX_SZE 0xFFFF
+
+#define AUDIO_SAIx_DMAx_IRQHandler DMA2_Stream6_IRQHandler
+
+/* Select the interrupt preemption priority for the DMA interrupt */
+#define AUDIO_OUT_IRQ_PREPRIO ((uint32_t)0x0E) /* Select the preemption priority level(0 is the highest) */
+
+/*------------------------------------------------------------------------------
+ AUDIO IN CONFIGURATION
+------------------------------------------------------------------------------*/
+/* SPI Configuration defines */
+#define AUDIO_I2Sx SPI3
+#define AUDIO_I2Sx_CLK_ENABLE() __HAL_RCC_SPI3_CLK_ENABLE()
+#define AUDIO_I2Sx_CLK_DISABLE() __HAL_RCC_SPI3_CLK_DISABLE()
+#define AUDIO_I2Sx_SCK_PIN GPIO_PIN_3
+#define AUDIO_I2Sx_SCK_GPIO_PORT GPIOB
+#define AUDIO_I2Sx_SCK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define AUDIO_I2Sx_SCK_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
+#define AUDIO_I2Sx_SCK_AF GPIO_AF6_SPI3
+
+#define AUDIO_I2Sx_SD_PIN GPIO_PIN_6
+#define AUDIO_I2Sx_SD_GPIO_PORT GPIOD
+#define AUDIO_I2Sx_SD_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
+#define AUDIO_I2Sx_SD_GPIO_CLK_DISABLE() __HAL_RCC_GPIOD_CLK_DISABLE()
+#define AUDIO_I2Sx_SD_AF GPIO_AF5_SPI3
+
+/* I2S DMA Stream Rx definitions */
+#define AUDIO_I2Sx_DMAx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
+#define AUDIO_I2Sx_DMAx_CLK_DISABLE() __HAL_RCC_DMA1_CLK_DISABLE()
+#define AUDIO_I2Sx_DMAx_STREAM DMA1_Stream2
+#define AUDIO_I2Sx_DMAx_CHANNEL DMA_CHANNEL_0
+#define AUDIO_I2Sx_DMAx_IRQ DMA1_Stream2_IRQn
+#define AUDIO_I2Sx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
+#define AUDIO_I2Sx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
+
+#define AUDIO_I2Sx_DMAx_IRQHandler DMA1_Stream2_IRQHandler
+
+/* Select the interrupt preemption priority and subpriority for the IT/DMA interrupt */
+#define AUDIO_IN_IRQ_PREPRIO ((uint32_t)0x0F) /* Select the preemption priority level(0 is the highest) */
+
+
+/* Two channels are used:
+ - one channel as input which is connected to I2S SCK in stereo mode
+ - one channel as outupt which divides the frequency on the input
+*/
+
+#define AUDIO_TIMx_CLK_ENABLE() __HAL_RCC_TIM3_CLK_ENABLE()
+#define AUDIO_TIMx_CLK_DISABLE() __HAL_RCC_TIM3_CLK_DISABLE()
+#define AUDIO_TIMx TIM3
+#define AUDIO_TIMx_IN_CHANNEL TIM_CHANNEL_1
+#define AUDIO_TIMx_OUT_CHANNEL TIM_CHANNEL_2 /* Select channel 2 as output */
+#define AUDIO_TIMx_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define AUDIO_TIMx_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
+#define AUDIO_TIMx_GPIO_PORT GPIOC
+#define AUDIO_TIMx_IN_GPIO_PIN GPIO_PIN_6
+#define AUDIO_TIMx_OUT_GPIO_PIN GPIO_PIN_7
+#define AUDIO_TIMx_AF GPIO_AF2_TIM3
+
+/*------------------------------------------------------------------------------
+ CONFIGURATION: Audio Driver Configuration parameters
+------------------------------------------------------------------------------*/
+
+#define AUDIODATA_SIZE 2 /* 16-bits audio data size */
+
+/* Audio status definition */
+#define AUDIO_OK ((uint8_t)0)
+#define AUDIO_ERROR ((uint8_t)1)
+#define AUDIO_TIMEOUT ((uint8_t)2)
+
+/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */
+#define DEFAULT_AUDIO_IN_FREQ I2S_AUDIOFREQ_16K
+#define DEFAULT_AUDIO_IN_BIT_RESOLUTION ((uint8_t)16)
+#define DEFAULT_AUDIO_IN_CHANNEL_NBR ((uint8_t)2) /* Mono = 1, Stereo = 2 */
+#define DEFAULT_AUDIO_IN_VOLUME ((uint16_t)64)
+
+/* PDM buffer input size */
+#define INTERNAL_BUFF_SIZE (128*DEFAULT_AUDIO_IN_FREQ/16000*DEFAULT_AUDIO_IN_CHANNEL_NBR)
+/* PCM buffer output size */
+#define PCM_OUT_SIZE (DEFAULT_AUDIO_IN_FREQ/1000*2)
+#define CHANNEL_DEMUX_MASK ((uint8_t)0x55)
+
+/*------------------------------------------------------------------------------
+ OPTIONAL Configuration defines parameters
+------------------------------------------------------------------------------*/
+
+/* Delay for the Codec to be correctly reset */
+#define CODEC_RESET_DELAY ((uint8_t)5)
+
+
+/*------------------------------------------------------------------------------
+ OUTPUT DEVICES definition
+------------------------------------------------------------------------------*/
+/* Alias on existing output devices to adapt for 2 headphones output */
+#define OUTPUT_DEVICE_HEADPHONE1 OUTPUT_DEVICE_HEADPHONE
+#define OUTPUT_DEVICE_HEADPHONE2 OUTPUT_DEVICE_SPEAKER /* Headphone2 is connected to Speaker output of the wm8994 */
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_AUDIO_Exported_Variables STM32756G_EVAL_AUDIO Exported Variables
+ * @{
+ */
+extern __IO uint16_t AudioInVolume;
+ /**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_AUDIO_Exported_Macros STM32756G_EVAL_AUDIO Exported Macros
+ * @{
+ */
+#define DMA_MAX(x) (((x) <= DMA_MAX_SZE)? (x):DMA_MAX_SZE)
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_AUDIO_OUT_Exported_Functions STM32756G_EVAL_AUDIO_OUT Exported Functions
+ * @{
+ */
+uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq);
+uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size);
+void BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size);
+uint8_t BSP_AUDIO_OUT_Pause(void);
+uint8_t BSP_AUDIO_OUT_Resume(void);
+uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option);
+uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume);
+void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq);
+void BSP_AUDIO_OUT_SetAudioFrameSlot(uint32_t AudioFrameSlot);
+uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd);
+uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output);
+void BSP_AUDIO_OUT_DeInit(void);
+
+/* User Callbacks: user has to implement these functions in his code if they are needed. */
+/* This function is called when the requested data has been completely transferred.*/
+void BSP_AUDIO_OUT_TransferComplete_CallBack(void);
+
+/* This function is called when half of the requested buffer has been transferred. */
+void BSP_AUDIO_OUT_HalfTransfer_CallBack(void);
+
+/* This function is called when an Interrupt due to transfer error on or peripheral
+ error occurs. */
+void BSP_AUDIO_OUT_Error_CallBack(void);
+
+/* These function can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_AUDIO_OUT_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params);
+void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params);
+void BSP_AUDIO_OUT_MspDeInit(SAI_HandleTypeDef *hsai, void *Params);
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_AUDIO_IN_Exported_Functions STM32756G_EVAL_AUDIO_IN Exported Functions
+ * @{
+ */
+uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_Record(uint16_t *pData, uint32_t Size);
+uint8_t BSP_AUDIO_IN_Stop(void);
+uint8_t BSP_AUDIO_IN_Pause(void);
+uint8_t BSP_AUDIO_IN_Resume(void);
+uint8_t BSP_AUDIO_IN_SetVolume(uint8_t Volume);
+void BSP_AUDIO_IN_DeInit(void);
+uint8_t BSP_AUDIO_IN_PDMToPCM(uint16_t* PDMBuf, uint16_t* PCMBuf);
+/* User Callbacks: user has to implement these functions in his code if they are needed. */
+/* This function should be implemented by the user application.
+ It is called into this driver when the current buffer is filled to prepare the next
+ buffer pointer and its size. */
+void BSP_AUDIO_IN_TransferComplete_CallBack(void);
+void BSP_AUDIO_IN_HalfTransfer_CallBack(void);
+
+/* This function is called when an Interrupt due to transfer error on or peripheral
+ error occurs. */
+void BSP_AUDIO_IN_Error_Callback(void);
+
+/* These function can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_AUDIO_IN_MspInit(I2S_HandleTypeDef *hi2s, void *Params);
+void BSP_AUDIO_IN_MspDeInit(I2S_HandleTypeDef *hi2s, void *Params);
+void BSP_AUDIO_IN_ClockConfig(I2S_HandleTypeDef *hi2s, uint32_t AudioFreq, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32756G_EVAL_AUDIO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_camera.c b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_camera.c
new file mode 100644
index 00000000..929e9009
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_camera.c
@@ -0,0 +1,664 @@
+/**
+ ******************************************************************************
+ * @file stm32756g_eval_camera.c
+ * @author MCD Application Team
+ * @brief This file includes the driver for Camera modules mounted on
+ * STM32756G-EVAL and STM32746G-EVAL evaluation boards.
+ @verbatim
+ How to use this driver:
+ -----------------------
+ - This driver is used to drive the camera.
+ - The S5K5CAG component driver MUST be included with this driver.
+
+ Driver description:
+ ------------------
+ + Initialization steps:
+ o Initialize the camera using the BSP_CAMERA_Init() function.
+ o Start the camera capture/snapshot using the CAMERA_Start() function.
+ o Suspend, resume or stop the camera capture using the following functions:
+ - BSP_CAMERA_Suspend()
+ - BSP_CAMERA_Resume()
+ - BSP_CAMERA_Stop()
+
+ + Options
+ o Increase or decrease on the fly the brightness and/or contrast
+ using the following function:
+ - BSP_CAMERA_ContrastBrightnessConfig
+ o Add a special effect on the fly using the following functions:
+ - BSP_CAMERA_BlackWhiteConfig()
+ - BSP_CAMERA_ColorEffectConfig()
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32756G_EVAL_CAMERA_H
+#define __STM32756G_EVAL_CAMERA_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include Camera component Driver */
+#include "../Components/s5k5cag/s5k5cag.h"
+#include "../Components/ov5640/ov5640.h"
+
+/* Include IO Driver */
+#include "stm32756g_eval_io.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL_CAMERA
+ * @{
+ */
+
+/** @defgroup STM32756G_EVAL_CAMERA_Exported_Types CAMERA Exported Types
+ * @{
+ */
+
+/**
+ * @brief Camera State structures definition
+ */
+typedef enum
+{
+ CAMERA_OK = 0x00,
+ CAMERA_ERROR = 0x01,
+ CAMERA_TIMEOUT = 0x02,
+ CAMERA_NOT_DETECTED = 0x03,
+ CAMERA_NOT_SUPPORTED = 0x04
+
+} Camera_StatusTypeDef;
+
+#define RESOLUTION_R160x120 CAMERA_R160x120 /* QQVGA Resolution */
+#define RESOLUTION_R320x240 CAMERA_R320x240 /* QVGA Resolution */
+#define RESOLUTION_R480x272 CAMERA_R480x272 /* 480x272 Resolution */
+#define RESOLUTION_R640x480 CAMERA_R640x480 /* VGA Resolution */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_CAMERA_Exported_Constants CAMERA Exported Constants
+ * @{
+ */
+#define BSP_CAMERA_IRQHandler DCMI_IRQHandler
+#define BSP_CAMERA_DMA_IRQHandler DMA2_Stream1_IRQHandler
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_CAMERA_Exported_Functions CAMERA Exported Functions
+ * @{
+ */
+uint8_t BSP_CAMERA_Init(uint32_t Resolution);
+uint8_t BSP_CAMERA_DeInit(void);
+void BSP_CAMERA_ContinuousStart(uint8_t *buff);
+void BSP_CAMERA_SnapshotStart(uint8_t *buff);
+void BSP_CAMERA_Suspend(void);
+void BSP_CAMERA_Resume(void);
+uint8_t BSP_CAMERA_Stop(void);
+void BSP_CAMERA_HwReset(void);
+void BSP_CAMERA_PwrDown(void);
+void BSP_CAMERA_LineEventCallback(void);
+void BSP_CAMERA_VsyncEventCallback(void);
+void BSP_CAMERA_FrameEventCallback(void);
+void BSP_CAMERA_ErrorCallback(void);
+
+/* Camera features functions prototype */
+void BSP_CAMERA_ContrastBrightnessConfig(uint32_t contrast_level, uint32_t brightness_level);
+void BSP_CAMERA_BlackWhiteConfig(uint32_t Mode);
+void BSP_CAMERA_ColorEffectConfig(uint32_t Effect);
+
+/* To be called in DCMI_IRQHandler function */
+void BSP_CAMERA_IRQHandler(void);
+/* To be called in DMA2_Stream1_IRQHandler function */
+void BSP_CAMERA_DMA_IRQHandler(void);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_CAMERA_MspInit(DCMI_HandleTypeDef *hdcmi, void *Params);
+void BSP_CAMERA_MspDeInit(DCMI_HandleTypeDef *hdcmi, void *Params);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32756G_EVAL_CAMERA_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_eeprom.c b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_eeprom.c
new file mode 100644
index 00000000..30f7ff15
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_eeprom.c
@@ -0,0 +1,476 @@
+/**
+ ******************************************************************************
+ * @file stm32756g_eval_eeprom.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage an I2C M24LR64
+ * EEPROM memory.
+ @verbatim
+ To be able to use this driver, the switch EE_M24LR64 must be defined
+ in your toolchain compiler preprocessor
+
+ ===================================================================
+ Notes:
+ - The I2C EEPROM memory (M24LR64) is available on separate daughter
+ board ANT7-M24LR-A, which is not provided with the STM32756G_EVAL
+ and STM32746G_EVAL boards.
+ To use this driver you have to connect the ANT7-M24LR-A to CN2
+ connector of STM32756G_EVAL board.
+ ===================================================================
+
+ It implements a high level communication layer for read and write
+ from/to this memory. The needed STM32F7xx hardware resources (I2C and
+ GPIO) are defined in stm32756g_eval.h file, and the initialization is
+ performed in EEPROM_IO_Init() function declared in stm32756g_eval.c
+ file.
+ You can easily tailor this driver to any other development board,
+ by just adapting the defines for hardware resources and
+ EEPROM_IO_Init() function.
+
+ @note In this driver, basic read and write functions (BSP_EEPROM_ReadBuffer()
+ and BSP_EEPROM_WritePage()) use DMA mode to perform the data
+ transfer to/from EEPROM memory.
+
+ @note Regarding BSP_EEPROM_WritePage(), it is an optimized function to perform
+ small write (less than 1 page) BUT the number of bytes (combined to write start address) must not
+ cross the EEPROM page boundary. This function can only writes into
+ the boundaries of an EEPROM page.
+ This function doesn't check on boundaries condition (in this driver
+ the function BSP_EEPROM_WriteBuffer() which calls BSP_EEPROM_WritePage() is
+ responsible of checking on Page boundaries).
+
+
+ +-----------------------------------------------------------------+
+ | Pin assignment for M24LR64 EEPROM |
+ +---------------------------------------+-----------+-------------+
+ | STM32F7xx I2C Pins | EEPROM | Pin |
+ +---------------------------------------+-----------+-------------+
+ | . | E0(GND) | 1 (0V) |
+ | . | AC0 | 2 |
+ | . | AC1 | 3 |
+ | . | VSS | 4 (0V) |
+ | SDA | SDA | 5 |
+ | SCL | SCL | 6 |
+ | . | E1(GND) | 7 (0V) |
+ | . | VDD | 8 (3.3V) |
+ +---------------------------------------+-----------+-------------+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Dependencies
+- stm32756g_eval.c
+EndDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32756g_eval_eeprom.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL
+ * @{
+ */
+
+/** @defgroup STM32756G_EVAL_EEPROM STM32756G_EVAL EEPROM
+ * @brief This file includes the I2C EEPROM driver of STM32756G-EVAL evaluation board.
+ * @{
+ */
+
+/** @defgroup STM32756G_EVAL_EEPROM_Private_Types EEPROM Private Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_EEPROM_Private_Defines EEPROM Private Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_EEPROM_Private_Macros EEPROM Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_EEPROM_Private_Variables EEPROM Private Variables
+ * @{
+ */
+__IO uint16_t EEPROMAddress = 0;
+__IO uint16_t EEPROMDataRead;
+__IO uint8_t EEPROMDataWrite;
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_EEPROM_Private_Functions_Prototypes EEPROM Private Functions Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_EEPROM_Private_Functions EEPROM Private Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes peripherals used by the I2C EEPROM driver.
+ * @note There are 2 different versions of M24LR64 (A01 & A02).
+ * Then try to connect on 1st one (EEPROM_I2C_ADDRESS_A01)
+ * and if problem, check the 2nd one (EEPROM_I2C_ADDRESS_A02)
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0)
+ */
+uint32_t BSP_EEPROM_Init(void)
+{
+ /* I2C Initialization */
+ EEPROM_IO_Init();
+
+ /* Select the EEPROM address for A01 and check if OK */
+ EEPROMAddress = EEPROM_I2C_ADDRESS_A01;
+ if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
+ {
+ /* Select the EEPROM address for A02 and check if OK */
+ EEPROMAddress = EEPROM_I2C_ADDRESS_A02;
+ if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
+ {
+ return EEPROM_FAIL;
+ }
+ }
+ return EEPROM_OK;
+}
+
+/**
+ * @brief DeInitializes the EEPROM.
+ * @retval EEPROM state
+ */
+uint8_t BSP_EEPROM_DeInit(void)
+{
+ /* I2C won't be disabled because common to other functionalities */
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Reads a block of data from the EEPROM.
+ * @param pBuffer: pointer to the buffer that receives the data read from
+ * the EEPROM.
+ * @param ReadAddr: EEPROM's internal address to start reading from.
+ * @param NumByteToRead: pointer to the variable holding number of bytes to
+ * be read from the EEPROM.
+ *
+ * @note The variable pointed by NumByteToRead is reset to 0 when all the
+ * data are read from the EEPROM. Application should monitor this
+ * variable in order know when the transfer is complete.
+ *
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
+{
+ uint32_t buffersize = *NumByteToRead;
+
+ /* Set the pointer to the Number of data to be read. This pointer will be used
+ by the DMA Transfer Completer interrupt Handler in order to reset the
+ variable to 0. User should check on this variable in order to know if the
+ DMA transfer has been complete or not. */
+ EEPROMDataRead = *NumByteToRead;
+
+ if(EEPROM_IO_ReadData(EEPROMAddress, ReadAddr, pBuffer, buffersize) != HAL_OK)
+ {
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ return EEPROM_FAIL;
+ }
+
+ /* If all operations OK, return EEPROM_OK (0) */
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Writes more than one byte to the EEPROM with a single WRITE cycle.
+ *
+ * @note The number of bytes (combined to write start address) must not
+ * cross the EEPROM page boundary. This function can only write into
+ * the boundaries of an EEPROM page.
+ * This function doesn't check on boundaries condition (in this driver
+ * the function BSP_EEPROM_WriteBuffer() which calls BSP_EEPROM_WritePage() is
+ * responsible of checking on Page boundaries).
+ *
+ * @param pBuffer: pointer to the buffer containing the data to be written to
+ * the EEPROM.
+ * @param WriteAddr: EEPROM's internal address to write to.
+ * @param NumByteToWrite: pointer to the variable holding number of bytes to
+ * be written into the EEPROM.
+ *
+ * @note The variable pointed by NumByteToWrite is reset to 0 when all the
+ * data are written to the EEPROM. Application should monitor this
+ * variable in order know when the transfer is complete.
+ *
+ * @note This function just configure the communication and enable the DMA
+ * channel to transfer data. Meanwhile, the user application may perform
+ * other tasks in parallel.
+ *
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite)
+{
+ uint32_t buffersize = *NumByteToWrite;
+ uint32_t status = EEPROM_OK;
+
+ /* Set the pointer to the Number of data to be written. This pointer will be used
+ by the DMA Transfer Completer interrupt Handler in order to reset the
+ variable to 0. User should check on this variable in order to know if the
+ DMA transfer has been complete or not. */
+ EEPROMDataWrite = *NumByteToWrite;
+
+ if(EEPROM_IO_WriteData(EEPROMAddress, WriteAddr, pBuffer, buffersize) != HAL_OK)
+ {
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ status = EEPROM_FAIL;
+ }
+
+ if(BSP_EEPROM_WaitEepromStandbyState() != EEPROM_OK)
+ {
+ return EEPROM_FAIL;
+ }
+
+ /* If all operations OK, return EEPROM_OK (0) */
+ return status;
+}
+
+/**
+ * @brief Writes buffer of data to the I2C EEPROM.
+ * @param pBuffer: pointer to the buffer containing the data to be written
+ * to the EEPROM.
+ * @param WriteAddr: EEPROM's internal address to write to.
+ * @param NumByteToWrite: number of bytes to write to the EEPROM.
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_WriteBuffer(uint8_t *pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
+{
+ uint16_t numofpage = 0, numofsingle = 0, count = 0;
+ uint16_t addr = 0;
+ uint8_t dataindex = 0;
+ uint32_t status = EEPROM_OK;
+
+ addr = WriteAddr % EEPROM_PAGESIZE;
+ count = EEPROM_PAGESIZE - addr;
+ numofpage = NumByteToWrite / EEPROM_PAGESIZE;
+ numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
+
+ /* If WriteAddr is EEPROM_PAGESIZE aligned */
+ if(addr == 0)
+ {
+ /* If NumByteToWrite < EEPROM_PAGESIZE */
+ if(numofpage == 0)
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ /* Start writing data */
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ /* If NumByteToWrite > EEPROM_PAGESIZE */
+ else
+ {
+ while(numofpage--)
+ {
+ /* Store the number of data to be written */
+ dataindex = EEPROM_PAGESIZE;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+
+ WriteAddr += EEPROM_PAGESIZE;
+ pBuffer += EEPROM_PAGESIZE;
+ }
+
+ if(numofsingle!=0)
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ }
+ }
+ /* If WriteAddr is not EEPROM_PAGESIZE aligned */
+ else
+ {
+ /* If NumByteToWrite < EEPROM_PAGESIZE */
+ if(numofpage== 0)
+ {
+ /* If the number of data to be written is more than the remaining space
+ in the current page: */
+ if(NumByteToWrite > count)
+ {
+ /* Store the number of data to be written */
+ dataindex = count;
+ /* Write the data contained in same page */
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+
+ /* Store the number of data to be written */
+ dataindex = (NumByteToWrite - count);
+ /* Write the remaining data in the following page */
+ status = BSP_EEPROM_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ else
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ }
+ /* If NumByteToWrite > EEPROM_PAGESIZE */
+ else
+ {
+ NumByteToWrite -= count;
+ numofpage = NumByteToWrite / EEPROM_PAGESIZE;
+ numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
+
+ if(count != 0)
+ {
+ /* Store the number of data to be written */
+ dataindex = count;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ WriteAddr += count;
+ pBuffer += count;
+ }
+
+ while(numofpage--)
+ {
+ /* Store the number of data to be written */
+ dataindex = EEPROM_PAGESIZE;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ WriteAddr += EEPROM_PAGESIZE;
+ pBuffer += EEPROM_PAGESIZE;
+ }
+ if(numofsingle != 0)
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ }
+ }
+
+ /* If all operations OK, return EEPROM_OK (0) */
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Wait for EEPROM Standby state.
+ *
+ * @note This function allows to wait and check that EEPROM has finished the
+ * last operation. It is mostly used after Write operation: after receiving
+ * the buffer to be written, the EEPROM may need additional time to actually
+ * perform the write operation. During this time, it doesn't answer to
+ * I2C packets addressed to it. Once the write operation is complete
+ * the EEPROM responds to its address.
+ *
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_WaitEepromStandbyState(void)
+{
+ /* Check if the maximum allowed number of trials has bee reached */
+ if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
+ {
+ /* If the maximum number of trials has been reached, exit the function */
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ return EEPROM_TIMEOUT;
+ }
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Basic management of the timeout situation.
+ * @retval None
+ */
+__weak void BSP_EEPROM_TIMEOUT_UserCallback(void)
+{
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_eeprom.h b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_eeprom.h
new file mode 100644
index 00000000..ae4db005
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_eeprom.h
@@ -0,0 +1,138 @@
+/**
+ ******************************************************************************
+ * @file stm32756g_eval_eeprom.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for
+ * the stm32756g_eval_eeprom.c firmware driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F756G_EVAL_EEPROM_H
+#define __STM32F756G_EVAL_EEPROM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32756g_eval.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL_EEPROM STM32756G_EVAL EEPROM
+ * @brief This file includes the I2C EEPROM driver of STM32756G-EVAL evaluation board.
+ * @{
+ */
+
+/** @defgroup STM32756G_EVAL_EEPROM_Exported_Types EEPROM Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_EEPROM_Exported_Constants EEPROM Exported Constants
+ * @{
+ */
+/* EEPROM hardware address and page size */
+#define EEPROM_PAGESIZE ((uint8_t)4)
+#define EEPROM_MAX_SIZE ((uint16_t)0x2000) /* 64Kbit */
+
+
+/* Maximum number of trials for EEPROM_WaitEepromStandbyState() function */
+#define EEPROM_MAX_TRIALS ((uint32_t)3000)
+
+#define EEPROM_OK ((uint32_t)0)
+#define EEPROM_FAIL ((uint32_t)1)
+#define EEPROM_TIMEOUT ((uint32_t)2)
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_EEPROM_Exported_Macros EEPROM Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_EEPROM_Exported_Functions EEPROM Exported Functions
+ * @{
+ */
+uint32_t BSP_EEPROM_Init(void);
+uint8_t BSP_EEPROM_DeInit(void);
+uint32_t BSP_EEPROM_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead);
+uint32_t BSP_EEPROM_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite);
+uint32_t BSP_EEPROM_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite);
+uint32_t BSP_EEPROM_WaitEepromStandbyState(void);
+
+/* USER Callbacks: This function is declared as __weak in EEPROM driver and
+ should be implemented into user application.
+ BSP_EEPROM_TIMEOUT_UserCallback() function is called whenever a timeout condition
+ occurs during communication (waiting on an event that doesn't occur, bus
+ errors, busy devices ...). */
+void BSP_EEPROM_TIMEOUT_UserCallback(void);
+
+/* Link function for I2C EEPROM peripheral */
+void EEPROM_IO_Init(void);
+HAL_StatusTypeDef EEPROM_IO_WriteData(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef EEPROM_IO_ReadData(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef EEPROM_IO_IsDeviceReady(uint16_t DevAddress, uint32_t Trials);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32756G_EVAL_EEPROM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_io.c b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_io.c
new file mode 100644
index 00000000..d99545f2
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_io.c
@@ -0,0 +1,325 @@
+/**
+ ******************************************************************************
+ * @file stm32756g_eval_io.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the IO pins
+ * on STM32756G-EVAL and STM32746G-EVAL evaluation board.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ - This driver is used to drive the IO module of the STM32756G-EVAL evaluation
+ board.
+ - The MFXSTM32L152 IO expander device component driver must be included with this
+ driver in order to run the IO functionalities commanded by the IO expander (MFX)
+ device mounted on the evaluation board.
+
+ Driver description:
+ -------------------
+ + Initialization steps:
+ o Initialize the IO module using the BSP_IO_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ communication layer configuration to start the IO functionalities use.
+
+ + IO functionalities use
+ o The IO pin mode is configured when calling the function BSP_IO_ConfigPin(), you
+ must specify the desired IO mode by choosing the "IO_ModeTypedef" parameter
+ predefined value.
+ o If an IO pin is used in interrupt mode, the function BSP_IO_ITGetStatus() is
+ needed to get the interrupt status. To clear the IT pending bits, you should
+ call the function BSP_IO_ITClear() with specifying the IO pending bit to clear.
+ o The IT is handled using the corresponding external interrupt IRQ handler,
+ the user IT callback treatment is implemented on the same external interrupt
+ callback.
+ o The IRQ_OUT pin (common for all functionalities: JOY, SD, LEDs, etc) can be
+ configured using the function BSP_IO_ConfigIrqOutPin()
+ o To get/set an IO pin combination state you can use the functions
+ BSP_IO_ReadPin()/BSP_IO_WritePin() or the function BSP_IO_TogglePin() to toggle the pin
+ state.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Dependencies
+- stm32756g_eval.h
+- mfxstm32l152.c
+EndDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32756g_eval_io.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL
+ * @{
+ */
+
+/** @defgroup STM32756G_EVAL_IO STM32756G_EVAL IO
+ * @{
+ */
+
+/** @defgroup STM32756G_EVAL_IO_Private_Types_Definitions IO Private Types Definitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_IO_Private_Defines IO Private Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_IO_Private_Macros IO Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_IO_Private_Variables IO Private Variables
+ * @{
+ */
+static IO_DrvTypeDef *IoDrv = NULL;
+static uint8_t mfxstm32l152Identifier;
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_IO_Private_Functions_Prototypes IO Private Functions Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_IO_Private_Functions IO Private Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes and configures the IO functionalities and configures all
+ * necessary hardware resources (MFX, ...).
+ * @note BSP_IO_Init() is using HAL_Delay() function to ensure that MFXSTM32L152
+ * IO Expander is correctly reset. HAL_Delay() function provides accurate
+ * delay (in milliseconds) based on variable incremented in SysTick ISR.
+ * This implies that if BSP_IO_Init() is called from a peripheral ISR process,
+ * then the SysTick interrupt must have higher priority (numerically lower)
+ * than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
+ * @retval IO_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_IO_Init(void)
+{
+ uint8_t ret = IO_OK;
+
+ if (IoDrv == NULL) /* Checks if MFX initialization never done */
+ {
+ /* Read ID and verify the MFX is ready */
+ mfxstm32l152Identifier = mfxstm32l152_io_drv.ReadID(IO_I2C_ADDRESS);
+ if((mfxstm32l152Identifier == MFXSTM32L152_ID_1) || (mfxstm32l152Identifier == MFXSTM32L152_ID_2))
+ {
+ /* Initialize the IO driver structure */
+ IoDrv = &mfxstm32l152_io_drv;
+
+ /* Initialize MFX */
+ IoDrv->Init(IO_I2C_ADDRESS);
+ IoDrv->Start(IO_I2C_ADDRESS, IO_PIN_ALL);
+ }
+ else
+ {
+ ret = IO_ERROR;
+ }
+ }
+ else
+ {
+ /* MFX initialization already done : do nothing */
+ }
+
+ return ret;
+}
+
+/**
+ * @brief DeInit allows Mfx Initialization to be executed again
+ * @note BSP_IO_Init() has no effect if the IoDrv is already initialized
+ * BSP_IO_DeInit() allows to erase the pointer such to allow init to be effective
+ * @retval IO_OK
+ */
+uint8_t BSP_IO_DeInit(void)
+{
+ IoDrv = NULL;
+ return IO_OK;
+}
+
+/**
+ * @brief Gets the selected pins IT status.
+ * @param IoPin: Selected pins to check the status.
+ * This parameter can be any combination of the IO pins.
+ * @retval IO_OK if read status OK. Other value if error.
+ */
+uint32_t BSP_IO_ITGetStatus(uint32_t IoPin)
+{
+ /* Return the IO Pin IT status */
+ return (IoDrv->ITStatus(IO_I2C_ADDRESS, IoPin));
+}
+
+/**
+ * @brief Clears all the IO IT pending bits.
+ * @retval None
+ */
+void BSP_IO_ITClear(void)
+{
+ /* Clear all IO IT pending bits */
+ IoDrv->ClearIT(IO_I2C_ADDRESS, MFXSTM32L152_GPIO_PINS_ALL);
+}
+
+/**
+ * @brief Configures the IO pin(s) according to IO mode structure value.
+ * @param IoPin: IO pin(s) to be configured.
+ * This parameter can be one of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+ * @param IoMode: IO pin mode to configure
+ * This parameter can be one of the following values:
+ * @arg IO_MODE_INPUT
+ * @arg IO_MODE_OUTPUT
+ * @arg IO_MODE_IT_RISING_EDGE
+ * @arg IO_MODE_IT_FALLING_EDGE
+ * @arg IO_MODE_IT_LOW_LEVEL
+ * @arg IO_MODE_IT_HIGH_LEVEL
+ * @arg IO_MODE_ANALOG
+ * @arg IO_MODE_OFF
+ * @arg IO_MODE_INPUT_PU,
+ * @arg IO_MODE_INPUT_PD,
+ * @arg IO_MODE_OUTPUT_OD,
+ * @arg IO_MODE_OUTPUT_OD_PU,
+ * @arg IO_MODE_OUTPUT_OD_PD,
+ * @arg IO_MODE_OUTPUT_PP,
+ * @arg IO_MODE_OUTPUT_PP_PU,
+ * @arg IO_MODE_OUTPUT_PP_PD,
+ * @arg IO_MODE_IT_RISING_EDGE_PU
+ * @arg IO_MODE_IT_FALLING_EDGE_PU
+ * @arg IO_MODE_IT_LOW_LEVEL_PU
+ * @arg IO_MODE_IT_HIGH_LEVEL_PU
+ * @arg IO_MODE_IT_RISING_EDGE_PD
+ * @arg IO_MODE_IT_FALLING_EDGE_PD
+ * @arg IO_MODE_IT_LOW_LEVEL_PD
+ * @arg IO_MODE_IT_HIGH_LEVEL_PD
+ * @retval IO_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_IO_ConfigPin(uint32_t IoPin, IO_ModeTypedef IoMode)
+{
+ /* Configure the selected IO pin(s) mode */
+ IoDrv->Config(IO_I2C_ADDRESS, IoPin, IoMode);
+
+ return IO_OK;
+}
+
+/**
+ * @brief Sets the IRQ_OUT pin polarity and type
+ * @param IoIrqOutPinPolarity: High/Low
+ * @param IoIrqOutPinType: OpenDrain/PushPull
+ * @retval OK
+ */
+uint8_t BSP_IO_ConfigIrqOutPin(uint8_t IoIrqOutPinPolarity, uint8_t IoIrqOutPinType)
+{
+ if((mfxstm32l152Identifier == MFXSTM32L152_ID_1) || (mfxstm32l152Identifier == MFXSTM32L152_ID_2))
+ {
+ /* Initialize the IO driver structure */
+ mfxstm32l152_SetIrqOutPinPolarity(IO_I2C_ADDRESS, IoIrqOutPinPolarity);
+ mfxstm32l152_SetIrqOutPinType(IO_I2C_ADDRESS, IoIrqOutPinType);
+ }
+
+ return IO_OK;
+}
+
+/**
+ * @brief Sets the selected pins state.
+ * @param IoPin: Selected pins to write.
+ * This parameter can be any combination of the IO pins.
+ * @param PinState: New pins state to write
+ * @retval None
+ */
+void BSP_IO_WritePin(uint32_t IoPin, BSP_IO_PinStateTypeDef PinState)
+{
+ /* Set the Pin state */
+ IoDrv->WritePin(IO_I2C_ADDRESS, IoPin, PinState);
+}
+
+/**
+ * @brief Gets the selected pins current state.
+ * @param IoPin: Selected pins to read.
+ * This parameter can be any combination of the IO pins.
+ * @retval The current pins state
+ */
+uint32_t BSP_IO_ReadPin(uint32_t IoPin)
+{
+ return(IoDrv->ReadPin(IO_I2C_ADDRESS, IoPin));
+}
+
+/**
+ * @brief Toggles the selected pins state.
+ * @param IoPin: Selected pins to toggle.
+ * This parameter can be any combination of the IO pins.
+ * @note This function is only used to toggle one pin in the same time
+ * @retval None
+ */
+void BSP_IO_TogglePin(uint32_t IoPin)
+{
+ /* Toggle the current pin state */
+ if(IoDrv->ReadPin(IO_I2C_ADDRESS, IoPin) != 0) /* Set */
+ {
+ IoDrv->WritePin(IO_I2C_ADDRESS, IoPin, 0); /* Reset */
+ }
+ else
+ {
+ IoDrv->WritePin(IO_I2C_ADDRESS, IoPin, 1); /* Set */
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_io.h b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_io.h
new file mode 100644
index 00000000..1c22f54b
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_io.h
@@ -0,0 +1,156 @@
+/**
+ ******************************************************************************
+ * @file stm32756g_eval_io.h
+ * @author MCD Application Team
+ * @brief This file contains the common defines and functions prototypes for
+ * the stm32756g_eval_io.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32756G_EVAL_IO_H
+#define __STM32756G_EVAL_IO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32756g_eval.h"
+/* Include IO component driver */
+#include "../Components/mfxstm32l152/mfxstm32l152.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL_IO
+ * @{
+ */
+
+/** @defgroup STM32756G_EVAL_IO_Exported_Types IO Exported Types
+ * @{
+ */
+
+typedef enum
+{
+ BSP_IO_PIN_RESET = 0,
+ BSP_IO_PIN_SET = 1
+}BSP_IO_PinStateTypeDef;
+
+typedef enum
+{
+ IO_OK = 0,
+ IO_ERROR = 1,
+ IO_TIMEOUT = 2
+}IO_StatusTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_IO_Exported_Constants IO Exported Constants
+ * @{
+ */
+#define IO_PIN_0 ((uint32_t)0x0001)
+#define IO_PIN_1 ((uint32_t)0x0002)
+#define IO_PIN_2 ((uint32_t)0x0004)
+#define IO_PIN_3 ((uint32_t)0x0008)
+#define IO_PIN_4 ((uint32_t)0x0010)
+#define IO_PIN_5 ((uint32_t)0x0020)
+#define IO_PIN_6 ((uint32_t)0x0040)
+#define IO_PIN_7 ((uint32_t)0x0080)
+#define IO_PIN_8 ((uint32_t)0x0100)
+#define IO_PIN_9 ((uint32_t)0x0200)
+#define IO_PIN_10 ((uint32_t)0x0400)
+#define IO_PIN_11 ((uint32_t)0x0800)
+#define IO_PIN_12 ((uint32_t)0x1000)
+#define IO_PIN_13 ((uint32_t)0x2000)
+#define IO_PIN_14 ((uint32_t)0x4000)
+#define IO_PIN_15 ((uint32_t)0x8000)
+#define IO_PIN_16 ((uint32_t)0x010000)
+#define IO_PIN_17 ((uint32_t)0x020000)
+#define IO_PIN_18 ((uint32_t)0x040000)
+#define IO_PIN_19 ((uint32_t)0x080000)
+#define IO_PIN_20 ((uint32_t)0x100000)
+#define IO_PIN_21 ((uint32_t)0x200000)
+#define IO_PIN_22 ((uint32_t)0x400000)
+#define IO_PIN_23 ((uint32_t)0x800000)
+#define IO_PIN_ALL ((uint32_t)0xFFFFFF)
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_IO_Exported_Macro IO Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_IO_Exported_Functions IO Exported Functions
+ * @{
+ */
+uint8_t BSP_IO_Init(void);
+uint8_t BSP_IO_DeInit(void);
+uint8_t BSP_IO_ConfigIrqOutPin(uint8_t IoIrqOutPinPolarity, uint8_t IoIrqOutPinType);
+uint32_t BSP_IO_ITGetStatus(uint32_t IoPin);
+void BSP_IO_ITClear(void);
+uint8_t BSP_IO_ConfigPin(uint32_t IoPin, IO_ModeTypedef IoMode);
+void BSP_IO_WritePin(uint32_t IoPin, BSP_IO_PinStateTypeDef PinState);
+uint32_t BSP_IO_ReadPin(uint32_t IoPin);
+void BSP_IO_TogglePin(uint32_t IoPin);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32756G_EVAL_IO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_lcd.c b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_lcd.c
new file mode 100644
index 00000000..52d3b0c4
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_lcd.c
@@ -0,0 +1,1626 @@
+/**
+ ******************************************************************************
+ * @file stm32756g_eval_lcd.c
+ * @author MCD Application Team
+ * @brief This file includes the driver for Liquid Crystal Display (LCD) module
+ * mounted on STM32756G-EVAL and STM32746G-EVAL evaluation boards.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ - This driver is used to drive directly an LCD TFT using the LTDC controller.
+ - This driver selects dynamically the mounted LCD, AMPIRE 640x480 LCD mounted
+ on MB1063 or AMPIRE 480x272 LCD mounted on MB1046 daughter board,
+ and uses the adequate timing and setting for the specified LCD using
+ device ID of the STMPE811 mounted on MB1046 daughter board.
+
+ Driver description:
+ ------------------
+ + Initialization steps:
+ o Initialize the LCD using the BSP_LCD_Init() function.
+ o Apply the Layer configuration using the BSP_LCD_LayerDefaultInit() function.
+ o Select the LCD layer to be used using the BSP_LCD_SelectLayer() function.
+ o Enable the LCD display using the BSP_LCD_DisplayOn() function.
+
+ + Options
+ o Configure and enable the colour keying functionality using the
+ BSP_LCD_SetColorKeying() function.
+ o Modify in the fly the transparency and/or the frame buffer address
+ using the following functions:
+ - BSP_LCD_SetTransparency()
+ - BSP_LCD_SetLayerAddress()
+
+ + Display on LCD
+ o Clear the whole LCD using BSP_LCD_Clear() function or only one specified string
+ line using the BSP_LCD_ClearStringLine() function.
+ o Display a character on the specified line and column using the BSP_LCD_DisplayChar()
+ function or a complete string line using the BSP_LCD_DisplayStringAtLine() function.
+ o Display a string line on the specified position (x,y in pixel) and align mode
+ using the BSP_LCD_DisplayStringAtLine() function.
+ o Draw and fill a basic shapes (dot, line, rectangle, circle, ellipse, .. bitmap)
+ on LCD using the available set of functions.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32756G_EVAL_LCD_H
+#define __STM32756G_EVAL_LCD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include LCD component Driver */
+/* LCD integrated within MB1063 */
+#include "../Components/ampire640480/ampire640480.h"
+/* LCD integrated within MB1046 */
+#include "../Components/ampire480272/ampire480272.h"
+
+/* Include IOExpander(STMPE811) component Driver */
+#include "../Components/stmpe811/stmpe811.h"
+
+/* Include SDRAM Driver */
+#include "stm32756g_eval_sdram.h"
+
+#include "stm32756g_eval.h"
+#include "../../../Utilities/Fonts/fonts.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL_LCD
+ * @{
+ */
+
+/** @defgroup STM32756G_EVAL_LCD_Exported_Types LCD Exported Types
+ * @{
+ */
+typedef struct
+{
+ uint32_t TextColor;
+ uint32_t BackColor;
+ sFONT *pFont;
+}LCD_DrawPropTypeDef;
+
+typedef struct
+{
+ int16_t X;
+ int16_t Y;
+}Point, * pPoint;
+
+/**
+ * @brief Line mode structures definition
+ */
+typedef enum
+{
+ CENTER_MODE = 0x01, /* Center mode */
+ RIGHT_MODE = 0x02, /* Right mode */
+ LEFT_MODE = 0x03 /* Left mode */
+}Text_AlignModeTypdef;
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_LCD_Exported_Constants LCD Exported Constants
+ * @{
+ */
+#define MAX_LAYER_NUMBER ((uint32_t)2)
+
+#define LCD_LayerCfgTypeDef LTDC_LayerCfgTypeDef
+
+#define LTDC_ACTIVE_LAYER ((uint32_t)1) /* Layer 1 */
+/**
+ * @brief LCD status structure definition
+ */
+#define LCD_OK ((uint8_t)0x00)
+#define LCD_ERROR ((uint8_t)0x01)
+#define LCD_TIMEOUT ((uint8_t)0x02)
+
+/**
+ * @brief LCD FB_StartAddress
+ */
+#define LCD_FB_START_ADDRESS ((uint32_t)0xC0000000)
+
+
+/**
+ * @brief LCD Layer_Number
+ */
+
+/* The programmed LTDC pixel clock depends on the vertical refresh rate of the panel 60Hz => 25.16MHz and
+ the LCD/SDRAM bandwidth affected by the several access on the bus and the number of used layers.
+ when only one layer is enabled "LCD_MAX_PCLK" can be used and when two layers are enabled simultaneously
+ or/and there is several access on the bus "LCD_MIN_PCLK" parameter is recommended */
+#define LCD_MAX_PCLK ((uint8_t)0x00)
+#define LCD_MIN_PCLK ((uint8_t)0x01)
+
+
+/**
+ * @brief LCD color
+ */
+#define LCD_COLOR_BLUE ((uint32_t)0xFF0000FF)
+#define LCD_COLOR_GREEN ((uint32_t)0xFF00FF00)
+#define LCD_COLOR_RED ((uint32_t)0xFFFF0000)
+#define LCD_COLOR_CYAN ((uint32_t)0xFF00FFFF)
+#define LCD_COLOR_MAGENTA ((uint32_t)0xFFFF00FF)
+#define LCD_COLOR_YELLOW ((uint32_t)0xFFFFFF00)
+#define LCD_COLOR_LIGHTBLUE ((uint32_t)0xFF8080FF)
+#define LCD_COLOR_LIGHTGREEN ((uint32_t)0xFF80FF80)
+#define LCD_COLOR_LIGHTRED ((uint32_t)0xFFFF8080)
+#define LCD_COLOR_LIGHTCYAN ((uint32_t)0xFF80FFFF)
+#define LCD_COLOR_LIGHTMAGENTA ((uint32_t)0xFFFF80FF)
+#define LCD_COLOR_LIGHTYELLOW ((uint32_t)0xFFFFFF80)
+#define LCD_COLOR_DARKBLUE ((uint32_t)0xFF000080)
+#define LCD_COLOR_DARKGREEN ((uint32_t)0xFF008000)
+#define LCD_COLOR_DARKRED ((uint32_t)0xFF800000)
+#define LCD_COLOR_DARKCYAN ((uint32_t)0xFF008080)
+#define LCD_COLOR_DARKMAGENTA ((uint32_t)0xFF800080)
+#define LCD_COLOR_DARKYELLOW ((uint32_t)0xFF808000)
+#define LCD_COLOR_WHITE ((uint32_t)0xFFFFFFFF)
+#define LCD_COLOR_LIGHTGRAY ((uint32_t)0xFFD3D3D3)
+#define LCD_COLOR_GRAY ((uint32_t)0xFF808080)
+#define LCD_COLOR_DARKGRAY ((uint32_t)0xFF404040)
+#define LCD_COLOR_BLACK ((uint32_t)0xFF000000)
+#define LCD_COLOR_BROWN ((uint32_t)0xFFA52A2A)
+#define LCD_COLOR_ORANGE ((uint32_t)0xFFFFA500)
+#define LCD_COLOR_TRANSPARENT ((uint32_t)0xFF000000)
+
+/**
+ * @brief LCD default font
+ */
+#define LCD_DEFAULT_FONT Font24
+
+/**
+ * @brief LCD Reload Types
+ */
+#define LCD_RELOAD_IMMEDIATE ((uint32_t)LTDC_SRCR_IMR)
+#define LCD_RELOAD_VERTICAL_BLANKING ((uint32_t)LTDC_SRCR_VBR)
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_LCD_Exported_Functions LCD Exported Functions
+ * @{
+ */
+uint8_t BSP_LCD_Init(void);
+uint8_t BSP_LCD_InitEx(uint32_t PclkConfig);
+
+uint8_t BSP_LCD_DeInit(void);
+uint32_t BSP_LCD_GetXSize(void);
+uint32_t BSP_LCD_GetYSize(void);
+void BSP_LCD_SetXSize(uint32_t imageWidthPixels);
+void BSP_LCD_SetYSize(uint32_t imageHeightPixels);
+
+/* Functions using the LTDC controller */
+void BSP_LCD_LayerDefaultInit(uint16_t LayerIndex, uint32_t FrameBuffer);
+void BSP_LCD_SetTransparency(uint32_t LayerIndex, uint8_t Transparency);
+void BSP_LCD_SetTransparency_NoReload(uint32_t LayerIndex, uint8_t Transparency);
+void BSP_LCD_SetLayerAddress(uint32_t LayerIndex, uint32_t Address);
+void BSP_LCD_SetLayerAddress_NoReload(uint32_t LayerIndex, uint32_t Address);
+void BSP_LCD_SetColorKeying(uint32_t LayerIndex, uint32_t RGBValue);
+void BSP_LCD_SetColorKeying_NoReload(uint32_t LayerIndex, uint32_t RGBValue);
+void BSP_LCD_ResetColorKeying(uint32_t LayerIndex);
+void BSP_LCD_ResetColorKeying_NoReload(uint32_t LayerIndex);
+void BSP_LCD_SetLayerWindow(uint16_t LayerIndex, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+void BSP_LCD_SetLayerWindow_NoReload(uint16_t LayerIndex, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+void BSP_LCD_SelectLayer(uint32_t LayerIndex);
+void BSP_LCD_SetLayerVisible(uint32_t LayerIndex, FunctionalState State);
+void BSP_LCD_SetLayerVisible_NoReload(uint32_t LayerIndex, FunctionalState State);
+void BSP_LCD_Relaod(uint32_t ReloadType);
+
+void BSP_LCD_SetTextColor(uint32_t Color);
+uint32_t BSP_LCD_GetTextColor(void);
+void BSP_LCD_SetBackColor(uint32_t Color);
+uint32_t BSP_LCD_GetBackColor(void);
+void BSP_LCD_SetFont(sFONT *fonts);
+sFONT *BSP_LCD_GetFont(void);
+
+uint32_t BSP_LCD_ReadPixel(uint16_t Xpos, uint16_t Ypos);
+void BSP_LCD_DrawPixel(uint16_t Xpos, uint16_t Ypos, uint32_t pixel);
+void BSP_LCD_Clear(uint32_t Color);
+void BSP_LCD_ClearStringLine(uint32_t Line);
+void BSP_LCD_DisplayStringAtLine(uint16_t Line, uint8_t *ptr);
+void BSP_LCD_DisplayStringAt(uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Text_AlignModeTypdef Mode);
+void BSP_LCD_DisplayChar(uint16_t Xpos, uint16_t Ypos, uint8_t Ascii);
+
+void BSP_LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+void BSP_LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+void BSP_LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+void BSP_LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+void BSP_LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+void BSP_LCD_DrawPolygon(pPoint Points, uint16_t PointCount);
+void BSP_LCD_DrawEllipse(int Xpos, int Ypos, int XRadius, int YRadius);
+void BSP_LCD_DrawBitmap(uint32_t Xpos, uint32_t Ypos, uint8_t *pbmp);
+
+void BSP_LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+void BSP_LCD_FillCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+void BSP_LCD_FillPolygon(pPoint Points, uint16_t PointCount);
+void BSP_LCD_FillEllipse(int Xpos, int Ypos, int XRadius, int YRadius);
+
+void BSP_LCD_DisplayOff(void);
+void BSP_LCD_DisplayOn(void);
+
+/* These functions can be modified in case the current settings
+ need to be changed for specific application needs */
+void BSP_LCD_MspInit(LTDC_HandleTypeDef *hltdc, void *Params);
+void BSP_LCD_MspDeInit(LTDC_HandleTypeDef *hltdc, void *Params);
+void BSP_LCD_ClockConfig(LTDC_HandleTypeDef *hltdc, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32756G_EVAL_LCD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_nor.c b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_nor.c
new file mode 100644
index 00000000..1b1d0948
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_nor.c
@@ -0,0 +1,456 @@
+/**
+ ******************************************************************************
+ * @file stm32756g_eval_nor.c
+ * @author MCD Application Team
+ * @brief This file includes a standard driver for the PC28F128M29EWLA NOR flash memory
+ * device mounted on STM32756G-EVAL and STM32746G-EVAL evaluation boards.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ - This driver is used to drive the PC28F128M29EWLA NOR flash external memory mounted
+ on STM32756G-EVAL evaluation board.
+ - This driver does not need a specific component driver for the NOR device
+ to be included with.
+
+ Driver description:
+ ------------------
+ + Initialization steps:
+ o Initialize the NOR external memory using the BSP_NOR_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ FMC controller configuration to interface with the external NOR memory.
+
+ + NOR flash operations
+ o NOR external memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_NOR_ReadData()/BSP_NOR_WriteData(). The BSP_NOR_WriteData() performs write operation
+ of an amount of data by unit (halfword). You can also perform a program data
+ operation of an amount of data using the function BSP_NOR_ProgramData().
+ o The function BSP_NOR_Read_ID() returns the chip IDs stored in the structure
+ "NOR_IDTypeDef". (see the NOR IDs in the memory data sheet)
+ o Perform erase block operation using the function BSP_NOR_Erase_Block() and by
+ specifying the block address. You can perform an erase operation of the whole
+ chip by calling the function BSP_NOR_Erase_Chip().
+ o After other operations, the function BSP_NOR_ReturnToReadMode() allows the NOR
+ flash to return to read mode to perform read operations on it.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32756G_EVAL_NOR_H
+#define __STM32756G_EVAL_NOR_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL_NOR
+ * @{
+ */
+
+/** @defgroup STM32756G_EVAL_NOR_Exported_Types NOR Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/**
+ * @brief NOR status structure definition
+ */
+#define NOR_STATUS_OK ((uint8_t)0x00)
+#define NOR_STATUS_ERROR ((uint8_t)0x01)
+
+/** @defgroup STM32756G_EVAL_NOR_Exported_Constants NOR Exported Constants
+ * @{
+ */
+#define NOR_DEVICE_ADDR ((uint32_t)0x60000000)
+
+/* #define NOR_MEMORY_WIDTH FMC_NORSRAM_MEM_BUS_WIDTH_8 */
+#define NOR_MEMORY_WIDTH FMC_NORSRAM_MEM_BUS_WIDTH_16
+
+#define NOR_BURSTACCESS FMC_BURST_ACCESS_MODE_DISABLE
+/* #define NOR_BURSTACCESS FMC_BURST_ACCESS_MODE_ENABLE*/
+
+#define NOR_WRITEBURST FMC_WRITE_BURST_DISABLE
+/* #define NOR_WRITEBURST FMC_WRITE_BURST_ENABLE */
+
+#define CONTINUOUSCLOCK_FEATURE FMC_CONTINUOUS_CLOCK_SYNC_ONLY
+/* #define CONTINUOUSCLOCK_FEATURE FMC_CONTINUOUS_CLOCK_SYNC_ASYNC */
+
+/* NOR operations Timeout definitions */
+#define BLOCKERASE_TIMEOUT ((uint32_t)0x00A00000) /* NOR block erase timeout */
+#define CHIPERASE_TIMEOUT ((uint32_t)0x30000000) /* NOR chip erase timeout */
+#define PROGRAM_TIMEOUT ((uint32_t)0x00004400) /* NOR program timeout */
+
+/* NOR Ready/Busy signal GPIO definitions */
+#define NOR_READY_BUSY_PIN GPIO_PIN_6
+#define NOR_READY_BUSY_GPIO GPIOD
+#define NOR_READY_STATE GPIO_PIN_SET
+#define NOR_BUSY_STATE GPIO_PIN_RESET
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_NOR_Exported_Macro NOR Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_NOR_Exported_Functions NOR Exported Functions
+ * @{
+ */
+uint8_t BSP_NOR_Init(void);
+uint8_t BSP_NOR_DeInit(void);
+uint8_t BSP_NOR_ReadData(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+uint8_t BSP_NOR_WriteData(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+uint8_t BSP_NOR_ProgramData(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+uint8_t BSP_NOR_Erase_Block(uint32_t BlockAddress);
+uint8_t BSP_NOR_Erase_Chip(void);
+uint8_t BSP_NOR_Read_ID(NOR_IDTypeDef *pNOR_ID);
+void BSP_NOR_ReturnToReadMode(void);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_NOR_MspInit(NOR_HandleTypeDef *hnor, void *Params);
+void BSP_NOR_MspDeInit(NOR_HandleTypeDef *hnor, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32756G_EVAL_NOR_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_qspi.c b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_qspi.c
new file mode 100644
index 00000000..34c6c948
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_qspi.c
@@ -0,0 +1,847 @@
+/**
+ ******************************************************************************
+ * @file stm32756g_eval_qspi.c
+ * @author MCD Application Team
+ * @brief This file includes a standard driver for the N25Q512A QSPI
+ * memory mounted on STM32756G-EVAL and STM32746G-EVAL board.
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) This driver is used to drive the N25Q512A QSPI external
+ memory mounted on STM32756G-EVAL and STM32746G-EVAL evaluation board.
+
+ (#) This driver need a specific component driver (N25Q512A) to be included with.
+
+ (#) Initialization steps:
+ (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ QSPI interface with the external memory.
+
+ (#) QSPI memory operations
+ (++) QSPI memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_QSPI_Read()/BSP_QSPI_Write().
+ (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory.
+ (see the QSPI memory data sheet)
+ (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by
+ specifying the block address. You can perform an erase operation of the whole
+ chip by calling the function BSP_QSPI_Erase_Chip().
+ (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory.
+ (see the QSPI memory data sheet)
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL
+ * @{
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32756G_EVAL_QSPI_H
+#define __STM32756G_EVAL_QSPI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+#include "../Components/n25q512a/n25q512a.h"
+
+/** @addtogroup STM32756G_EVAL_QSPI
+ * @{
+ */
+
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup STM32756G_EVAL_QSPI_Exported_Constants Exported Constants
+ * @{
+ */
+/* QSPI Error codes */
+#define QSPI_OK ((uint8_t)0x00)
+#define QSPI_ERROR ((uint8_t)0x01)
+#define QSPI_BUSY ((uint8_t)0x02)
+#define QSPI_NOT_SUPPORTED ((uint8_t)0x04)
+#define QSPI_SUSPENDED ((uint8_t)0x08)
+
+
+/* Definition for QSPI clock resources */
+#define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE()
+#define QSPI_CLK_DISABLE() __HAL_RCC_QSPI_CLK_DISABLE()
+#define QSPI_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define QSPI_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define QSPI_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
+#define QSPI_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
+#define QSPI_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
+#define QSPI_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
+
+#define QSPI_FORCE_RESET() __HAL_RCC_QSPI_FORCE_RESET()
+#define QSPI_RELEASE_RESET() __HAL_RCC_QSPI_RELEASE_RESET()
+
+/* Definition for QSPI Pins */
+#define QSPI_CS_PIN GPIO_PIN_6
+#define QSPI_CS_GPIO_PORT GPIOB
+#define QSPI_CLK_PIN GPIO_PIN_2
+#define QSPI_CLK_GPIO_PORT GPIOB
+#define QSPI_D0_PIN GPIO_PIN_8
+#define QSPI_D0_GPIO_PORT GPIOF
+#define QSPI_D1_PIN GPIO_PIN_9
+#define QSPI_D1_GPIO_PORT GPIOF
+#define QSPI_D2_PIN GPIO_PIN_7
+#define QSPI_D2_GPIO_PORT GPIOF
+#define QSPI_D3_PIN GPIO_PIN_6
+#define QSPI_D3_GPIO_PORT GPIOF
+
+/* N25Q512A13GSF40E Micron memory */
+/* Size of the flash */
+#define QSPI_FLASH_SIZE 25 /* Address bus width to access whole memory space */
+#define QSPI_PAGE_SIZE 256
+
+/* This alias is added as the name of Memory mapped fucntion changed */
+#define BSP_QSPI_MemoryMappedMode BSP_QSPI_EnableMemoryMappedMode
+/**
+ * @}
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup STM32756G_EVAL_QSPI_Exported_Types Exported Types
+ * @{
+ */
+/* QSPI Info */
+typedef struct {
+ uint32_t FlashSize; /*!< Size of the flash */
+ uint32_t EraseSectorSize; /*!< Size of sectors for the erase operation */
+ uint32_t EraseSectorsNumber; /*!< Number of sectors for the erase operation */
+ uint32_t ProgPageSize; /*!< Size of pages for the program operation */
+ uint32_t ProgPagesNumber; /*!< Number of pages for the program operation */
+} QSPI_Info;
+
+/**
+ * @}
+ */
+
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup STM32756G_EVAL_QSPI_Exported_Functions
+ * @{
+ */
+uint8_t BSP_QSPI_Init (void);
+uint8_t BSP_QSPI_DeInit (void);
+uint8_t BSP_QSPI_Read (uint8_t* pData, uint32_t ReadAddr, uint32_t Size);
+uint8_t BSP_QSPI_Write (uint8_t* pData, uint32_t WriteAddr, uint32_t Size);
+uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress);
+uint8_t BSP_QSPI_Erase_Chip (void);
+uint8_t BSP_QSPI_GetStatus (void);
+uint8_t BSP_QSPI_GetInfo (QSPI_Info* pInfo);
+uint8_t BSP_QSPI_EnableMemoryMappedMode(void);
+
+/* These functions can be modified in case the current settings
+ need to be changed for specific application needs */
+void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params);
+void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32756G_EVAL_QSPI_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_sd.c b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_sd.c
new file mode 100644
index 00000000..b6366b72
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_sd.c
@@ -0,0 +1,612 @@
+/**
+ ******************************************************************************
+ * @file stm32756g_eval_sd.c
+ * @author MCD Application Team
+ * @brief This file includes the uSD card driver mounted on STM32756G-EVAL and
+ * STM32746G-EVAL evaluation boards.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ - This driver is used to drive the micro SD external card mounted on STM32756G-EVAL
+ evaluation board.
+ - This driver does not need a specific component driver for the micro SD device
+ to be included with.
+
+ Driver description:
+ ------------------
+ + Initialization steps:
+ o Initialize the micro SD card using the BSP_SD_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ SDIO interface configuration to interface with the external micro SD. It
+ also includes the micro SD initialization sequence.
+ o To check the SD card presence you can use the function BSP_SD_IsDetected() which
+ returns the detection status
+ o If SD presence detection interrupt mode is desired, you must configure the
+ SD detection interrupt mode by calling the function BSP_SD_ITConfig(). The interrupt
+ is generated as an external interrupt whenever the micro SD card is
+ plugged/unplugged in/from the evaluation board. The SD detection is managed by MFX,
+ so the SD detection interrupt has to be treated by MFX_IRQOUT gpio pin IRQ handler.
+ o The function BSP_SD_GetCardInfo() is used to get the micro SD card information
+ which is stored in the structure "HAL_SD_CardInfoTypedef".
+
+ + Micro SD card operations
+ o The micro SD card can be accessed with read/write block(s) operations once
+ it is ready for access. The access can be performed whether using the polling
+ mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks(), or by DMA
+ transfer using the functions BSP_SD_ReadBlocks_DMA()/BSP_SD_WriteBlocks_DMA()
+ o The DMA transfer complete is used with interrupt mode. Once the SD transfer
+ is complete, the SD interrupt is handled using the function BSP_SD_IRQHandler(),
+ the DMA Tx/Rx transfer complete are handled using the functions
+ BSP_SD_DMA_Tx_IRQHandler()/BSP_SD_DMA_Rx_IRQHandler(). The corresponding user callbacks
+ are implemented by the user at application level.
+ o The SD erase block(s) is performed using the function BSP_SD_Erase() with specifying
+ the number of blocks to erase.
+ o The SD runtime status is returned when calling the function BSP_SD_GetCardState().
+
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32756G_EVAL_SD_H
+#define __STM32756G_EVAL_SD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+#include "stm32756g_eval_io.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL_SD
+ * @{
+ */
+
+/** @defgroup STM32756G_EVAL_SD_Exported_Types SD Exported Types
+ * @{
+ */
+
+/**
+ * @brief SD Card information structure
+ */
+#define BSP_SD_CardInfo HAL_SD_CardInfoTypeDef
+/**
+ * @}
+ */
+
+/**
+ * @brief SD status structure definition
+ */
+#define MSD_OK ((uint8_t)0x00)
+#define MSD_ERROR ((uint8_t)0x01)
+#define MSD_ERROR_SD_NOT_PRESENT ((uint8_t)0x02)
+
+/**
+ * @brief SD transfer state definition
+ */
+#define SD_TRANSFER_OK ((uint8_t)0x00)
+#define SD_TRANSFER_BUSY ((uint8_t)0x01)
+
+/** @defgroup STM32756G_EVAL_SD_Exported_Constants SD Exported Constants
+ * @{
+ */
+#define SD_PRESENT ((uint8_t)0x01)
+#define SD_NOT_PRESENT ((uint8_t)0x00)
+
+#define SD_DATATIMEOUT ((uint32_t)100000000)
+
+/* DMA definitions for SD DMA transfer */
+#define __DMAx_TxRx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
+#define SD_DMAx_Tx_CHANNEL DMA_CHANNEL_4
+#define SD_DMAx_Rx_CHANNEL DMA_CHANNEL_4
+#define SD_DMAx_Tx_STREAM DMA2_Stream6
+#define SD_DMAx_Rx_STREAM DMA2_Stream3
+#define SD_DMAx_Tx_IRQn DMA2_Stream6_IRQn
+#define SD_DMAx_Rx_IRQn DMA2_Stream3_IRQn
+#define BSP_SDMMC_IRQHandler SDMMC1_IRQHandler
+#define BSP_SDMMC_DMA_Tx_IRQHandler DMA2_Stream6_IRQHandler
+#define BSP_SDMMC_DMA_Rx_IRQHandler DMA2_Stream3_IRQHandler
+#define SD_DetectIRQHandler() HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8)
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_SD_Exported_Macro SD Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_SD_Exported_Functions SD Exported Functions
+ * @{
+ */
+uint8_t BSP_SD_Init(void);
+uint8_t BSP_SD_DeInit(void);
+uint8_t BSP_SD_ITConfig(void);
+void BSP_SD_DetectIT(void);
+void BSP_SD_DetectCallback(void);
+uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout);
+uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout);
+uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks);
+uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks);
+uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr);
+uint8_t BSP_SD_GetCardState(void);
+void BSP_SD_GetCardInfo(BSP_SD_CardInfo *CardInfo);
+uint8_t BSP_SD_IsDetected(void);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params);
+void BSP_SD_MspDeInit(SD_HandleTypeDef *hsd, void *Params);
+void BSP_SD_AbortCallback(void);
+void BSP_SD_WriteCpltCallback(void);
+void BSP_SD_ReadCpltCallback(void);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32756G_EVAL_SD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_sdram.c b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_sdram.c
new file mode 100644
index 00000000..f30a48f2
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_sdram.c
@@ -0,0 +1,504 @@
+/**
+ ******************************************************************************
+ * @file stm32756g_eval_sdram.c
+ * @author MCD Application Team
+ * @brief This file includes the SDRAM driver for the MT48LC4M32B2B5-7 memory
+ * device mounted on STM32756G-EVAL and STM32746G-EVAL evaluation boards.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ - This driver is used to drive the MT48LC4M32B2B5-7 SDRAM external memory mounted
+ on STM32756G-EVAL evaluation board.
+ - This driver does not need a specific component driver for the SDRAM device
+ to be included with.
+
+ Driver description:
+ ------------------
+ + Initialization steps:
+ o Initialize the SDRAM external memory using the BSP_SDRAM_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ FMC controller configuration to interface with the external SDRAM memory.
+ o It contains the SDRAM initialization sequence to program the SDRAM external
+ device using the function BSP_SDRAM_Initialization_sequence(). Note that this
+ sequence is standard for all SDRAM devices, but can include some differences
+ from a device to another. If it is the case, the right sequence should be
+ implemented separately.
+
+ + SDRAM read/write operations
+ o SDRAM external memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_SDRAM_ReadData()/BSP_SDRAM_WriteData(), or by DMA transfer using the functions
+ BSP_SDRAM_ReadData_DMA()/BSP_SDRAM_WriteData_DMA().
+ o The AHB access is performed with 32-bit width transaction, the DMA transfer
+ configuration is fixed at single (no burst) word transfer (see the
+ SDRAM_MspInit() static function).
+ o User can implement his own functions for read/write access with his desired
+ configurations.
+ o If interrupt mode is used for DMA transfer, the function BSP_SDRAM_DMA_IRQHandler()
+ is called in IRQ handler file, to serve the generated interrupt once the DMA
+ transfer is complete.
+ o You can send a command to the SDRAM device in runtime using the function
+ BSP_SDRAM_Sendcmd(), and giving the desired command as parameter chosen between
+ the predefined commands of the "FMC_SDRAM_CommandTypeDef" structure.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32756G_EVAL_SDRAM_H
+#define __STM32756G_EVAL_SDRAM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL_SDRAM
+ * @{
+ */
+
+/** @defgroup STM32756G_EVAL_SDRAM_Exported_Types SDRAM Exported Types
+ * @{
+ */
+
+/**
+ * @brief SDRAM status structure definition
+ */
+#define SDRAM_OK ((uint8_t)0x00)
+#define SDRAM_ERROR ((uint8_t)0x01)
+
+/** @defgroup STM32756G_EVAL_SDRAM_Exported_Constants SDRAM Exported Constants
+ * @{
+ */
+#define SDRAM_DEVICE_ADDR ((uint32_t)0xC0000000)
+#define SDRAM_DEVICE_SIZE ((uint32_t)0x800000) /* SDRAM device size in MBytes */
+
+/* #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_8 */
+/* #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16 */
+#define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_32
+
+#define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_2
+/* #define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_3 */
+
+#define REFRESH_COUNT ((uint32_t)0x0603) /* SDRAM refresh counter (100Mhz SD clock) */
+
+#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
+
+/* DMA definitions for SDRAM DMA transfer */
+#define __DMAx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
+#define __DMAx_CLK_DISABLE __HAL_RCC_DMA2_CLK_DISABLE
+#define SDRAM_DMAx_CHANNEL DMA_CHANNEL_0
+#define SDRAM_DMAx_STREAM DMA2_Stream0
+#define SDRAM_DMAx_IRQn DMA2_Stream0_IRQn
+#define BSP_SDRAM_DMA_IRQHandler DMA2_Stream0_IRQHandler
+/**
+ * @}
+ */
+
+/**
+ * @brief FMC SDRAM Mode definition register defines
+ */
+#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
+#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
+#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
+#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
+#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
+#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
+#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
+#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
+#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
+#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
+#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_SDRAM_Exported_Macro SDRAM Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_SDRAM_Exported_Functions SDRAM Exported Functions
+ * @{
+ */
+uint8_t BSP_SDRAM_Init(void);
+uint8_t BSP_SDRAM_DeInit(void);
+void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount);
+uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram, void *Params);
+void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram, void *Params);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32756G_EVAL_SDRAM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_sram.c b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_sram.c
new file mode 100644
index 00000000..1ab2055d
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_sram.c
@@ -0,0 +1,402 @@
+/**
+ ******************************************************************************
+ * @file stm32756g_eval_sram.c
+ * @author MCD Application Team
+ * @brief This file includes the SRAM driver for the IS61WV102416BLL-10M memory
+ * device mounted on STM32756G-EVAL and STM32746G-EVAL evaluation boards.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ - This driver is used to drive the IS61WV102416BLL-10M SRAM external memory mounted
+ on STM32756G-EVAL evaluation board.
+ - This driver does not need a specific component driver for the SRAM device
+ to be included with.
+
+ Driver description:
+ ------------------
+ + Initialization steps:
+ o Initialize the SRAM external memory using the BSP_SRAM_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ FMC controller configuration to interface with the external SRAM memory.
+
+ + SRAM read/write operations
+ o SRAM external memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_SRAM_ReadData()/BSP_SRAM_WriteData(), or by DMA transfer using the functions
+ BSP_SRAM_ReadData_DMA()/BSP_SRAM_WriteData_DMA().
+ o The AHB access is performed with 16-bit width transaction, the DMA transfer
+ configuration is fixed at single (no burst) halfword transfer
+ (see the SRAM_MspInit() static function).
+ o User can implement his own functions for read/write access with his desired
+ configurations.
+ o If interrupt mode is used for DMA transfer, the function BSP_SRAM_DMA_IRQHandler()
+ is called in IRQ handler file, to serve the generated interrupt once the DMA
+ transfer is complete.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32756G_EVAL_SRAM_H
+#define __STM32756G_EVAL_SRAM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL_SRAM
+ * @{
+ */
+
+/** @defgroup STM32756G_EVAL_SRAM_Exported_Types SRAM Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_SRAM_Exported_Constants SRAM Exported Constants
+ * @{
+ */
+
+/**
+ * @brief SRAM status structure definition
+ */
+#define SRAM_OK ((uint8_t)0x00)
+#define SRAM_ERROR ((uint8_t)0x01)
+
+#define SRAM_DEVICE_ADDR ((uint32_t)0x68000000)
+#define SRAM_DEVICE_SIZE ((uint32_t)0x200000) /* SRAM device size in MBytes */
+
+/* #define SRAM_MEMORY_WIDTH FMC_NORSRAM_MEM_BUS_WIDTH_8*/
+#define SRAM_MEMORY_WIDTH FMC_NORSRAM_MEM_BUS_WIDTH_16
+
+#define SRAM_BURSTACCESS FMC_BURST_ACCESS_MODE_DISABLE
+/* #define SRAM_BURSTACCESS FMC_BURST_ACCESS_MODE_ENABLE*/
+
+#define SRAM_WRITEBURST FMC_WRITE_BURST_DISABLE
+/* #define SRAM_WRITEBURST FMC_WRITE_BURST_ENABLE */
+
+#define CONTINUOUSCLOCK_FEATURE FMC_CONTINUOUS_CLOCK_SYNC_ONLY
+/* #define CONTINUOUSCLOCK_FEATURE FMC_CONTINUOUS_CLOCK_SYNC_ASYNC */
+
+/* DMA definitions for SRAM DMA transfer */
+#define __SRAM_DMAx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
+#define __SRAM_DMAx_CLK_DISABLE __HAL_RCC_DMA2_CLK_DISABLE
+#define SRAM_DMAx_CHANNEL DMA_CHANNEL_0
+#define SRAM_DMAx_STREAM DMA2_Stream4
+#define SRAM_DMAx_IRQn DMA2_Stream4_IRQn
+#define BSP_SRAM_DMA_IRQHandler DMA2_Stream4_IRQHandler
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_SRAM_Exported_Macro SRAM Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_SRAM_Exported_Functions SRAM Exported Functions
+ * @{
+ */
+uint8_t BSP_SRAM_Init(void);
+uint8_t BSP_SRAM_DeInit(void);
+uint8_t BSP_SRAM_ReadData(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SRAM_ReadData_DMA(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SRAM_WriteData(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SRAM_WriteData_DMA(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_SRAM_MspInit(SRAM_HandleTypeDef *hsram, void *Params);
+void BSP_SRAM_MspDeInit(SRAM_HandleTypeDef *hsram, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32756G_EVAL_SRAM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_ts.c b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_ts.c
new file mode 100644
index 00000000..53f6df30
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32756G_EVAL/stm32756g_eval_ts.c
@@ -0,0 +1,305 @@
+/**
+ ******************************************************************************
+ * @file stm32756g_eval_ts.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the Touch
+ * Screen on STM32756G-EVAL and STM32746G-EVAL evaluation boards.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ - This driver is used to drive the touch screen module of the STM32756G-EVAL
+ evaluation board on the AMPIRE 640x480 LCD mounted on MB1063 or AMPIRE
+ 480x272 LCD mounted on MB1046 daughter board.
+ - If the AMPIRE 640x480 LCD is used, the TS3510 or EXC7200 component driver
+ must be included according to the touch screen driver present on this board.
+ - If the AMPIRE 480x272 LCD is used, the STMPE811 IO expander device component
+ driver must be included in order to run the TS module commanded by the IO
+ expander device, the MFXSTM32L152 IO expander device component driver must be
+ also included in case of interrupt mode use of the TS.
+
+ Driver description:
+ ------------------
+ + Initialization steps:
+ o Initialize the TS module using the BSP_TS_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ communication layer configuration to start the TS use. The LCD size properties
+ (x and y) are passed as parameters.
+ o If TS interrupt mode is desired, you must configure the TS interrupt mode
+ by calling the function BSP_TS_ITConfig(). The TS interrupt mode is generated
+ as an external interrupt whenever a touch is detected.
+ The interrupt mode internally uses the IO functionalities driver driven by
+ the IO expander, to configure the IT line.
+
+ + Touch screen use
+ o The touch screen state is captured whenever the function BSP_TS_GetState() is
+ used. This function returns information about the last LCD touch occurred
+ in the TS_StateTypeDef structure.
+ o If TS interrupt mode is used, the function BSP_TS_ITGetStatus() is needed to get
+ the interrupt status. To clear the IT pending bits, you should call the
+ function BSP_TS_ITClear().
+ o The IT is handled using the corresponding external interrupt IRQ handler,
+ the user IT callback treatment is implemented on the same external interrupt
+ callback.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32756G_EVAL_TS_H
+#define __STM32756G_EVAL_TS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32756g_eval.h"
+/* Include IOExpander(STMPE811) component Driver */
+#include "../Components/stmpe811/stmpe811.h"
+/* Include TouchScreen component drivers */
+#include "../Components/ts3510/ts3510.h"
+#include "../Components/exc7200/exc7200.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32756G_EVAL_TS
+ * @{
+ */
+
+/** @defgroup STM32756G_EVAL_TS_Exported_Types TS Exported Types
+ * @{
+ */
+typedef struct
+{
+ uint16_t TouchDetected;
+ uint16_t x;
+ uint16_t y;
+ uint16_t z;
+}TS_StateTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_TS_Exported_Constants TS Exported Constants
+ * @{
+ */
+#define TS_SWAP_NONE ((uint8_t)0x00)
+#define TS_SWAP_X ((uint8_t)0x01)
+#define TS_SWAP_Y ((uint8_t)0x02)
+#define TS_SWAP_XY ((uint8_t)0x04)
+
+typedef enum
+{
+ TS_OK = 0x00,
+ TS_ERROR = 0x01,
+ TS_TIMEOUT = 0x02
+}TS_StatusTypeDef;
+
+/* Interrupt sources pins definition */
+#define TS_INT_PIN LCD_INT_PIN
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_TS_Exported_Macros TS Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32756G_EVAL_TS_Exported_Functions TS Exported Functions
+ * @{
+ */
+uint8_t BSP_TS_Init(uint16_t xSize, uint16_t ySize);
+uint8_t BSP_TS_DeInit(void);
+uint8_t BSP_TS_GetState(TS_StateTypeDef *TS_State);
+uint8_t BSP_TS_ITConfig(void);
+uint8_t BSP_TS_ITGetStatus(void);
+void BSP_TS_ITClear(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32756G_EVAL_TS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/Release_Notes.html b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/Release_Notes.html
new file mode 100644
index 00000000..9826b8da
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/Release_Notes.html
@@ -0,0 +1,358 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Release Notes for STM32F723E-Discovery Kit BSP Drivers
+
+
+
+
+
+
+
+
+
+
+
+
Release
+Notes for STM32F723E-Discovery Board Drivers
+
Copyright
+2016 STMicroelectronics
+
+
+
+
+
+
+
+
+
+
The BSP (Board Specific
+Package) drivers are parts of the STM32Cube package based on the HAL
+drivers and provide a set of high level APIs relative to the hardware
+components and features in the evaluation boards, discovery kits and nucleo
+boards coming with the STM32Cube package for a given STM32 serie.
+
The BSP drivers allow a quick access to the boards’
+services using high level APIs and without any specific configuration as the
+link with the HAL and the external components is done in intrinsic within the drivers.
+
+
From project settings points of view, user has only
+to add the necessary driver’s files in the workspace and call the needed
+functions from examples. However some low level
+configuration functions are weak and can be overridden by the applications if user
+wants to change some BSP drivers default behavior.
First official Release for STM32F723E-Discovery
+board drivers.
Dependencies
+
+
+
+
+
+
+
STM32F7xx_HAL_Driver V1.2.0
+
BSP Common V4.0.1
License
+
+
Redistribution and use in
+source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
+
Redistributions of source
+code must retain the above copyright notice, this list of conditions
+and the following disclaimer.
+
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+
Neither the name of
+STMicroelectronics nor the names of its contributors may be used to
+endorse or promote products derived
+
+
+
+from this software without specific prior written permission.
+
+ THIS
+SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery.c b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery.c
new file mode 100644
index 00000000..d35c1a55
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery.c
@@ -0,0 +1,1053 @@
+/**
+ ******************************************************************************
+ * @file stm32f723e_discovery.c
+ * @author MCD Application Team
+ * @brief This file provides a set of firmware functions to manage LEDs,
+ * push-buttons, external PSRAM, external QSPI Flash, TS available on
+ * STM32F723E-Discovery board (MB1260) from STMicroelectronics.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F723E_DISCOVERY_H
+#define __STM32F723E_DISCOVERY_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+ /* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F723E_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F723E_DISCOVERY_LOW_LEVEL
+ * @{
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_LOW_LEVEL_Exported_Types STM32F723E Discovery Low Level Exported Types
+ * @{
+ */
+
+/**
+ * @brief Define for STM32F723E_DISCOVERY board
+ */
+#if !defined (USE_STM32F723E_DISCO)
+ #define USE_STM32F723E_DISCO
+#endif
+
+/** @brief Led_TypeDef
+ * STM32F723E_Discovery board leds definitions.
+ */
+typedef enum
+{
+ LED5 = 0,
+ LED_RED = LED5,
+ LED6 = 1,
+ LED_GREEN = LED6
+} Led_TypeDef;
+
+/** @brief Button_TypeDef
+ * STM32F723E_Discovery board Buttons definitions.
+ */
+typedef enum
+{
+ BUTTON_WAKEUP = 0,
+} Button_TypeDef;
+
+#define BUTTON_USER BUTTON_WAKEUP
+
+/** @brief ButtonMode_TypeDef
+ * STM32F723E_Discovery board Buttons Modes definitions.
+ */
+typedef enum
+{
+ BUTTON_MODE_GPIO = 0,
+ BUTTON_MODE_EXTI = 1
+
+} ButtonMode_TypeDef;
+
+typedef enum
+{
+ PB_SET = 0,
+ PB_RESET = !PB_SET
+} ButtonValue_TypeDef;
+
+typedef enum
+{
+ COM1 = 0,
+}COM_TypeDef;
+
+/** @brief DISCO_Status_TypeDef
+ * STM32F723E_DISCO board Status return possible values.
+ */
+typedef enum
+{
+ DISCO_OK = 0,
+ DISCO_ERROR = 1
+
+} DISCO_Status_TypeDef;
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F723E_DISCOVERY_LOW_LEVEL_LED STM32F723E Discovery Low Level Led
+ * @{
+ */
+/* Always four leds for all revisions of Discovery boards */
+#define LEDn ((uint8_t)2)
+
+
+/* 2 Leds are connected to MCU directly on PA7 and PB1 */
+#define LED5_GPIO_PORT ((GPIO_TypeDef*)GPIOA)
+#define LED6_GPIO_PORT ((GPIO_TypeDef*)GPIOB)
+
+#define LED5_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define LED6_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+
+#define LED5_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define LED6_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
+
+
+#define LEDx_GPIO_CLK_ENABLE(__INDEX__) do{if((__INDEX__) == 0) LED5_GPIO_CLK_ENABLE(); else \
+ if((__INDEX__) == 1) LED6_GPIO_CLK_ENABLE(); \
+ }while(0)
+
+#define LEDx_GPIO_CLK_DISABLE(__INDEX__) do{if((__INDEX__) == 0) LED5_GPIO_CLK_DISABLE(); else \
+ if((__INDEX__) == 1) LED6_GPIO_CLK_DISABLE(); \
+ }while(0)
+
+#define LED5_PIN ((uint32_t)GPIO_PIN_7)
+#define LED6_PIN ((uint32_t)GPIO_PIN_1)
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F723E_DISCOVERY_LOW_LEVEL_BUTTON STM32F723E Discovery Low Level Button
+ * @{
+ */
+/* Only one User/Wakeup button */
+#define BUTTONn ((uint8_t)1)
+
+/**
+ * @brief Wakeup push-button
+ */
+#define WAKEUP_BUTTON_PIN GPIO_PIN_0
+#define WAKEUP_BUTTON_GPIO_PORT GPIOA
+#define WAKEUP_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define WAKEUP_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define WAKEUP_BUTTON_EXTI_IRQn EXTI0_IRQn
+
+/* Define the USER button as an alias of the Wakeup button */
+#define USER_BUTTON_PIN WAKEUP_BUTTON_PIN
+#define USER_BUTTON_GPIO_PORT WAKEUP_BUTTON_GPIO_PORT
+#define USER_BUTTON_GPIO_CLK_ENABLE() WAKEUP_BUTTON_GPIO_CLK_ENABLE()
+#define USER_BUTTON_GPIO_CLK_DISABLE() WAKEUP_BUTTON_GPIO_CLK_DISABLE()
+#define USER_BUTTON_EXTI_IRQn WAKEUP_BUTTON_EXTI_IRQn
+
+#define BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_LOW_LEVEL_Exported_Constants LOW_LEVEL Exported Constants
+ * @{
+ */
+/**
+ * @brief USB OTG HS Over Current signal
+ */
+#define OTG_HS_OVER_CURRENT_PIN GPIO_PIN_10
+#define OTG_HS_OVER_CURRENT_PORT GPIOH
+#define OTG_HS_OVER_CURRENT_PORT_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+
+/**
+ * @brief USB OTG FS Over Current signal
+ */
+#define OTG_FS_OVER_CURRENT_PIN GPIO_PIN_8
+#define OTG_FS_OVER_CURRENT_PORT GPIOC
+#define OTG_FS_OVER_CURRENT_PORT_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+
+/**
+ * @brief TS_INT signal from TouchScreen
+ */
+#define TS_INT_PIN ((uint32_t)GPIO_PIN_9)
+#define TS_INT_GPIO_PORT ((GPIO_TypeDef*)GPIOI)
+#define TS_INT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define TS_INT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define TS_INT_EXTI_IRQn EXTI9_5_IRQn
+
+/**
+ * @brief TS RESET pin
+ */
+#define TS_RESET_PIN GPIO_PIN_9
+#define TS_RESET_GPIO_PORT GPIOH
+#define TS_RESET_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+#define TS_RESET_GPIO_CLK_DISABLE() __HAL_RCC_GPIOH_CLK_DISABLE()
+#define TS_RESET_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @brief Definition for I2C3 Touchscreen Pins
+ * resources (touchescreen).
+ * Definition for I2C3 clock resources
+ */
+#define TS_I2Cx I2C3
+#define TS_I2Cx_CLK_ENABLE() __HAL_RCC_I2C3_CLK_ENABLE()
+#define TS_I2Cx_SCL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define TS_I2Cx_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+
+#define TS_I2Cx_FORCE_RESET() __HAL_RCC_I2C3_FORCE_RESET()
+#define TS_I2Cx_RELEASE_RESET() __HAL_RCC_I2C3_RELEASE_RESET()
+
+/** @brief Definition for Touchscreen Pins
+ */
+#define TS_I2Cx_SCL_PIN GPIO_PIN_8
+#define TS_I2Cx_SCL_AF GPIO_AF4_I2C3
+#define TS_I2Cx_SCL_GPIO_PORT GPIOA
+#define TS_I2Cx_SDA_PIN GPIO_PIN_8
+#define TS_I2Cx_SDA_AF GPIO_AF4_I2C3
+#define TS_I2Cx_SDA_GPIO_PORT GPIOH
+
+#define TS_I2Cx_EV_IRQn I2C3_EV_IRQn
+#define TS_I2Cx_ER_IRQn I2C3_ER_IRQn
+
+/**
+ * @brief TouchScreen FT6206 Slave I2C address
+ */
+#define TS_I2C_ADDRESS ((uint16_t)0x70)
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F723E_DISCOVERY_LOW_LEVEL_COM STM32F723E DISCOVERY Low Level COM
+ * @{
+ */
+#define COMn ((uint8_t)1)
+
+/**
+ * @brief Definition for COM port1, connected to USART2
+ */
+#define DISCOVERY_COM1 USART2
+#define DISCOVERY_COM1_CLK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE()
+#define DISCOVERY_COM1_CLK_DISABLE() __HAL_RCC_USART2_CLK_DISABLE()
+
+#define DISCOVERY_COM1_TX_PIN GPIO_PIN_3
+#define DISCOVERY_COM1_TX_GPIO_PORT GPIOA
+#define DISCOVERY_COM1_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define DISCOVERY_COM1_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define DISCOVERY_COM1_TX_AF GPIO_AF7_USART2
+
+#define DISCOVERY_COM1_RX_PIN GPIO_PIN_2
+#define DISCOVERY_COM1_RX_GPIO_PORT GPIOA
+#define DISCOVERY_COM1_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define DISCOVERY_COM1_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define DISCOVERY_COM1_RX_AF GPIO_AF7_USART2
+
+#define DISCOVERY_COM1_IRQn USART2_IRQn
+
+#define DISCOVERY_COMx_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) {DISCOVERY_COM1_CLK_ENABLE();} } while(0)
+#define DISCOVERY_COMx_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? DISCOVERY_COM1_CLK_DISABLE() : 0)
+
+#define DISCOVERY_COMx_TX_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) {DISCOVERY_COM1_TX_GPIO_CLK_ENABLE();} } while(0)
+#define DISCOVERY_COMx_TX_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? DISCOVERY_COM1_TX_GPIO_CLK_DISABLE() : 0)
+
+#define DISCOVERY_COMx_RX_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) {DISCOVERY_COM1_RX_GPIO_CLK_ENABLE();} } while(0)
+#define DISCOVERY_COMx_RX_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? DISCOVERY_COM1_RX_GPIO_CLK_DISABLE() : 0)
+
+
+/**
+ * @brief Audio I2C Slave address
+ */
+#define AUDIO_I2C_ADDRESS ((uint16_t)0x34)
+
+/**
+ * @brief User can use this section to tailor I2C1 instance used and associated
+ * resources (audio codec).
+ * Definition for I2C1 clock resources
+ */
+#define DISCOVERY_AUDIO_I2Cx I2C1
+#define DISCOVERY_AUDIO_I2Cx_CLK_ENABLE() __HAL_RCC_I2C1_CLK_ENABLE()
+#define DISCOVERY_AUDIO_I2Cx_SCL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define DISCOVERY_AUDIO_I2Cx_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+
+#define DISCOVERY_AUDIO_I2Cx_FORCE_RESET() __HAL_RCC_I2C1_FORCE_RESET()
+#define DISCOVERY_AUDIO_I2Cx_RELEASE_RESET() __HAL_RCC_I2C1_RELEASE_RESET()
+
+/** @brief Definition for I2C1 Pins
+ */
+#define DISCOVERY_AUDIO_I2Cx_SCL_PIN GPIO_PIN_8 /*!< PB8 */
+#define DISCOVERY_AUDIO_I2Cx_SCL_AF GPIO_AF4_I2C1
+#define DISCOVERY_AUDIO_I2Cx_SCL_GPIO_PORT GPIOB
+#define DISCOVERY_AUDIO_I2Cx_SDA_PIN GPIO_PIN_9 /*!< PB9 */
+#define DISCOVERY_AUDIO_I2Cx_SDA_AF GPIO_AF4_I2C1
+#define DISCOVERY_AUDIO_I2Cx_SDA_GPIO_PORT GPIOB
+/** @brief Definition of I2C1 interrupt requests
+ */
+#define DISCOVERY_AUDIO_I2Cx_EV_IRQn I2C1_EV_IRQn
+#define DISCOVERY_AUDIO_I2Cx_ER_IRQn I2C1_ER_IRQn
+
+
+/* Definition for external, camera and Arduino connector I2Cx resources */
+#define DISCOVERY_EXT_I2Cx I2C2
+#define DISCOVERY_EXT_I2Cx_CLK_ENABLE() __HAL_RCC_I2C2_CLK_ENABLE()
+#define DISCOVERY_EXT_DMAx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
+#define DISCOVERY_EXT_I2Cx_SCL_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+
+#define DISCOVERY_EXT_I2Cx_FORCE_RESET() __HAL_RCC_I2C2_FORCE_RESET()
+#define DISCOVERY_EXT_I2Cx_RELEASE_RESET() __HAL_RCC_I2C2_RELEASE_RESET()
+
+/* Definition for I2Cx Pins */
+#define DISCOVERY_EXT_I2Cx_SCL_PIN GPIO_PIN_4
+#define DISCOVERY_EXT_I2Cx_SCL_SDA_GPIO_PORT GPIOH
+#define DISCOVERY_EXT_I2Cx_SCL_SDA_AF GPIO_AF4_I2C2
+#define DISCOVERY_EXT_I2Cx_SDA_PIN GPIO_PIN_5
+
+/* I2C interrupt requests */
+#define DISCOVERY_EXT_I2Cx_EV_IRQn I2C2_EV_IRQn
+#define DISCOVERY_EXT_I2Cx_ER_IRQn I2C2_ER_IRQn
+
+
+/* I2C TIMING Register define when I2C clock source is SYSCLK */
+/* I2C TIMING is calculated from APB1 source clock = 50 MHz */
+/* Due to the big MOFSET capacity for adapting the camera level the rising time is very large (>1us) */
+/* 0x40912732 takes in account the big rising and aims a clock of 100khz */
+#ifndef DISCOVERY_I2Cx_TIMING
+#define DISCOVERY_I2Cx_TIMING ((uint32_t)0x40912732)
+#endif /* DISCOVERY_I2Cx_TIMING */
+
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_LOW_LEVEL_Exported_Macros STM32F723E Discovery Low Level Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_LOW_LEVEL_Exported_Functions STM32F723E Discovery Low Level Exported Functions
+ * @{
+ */
+uint32_t BSP_GetVersion(void);
+void BSP_LED_Init(Led_TypeDef Led);
+void BSP_LED_DeInit(Led_TypeDef Led);
+void BSP_LED_On(Led_TypeDef Led);
+void BSP_LED_Off(Led_TypeDef Led);
+void BSP_LED_Toggle(Led_TypeDef Led);
+void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef Button_Mode);
+void BSP_PB_DeInit(Button_TypeDef Button);
+uint32_t BSP_PB_GetState(Button_TypeDef Button);
+void BSP_COM_Init(COM_TypeDef COM, UART_HandleTypeDef *huart);
+void BSP_COM_DeInit(COM_TypeDef COM, UART_HandleTypeDef *huart);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F723E_DISCOVERY_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_audio.c b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_audio.c
new file mode 100644
index 00000000..5bb89bd8
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_audio.c
@@ -0,0 +1,1446 @@
+/**
+ ******************************************************************************
+ * @file stm32f723e_discovery_audio.c
+ * @author MCD Application Team
+ * @brief This file provides the Audio driver for the STM32F723E-DISCOVERY
+ * board.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ + This driver supports STM32F7xx devices on STM32F723E-DISCOVERY (MB1260) Evaluation boards.
+ + Call the function BSP_AUDIO_OUT_Init(
+ OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER,
+ OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
+ Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
+ AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...)
+ this parameter is relative to the audio file/stream type.
+ )
+ This function configures all the hardware required for the audio application (codec, I2C, SAI,
+ GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
+ If the returned value is different from AUDIO_OK or the function is stuck then the communication with
+ the codec has failed (try to un-plug the power or reset device in this case).
+ - OUTPUT_DEVICE_SPEAKER : only speaker will be set as output for the audio stream.
+ - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
+ - OUTPUT_DEVICE_BOTH : both Speaker and Headphone are used as outputs for the audio stream
+ at the same time.
+ + Call the function BSP_DISCOVERY_AUDIO_OUT_Play(
+ pBuffer: pointer to the audio data file address
+ Size : size of the buffer to be sent in Bytes
+ )
+ to start playing (for the first time) from the audio file/stream.
+ + Call the function BSP_AUDIO_OUT_Pause() to pause playing
+ + Call the function BSP_AUDIO_OUT_Resume() to resume playing.
+ Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
+ for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
+ Note. This function should be called only when the audio file is played or paused (not stopped).
+ + For each mode, you may need to implement the relative callback functions into your code.
+ The Callback functions are named AUDIO_OUT_XXX_CallBack() and only their prototypes are declared in
+ the stm32f723e_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
+ + To Stop playing, to modify the volume level, the frequency, the audio frame slot,
+ the device output mode the mute or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(),
+ AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetAudioFrameSlot(), BSP_AUDIO_OUT_SetOutputMode(),
+ BSP_AUDIO_OUT_SetMute() and BSP_AUDIO_OUT_Stop().
+ + The driver API and the callback functions are at the end of the stm32f723e_discovery_audio.h file.
+
+ + Call the function BSP_AUDIO_IN_Init(
+ InputDevice: physical input mode (INPUT_DEVICE_DIGITAL_MICROPHONE_1,
+ INPUT_DEVICE_DIGITAL_MICROPHONE_2, INPUT_DEVICE_DIGITAL_MIC1_MIC2
+ or INPUT_DEVICE_INPUT_LINE_1)
+ Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
+ AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000...)
+ this parameter is relative to the audio file/stream type.
+ )
+ This function configures all the hardware required for the AUDIO IN application (SAI blocks,
+ SAI clock source, GPIOs, DMA and interrupt if needed).
+ This function returns AUDIO_OK if configuration is OK.If the returned value is different from AUDIO_OK then
+ the configuration should be wrong.
+ Note: On STM32F723E-DISCOVERY, two SAI blocks are configured and their DMA streams are configured
+ in CIRCULAR mode.
+ + Call the function BSP_AUDIO_IN_RECORD(
+ pBuf: pointer to the recorded audio data file address
+ Size: size of the buffer to be written in Bytes
+ )
+ to start recording from microphones.
+
+ + Call the function BSP_AUDIO_IN_Pause() to pause recording
+ + Call the function BSP_AUDIO_IN_Resume() to recording playing.
+ Note. After calling BSP_AUDIO_IN_Pause() function for pause, only BSP_AUDIO_IN_Resume() should be called
+ for resume (it is not allowed to call BSP_AUDIO_IN_RECORD() in this case).
+ + Call the function BSP_AUDIO_IN_Stop() to stop recording
+ + For each mode, you may need to implement the relative callback functions into your code.
+ The Callback functions are named BSP_AUDIO_IN_XXX_CallBack() and only their prototypes are declared in
+ the stm32f723e_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
+
+ + Call the function BSP_AUDIO_IN_OUT_Init(
+ InputDevice : physical input mode (INPUT_DEVICE_DIGITAL_MICROPHONE_1,
+ INPUT_DEVICE_DIGITAL_MICROPHONE_2, INPUT_DEVICE_DIGITAL_MIC1_MIC2
+ or INPUT_DEVICE_INPUT_LINE_1)
+ OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER,
+ OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
+ Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
+ AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...)
+ this parameter is relative to the audio file/stream type.
+ )
+ This function configures all the hardware required for the AUDIO IN(record) and AUDIO OUT(play)
+ application (SAI blocks, SAI clock source, GPIOs, DMA and interrupt if needed).
+
+ Driver architecture:
+ --------------------
+ + This driver provides the High Audio Layer: consists of the function API exported in the stm32f723e_discovery_audio.h file
+ (BSP_AUDIO_OUT_Init(), BSP_AUDIO_OUT_Play() ...)
+ + This driver provide also the Media Access Layer (MAL): which consists of functions allowing to access the media containing/
+ providing the audio file/stream. These functions are also included as local functions into
+ the stm32f723e_discovery_audio.c file (SAIx_Out_Init() and SAIx_Out_DeInit(), SAIx_In_Init() and SAIx_In_DeInit())
+
+ Known Limitations:
+ ------------------
+ 1- If the TDM Format used to play in parallel 2 audio Stream (the first Stream is configured in codec SLOT0 and second
+ Stream in SLOT1) the Pause/Resume, volume and mute feature will control the both streams.
+ 2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size,
+ File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
+ 3- Supports only Stereo audio streaming.
+ 4- Supports only 16-bits audio data size.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F723E_DISCOVERY_AUDIO_H
+#define __STM32F723E_DISCOVERY_AUDIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include audio component Driver */
+#include "../Components/wm8994/wm8994.h"
+#include "stm32f723e_discovery.h"
+#include
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F723E_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_AUDIO STM32F723E_DISCOVERY_AUDIO
+ * @{
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_AUDIO_Exported_Types STM32F723E_DISCOVERY_AUDIO Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_AUDIO_Exported_Constants STM32F723E_DISCOVERY_AUDIO Exported Constants
+ * @{
+ */
+
+/** @defgroup BSP_Audio_Out_Option BSP Audio Out Option
+ * @{
+ */
+#define BSP_AUDIO_OUT_CIRCULARMODE ((uint32_t)0x00000001) /* BUFFER CIRCULAR MODE */
+#define BSP_AUDIO_OUT_NORMALMODE ((uint32_t)0x00000002) /* BUFFER NORMAL MODE */
+#define BSP_AUDIO_OUT_STEREOMODE ((uint32_t)0x00000004) /* STEREO MODE */
+#define BSP_AUDIO_OUT_MONOMODE ((uint32_t)0x00000008) /* MONO MODE */
+/**
+ * @}
+ */
+/** @defgroup BSP_Audio_Sample_Rate BSP Audio Sample Rate
+ * @{
+ */
+#define BSP_AUDIO_FREQUENCY_96K SAI_AUDIO_FREQUENCY_96K
+#define BSP_AUDIO_FREQUENCY_48K SAI_AUDIO_FREQUENCY_48K
+#define BSP_AUDIO_FREQUENCY_44K SAI_AUDIO_FREQUENCY_44K
+#define BSP_AUDIO_FREQUENCY_32K SAI_AUDIO_FREQUENCY_32K
+#define BSP_AUDIO_FREQUENCY_22K SAI_AUDIO_FREQUENCY_22K
+#define BSP_AUDIO_FREQUENCY_16K SAI_AUDIO_FREQUENCY_16K
+#define BSP_AUDIO_FREQUENCY_11K SAI_AUDIO_FREQUENCY_11K
+#define BSP_AUDIO_FREQUENCY_8K SAI_AUDIO_FREQUENCY_8K
+/**
+ * @}
+ */
+
+/*------------------------------------------------------------------------------
+ USER SAI defines parameters
+ -----------------------------------------------------------------------------*/
+/** CODEC_AudioFrame_SLOT_TDMMode In W8994 codec the Audio frame contains 4 slots : TDM Mode
+ * TDM format :
+ * +------------------|------------------|--------------------|-------------------+
+ * | CODEC_SLOT0 Left | CODEC_SLOT1 Left | CODEC_SLOT0 Right | CODEC_SLOT1 Right |
+ * +------------------------------------------------------------------------------+
+ */
+/* To have 2 separate audio stream in Both headphone and speaker the 4 slot must be activated */
+#define CODEC_AUDIOFRAME_SLOT_0123 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_2 | SAI_SLOTACTIVE_3
+
+/* To have an audio stream in headphone only SAI Slot 0 and Slot 2 must be activated */
+#define CODEC_AUDIOFRAME_SLOT_02 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_2
+/* To have an audio stream in speaker only SAI Slot 1 and Slot 3 must be activated */
+#define CODEC_AUDIOFRAME_SLOT_13 SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_3
+
+
+/* SAI peripheral configuration defines */
+#define AUDIO_OUT_SAIx SAI2_Block_A
+#define AUDIO_OUT_SAIx_CLK_ENABLE() __HAL_RCC_SAI2_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_CLK_DISABLE() __HAL_RCC_SAI2_CLK_DISABLE()
+#define AUDIO_OUT_SAIx_AF GPIO_AF10_SAI2
+
+#define AUDIO_OUT_SAIx_MCLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_MCLK_GPIO_PORT GPIOI
+#define AUDIO_OUT_SAIx_MCLK_PIN GPIO_PIN_4
+#define AUDIO_OUT_SAIx_SD_FS_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_SD_FS_SCK_GPIO_PORT GPIOI
+#define AUDIO_OUT_SAIx_FS_PIN GPIO_PIN_7
+#define AUDIO_OUT_SAIx_SCK_PIN GPIO_PIN_5
+#define AUDIO_OUT_SAIx_SD_PIN GPIO_PIN_6
+
+/* SAI DMA Stream definitions */
+#define AUDIO_OUT_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_DMAx_STREAM DMA2_Stream4
+#define AUDIO_OUT_SAIx_DMAx_CHANNEL DMA_CHANNEL_3
+#define AUDIO_OUT_SAIx_DMAx_IRQ DMA2_Stream4_IRQn
+#define AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
+#define AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
+#define DMA_MAX_SZE 0xFFFF
+
+#define AUDIO_OUT_SAIx_DMAx_IRQHandler DMA2_Stream4_IRQHandler
+
+/* Select the interrupt preemption priority for the DMA interrupt */
+#define AUDIO_OUT_IRQ_PREPRIO ((uint32_t)0x0E) /* Select the preemption priority level(0 is the highest) */
+
+/*------------------------------------------------------------------------------
+ AUDIO IN CONFIGURATION
+------------------------------------------------------------------------------*/
+/* SAI IN peripheral configuration defines */
+#define AUDIO_IN_SAIx SAI2_Block_B
+#define AUDIO_IN_SAIx_CLK_ENABLE() __HAL_RCC_SAI2_CLK_ENABLE()
+#define AUDIO_IN_SAIx_CLK_DISABLE() __HAL_RCC_SAI2_CLK_DISABLE()
+#define AUDIO_IN_SAIx_SD_AF GPIO_AF10_SAI2
+
+#define AUDIO_IN_SAIx_SD_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
+#define AUDIO_IN_SAIx_SD_GPIO_PORT GPIOG
+#define AUDIO_IN_SAIx_SD_PIN GPIO_PIN_10
+
+#define AUDIO_IN_INT_GPIO_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
+#define AUDIO_IN_INT_GPIO_PORT GPIOG
+#define AUDIO_IN_INT_GPIO_PIN GPIO_PIN_15
+#define AUDIO_IN_INT_IRQ EXTI15_10_IRQn
+
+/* SAI DMA Stream definitions */
+#define AUDIO_IN_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
+#define AUDIO_IN_SAIx_DMAx_STREAM DMA2_Stream6
+#define AUDIO_IN_SAIx_DMAx_CHANNEL DMA_CHANNEL_3
+#define AUDIO_IN_SAIx_DMAx_IRQ DMA2_Stream6_IRQn
+#define AUDIO_IN_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
+#define AUDIO_IN_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
+
+#define AUDIO_IN_SAIx_DMAx_IRQHandler DMA2_Stream6_IRQHandler
+#define AUDIO_IN_INT_IRQHandler EXTI15_10_IRQHandler
+
+/* Select the interrupt preemption priority and subpriority for the IT/DMA interrupt */
+#define AUDIO_IN_IRQ_PREPRIO ((uint32_t)0x0F) /* Select the preemption priority level(0 is the highest) */
+
+
+/*------------------------------------------------------------------------------
+ CONFIGURATION: Audio Driver Configuration parameters
+------------------------------------------------------------------------------*/
+
+#define AUDIODATA_SIZE 2 /* 16-bits audio data size */
+
+/* Audio status definition */
+#define AUDIO_OK ((uint8_t)0)
+#define AUDIO_ERROR ((uint8_t)1)
+#define AUDIO_TIMEOUT ((uint8_t)2)
+
+/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */
+#define DEFAULT_AUDIO_IN_FREQ BSP_AUDIO_FREQUENCY_16K
+#define DEFAULT_AUDIO_IN_BIT_RESOLUTION ((uint8_t)16)
+#define DEFAULT_AUDIO_IN_CHANNEL_NBR ((uint8_t)2) /* Mono = 1, Stereo = 2 */
+#define DEFAULT_AUDIO_IN_VOLUME ((uint16_t)64)
+
+/*------------------------------------------------------------------------------
+ OPTIONAL Configuration defines parameters
+------------------------------------------------------------------------------*/
+
+/* Delay for the Codec to be correctly reset */
+#define CODEC_RESET_DELAY ((uint8_t)5)
+
+
+/*------------------------------------------------------------------------------
+ OUTPUT DEVICES definition
+------------------------------------------------------------------------------*/
+/* Alias on existing output devices to adapt to headphones output */
+#define OUTPUT_DEVICE_HEADPHONE1 OUTPUT_DEVICE_HEADPHONE
+#define OUTPUT_DEVICE_HEADPHONE2 OUTPUT_DEVICE_SPEAKER
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_AUDIO_Exported_Variables STM32F723E_DISCOVERY_AUDIO Exported Variables
+ * @{
+ */
+ /**
+ * @}
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_AUDIO_Exported_Macros STM32F723E_DISCOVERY_AUDIO Exported Macros
+ * @{
+ */
+#define DMA_MAX(x) (((x) <= DMA_MAX_SZE)? (x):DMA_MAX_SZE)
+/**
+ * @}
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_AUDIO_OUT_Exported_Functions STM32F723E_DISCOVERY_AUDIO_OUT Exported Functions
+ * @{
+ */
+uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq);
+void BSP_AUDIO_OUT_DeInit(void);
+uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size);
+uint8_t BSP_AUDIO_OUT_Pause(void);
+uint8_t BSP_AUDIO_OUT_Resume(void);
+uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option);
+uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume);
+void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq);
+void BSP_AUDIO_OUT_SetAudioFrameSlot(uint32_t AudioFrameSlot);
+uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd);
+uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output);
+void BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size);
+
+/* User Callbacks: user has to implement these functions in his code if they are needed. */
+/* This function is called when the requested data has been completely transferred.*/
+void BSP_AUDIO_OUT_TransferComplete_CallBack(void);
+
+/* This function is called when half of the requested buffer has been transferred. */
+void BSP_AUDIO_OUT_HalfTransfer_CallBack(void);
+
+/* This function is called when an Interrupt due to transfer error on or peripheral
+ error occurs. */
+void BSP_AUDIO_OUT_Error_CallBack(void);
+
+/* These function can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_AUDIO_OUT_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params);
+void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params);
+void BSP_AUDIO_OUT_MspDeInit(SAI_HandleTypeDef *hsai, void *Params);
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_AUDIO_IN_Exported_Functions STM32F723E_DISCOVERY_AUDIO_IN Exported Functions
+ * @{
+ */
+uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_InitEx(uint16_t InputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_OUT_Init(uint16_t InputDevice, uint16_t OutputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+void BSP_AUDIO_IN_DeInit(void);
+uint8_t BSP_AUDIO_IN_Record(uint16_t *pData, uint32_t Size);
+uint8_t BSP_AUDIO_IN_Stop(uint32_t Option);
+uint8_t BSP_AUDIO_IN_Pause(void);
+uint8_t BSP_AUDIO_IN_Resume(void);
+uint8_t BSP_AUDIO_IN_SetVolume(uint8_t Volume);
+void BSP_AUDIO_IN_DeInit(void);
+
+/* User Callbacks: user has to implement these functions in his code if they are needed. */
+/* This function should be implemented by the user application.
+ It is called into this driver when the current buffer is filled to prepare the next
+ buffer pointer and its size. */
+void BSP_AUDIO_IN_TransferComplete_CallBack(void);
+void BSP_AUDIO_IN_HalfTransfer_CallBack(void);
+
+/* This function is called when an Interrupt due to transfer error on or peripheral
+ error occurs. */
+void BSP_AUDIO_IN_Error_CallBack(void);
+
+/* These function can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_AUDIO_IN_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params);
+void BSP_AUDIO_IN_MspInit(SAI_HandleTypeDef *hsai, void *Params);
+void BSP_AUDIO_IN_MspDeInit(SAI_HandleTypeDef *hsai, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F723E_DISCOVERY_AUDIO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_lcd.c b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_lcd.c
new file mode 100644
index 00000000..b16be830
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_lcd.c
@@ -0,0 +1,1182 @@
+/**
+ ******************************************************************************
+ * @file stm32f723e_discovery_lcd.c
+ * @author MCD Application Team
+ * @brief This file includes the driver for Liquid Crystal Display (LCD) module
+ * mounted on STM32F723E-DISCOVERY board.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F723E_DISCOVERY_LCD_H
+#define __STM32F723E_DISCOVERY_LCD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f723e_discovery.h"
+#include "../Components/st7789h2/st7789h2.h"
+#include "../../../Utilities/Fonts/fonts.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F723E_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_LCD STM32F723E-DISCOVERY LCD
+ * @{
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_LCD_Exported_Types STM32F723E DISCOVERY LCD Exported Types
+ * @{
+ */
+typedef struct
+{
+ uint32_t TextColor;
+ uint32_t BackColor;
+ sFONT *pFont;
+}LCD_DrawPropTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_LCD_Exported_Constants STM32F723E DISCOVERY LCD Exported Constants
+ * @{
+ */
+/**
+ * @brief LCD status structure definition
+ */
+#define LCD_OK ((uint8_t)0x00)
+#define LCD_ERROR ((uint8_t)0x01)
+#define LCD_TIMEOUT ((uint8_t)0x02)
+
+typedef struct
+{
+ int16_t X;
+ int16_t Y;
+}Point, * pPoint;
+
+/**
+ * @brief Line mode structures definition
+ */
+typedef enum
+{
+ CENTER_MODE = 0x01, /* Center mode */
+ RIGHT_MODE = 0x02, /* Right mode */
+ LEFT_MODE = 0x03 /* Left mode */
+}Line_ModeTypdef;
+
+
+#define LCD_ORIENTATION_PORTRAIT ((uint8_t)0x00) /*!< Portrait orientation choice of LCD screen */
+#define LCD_ORIENTATION_LANDSCAPE ((uint8_t)0x01) /*!< Landscape orientation choice of LCD screen */
+#define LCD_ORIENTATION_LANDSCAPE_ROT180 ((uint32_t)0x02) /*!< Landscape rotated 180 orientation choice of LCD screen */
+
+
+/**
+ * @brief LCD color
+ */
+#define LCD_COLOR_BLUE ((uint16_t)0x001F)
+#define LCD_COLOR_GREEN ((uint16_t)0x07E0)
+#define LCD_COLOR_RED ((uint16_t)0xF800)
+#define LCD_COLOR_CYAN ((uint16_t)0x07FF)
+#define LCD_COLOR_MAGENTA ((uint16_t)0xF81F)
+#define LCD_COLOR_YELLOW ((uint16_t)0xFFE0)
+#define LCD_COLOR_LIGHTBLUE ((uint16_t)0x841F)
+#define LCD_COLOR_LIGHTGREEN ((uint16_t)0x87F0)
+#define LCD_COLOR_LIGHTRED ((uint16_t)0xFC10)
+#define LCD_COLOR_LIGHTMAGENTA ((uint16_t)0xFC1F)
+#define LCD_COLOR_LIGHTYELLOW ((uint16_t)0xFFF0)
+#define LCD_COLOR_DARKBLUE ((uint16_t)0x0010)
+#define LCD_COLOR_DARKGREEN ((uint16_t)0x0400)
+#define LCD_COLOR_DARKRED ((uint16_t)0x8000)
+#define LCD_COLOR_DARKCYAN ((uint16_t)0x0410)
+#define LCD_COLOR_DARKMAGENTA ((uint16_t)0x8010)
+#define LCD_COLOR_DARKYELLOW ((uint16_t)0x8400)
+#define LCD_COLOR_WHITE ((uint16_t)0xFFFF)
+#define LCD_COLOR_LIGHTGRAY ((uint16_t)0xD69A)
+#define LCD_COLOR_GRAY ((uint16_t)0x8410)
+#define LCD_COLOR_DARKGRAY ((uint16_t)0x4208)
+#define LCD_COLOR_BLACK ((uint16_t)0x0000)
+#define LCD_COLOR_BROWN ((uint16_t)0xA145)
+#define LCD_COLOR_ORANGE ((uint16_t)0xFD20)
+
+/**
+ * @brief LCD default font
+ */
+#define LCD_DEFAULT_FONT Font12
+
+/**
+ * @brief LCD special pins
+ */
+/* LCD reset pin */
+#define LCD_RESET_PIN GPIO_PIN_7
+#define LCD_RESET_GPIO_PORT GPIOH
+#define LCD_RESET_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+#define LCD_RESET_GPIO_CLK_DISABLE() __HAL_RCC_GPIOH_CLK_DISABLE()
+
+/* LCD tearing effect pin */
+#define LCD_TE_PIN GPIO_PIN_8
+#define LCD_TE_GPIO_PORT GPIOC
+#define LCD_TE_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define LCD_TE_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
+
+/* Backlight control pin */
+#define LCD_BL_CTRL_PIN GPIO_PIN_11
+#define LCD_BL_CTRL_GPIO_PORT GPIOH
+#define LCD_BL_CTRL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+#define LCD_BL_CTRL_GPIO_CLK_DISABLE() __HAL_RCC_GPIOH_CLK_DISABLE()
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_LCD_Exported_Functions STM32F723E DISCOVERY LCD Exported Functions
+ * @{
+ */
+uint8_t BSP_LCD_Init(void);
+uint8_t BSP_LCD_InitEx(uint32_t orientation);
+uint8_t BSP_LCD_DeInit(void);
+uint32_t BSP_LCD_GetXSize(void);
+uint32_t BSP_LCD_GetYSize(void);
+
+uint16_t BSP_LCD_GetTextColor(void);
+uint16_t BSP_LCD_GetBackColor(void);
+void BSP_LCD_SetTextColor(__IO uint16_t Color);
+void BSP_LCD_SetBackColor(__IO uint16_t Color);
+void BSP_LCD_SetFont(sFONT *fonts);
+sFONT *BSP_LCD_GetFont(void);
+
+void BSP_LCD_Clear(uint16_t Color);
+void BSP_LCD_ClearStringLine(uint16_t Line);
+void BSP_LCD_DisplayStringAtLine(uint16_t Line, uint8_t *ptr);
+void BSP_LCD_DisplayStringAt(uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Line_ModeTypdef Mode);
+void BSP_LCD_DisplayChar(uint16_t Xpos, uint16_t Ypos, uint8_t Ascii);
+
+uint16_t BSP_LCD_ReadPixel(uint16_t Xpos, uint16_t Ypos);
+void BSP_LCD_DrawPixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGB_Code);
+void BSP_LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+void BSP_LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+void BSP_LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+void BSP_LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+void BSP_LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+void BSP_LCD_DrawPolygon(pPoint Points, uint16_t PointCount);
+void BSP_LCD_DrawEllipse(int Xpos, int Ypos, int XRadius, int YRadius);
+void BSP_LCD_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pbmp);
+void BSP_LCD_DrawRGBImage(uint16_t Xpos, uint16_t Ypos, uint16_t Xsize, uint16_t Ysize, uint8_t *pbmp);
+void BSP_LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+void BSP_LCD_FillCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+void BSP_LCD_FillPolygon(pPoint Points, uint16_t PointCount);
+void BSP_LCD_FillEllipse(int Xpos, int Ypos, int XRadius, int YRadius);
+
+void BSP_LCD_DisplayOff(void);
+void BSP_LCD_DisplayOn(void);
+
+/* These functions can be modified in case the current settings
+ need to be changed for specific application needs */
+__weak void BSP_LCD_MspInit(void);
+__weak void BSP_LCD_MspDeInit(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F723E_DISCOVERY_LCD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_psram.c b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_psram.c
new file mode 100644
index 00000000..3a365dfc
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_psram.c
@@ -0,0 +1,403 @@
+/**
+ ******************************************************************************
+ * @file stm32f723e_discovery_psram.c
+ * @author MCD Application Team
+ * @brief This file includes the PSRAM driver for the IS61WV51216BLL-10MLI memory
+ * device mounted on STM32F723E-DISCOVERY boards.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ - This driver is used to drive the IS61WV51216BLL-10M PSRAM external memory mounted
+ on STM32F723E discovery board.
+ - This driver does not need a specific component driver for the PSRAM device
+ to be included with.
+
+ Driver description:
+ ------------------
+ + Initialization steps:
+ o Initialize the PSRAM external memory using the BSP_PSRAM_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ FMC controller configuration to interface with the external PSRAM memory.
+
+ + PSRAM read/write operations
+ o PSRAM external memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_PSRAM_ReadData()/BSP_PSRAM_WriteData(), or by DMA transfer using the functions
+ BSP_PSRAM_ReadData_DMA()/BSP_PSRAM_WriteData_DMA().
+ o The AHB access is performed with 16-bit width transaction, the DMA transfer
+ configuration is fixed at single (no burst) halfword transfer
+ (see the PSRAM_MspInit() static function).
+ o User can implement his own functions for read/write access with his desired
+ configurations.
+ o If interrupt mode is used for DMA transfer, the function BSP_PSRAM_DMA_IRQHandler()
+ is called in IRQ handler file, to serve the generated interrupt once the DMA
+ transfer is complete.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F723E_DISCOVERY_PSRAM_H
+#define __STM32F723E_DISCOVERY_PSRAM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F723E_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F723E_DISCOVERY_PSRAM
+ * @{
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_PSRAM_Exported_Types PSRAM Exported Types
+ * @{
+ */
+
+/**
+ * @brief PSRAM status structure definition
+ */
+#define PSRAM_OK ((uint8_t)0x00)
+#define PSRAM_ERROR ((uint8_t)0x01)
+
+#define PSRAM_DEVICE_ADDR ((uint32_t)0x60000000)
+#define PSRAM_DEVICE_SIZE ((uint32_t)0x80000) /* SRAM device size in Bytes */
+
+/* #define SRAM_MEMORY_WIDTH FMC_NORSRAM_MEM_BUS_WIDTH_8*/
+#define PSRAM_MEMORY_WIDTH FMC_NORSRAM_MEM_BUS_WIDTH_16
+
+#define PSRAM_BURSTACCESS FMC_BURST_ACCESS_MODE_DISABLE
+/* #define PSRAM_BURSTACCESS FMC_BURST_ACCESS_MODE_ENABLE*/
+
+#define PSRAM_WRITEBURST FMC_WRITE_BURST_DISABLE
+/* #define PSRAM_WRITEBURST FMC_WRITE_BURST_ENABLE */
+
+#define CONTINUOUSCLOCK_FEATURE FMC_CONTINUOUS_CLOCK_SYNC_ONLY
+/* #define CONTINUOUSCLOCK_FEATURE FMC_CONTINUOUS_CLOCK_SYNC_ASYNC */
+
+/* DMA definitions for SRAM DMA transfer */
+#define __PSRAM_DMAx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
+#define __PSRAM_DMAx_CLK_DISABLE __HAL_RCC_DMA2_CLK_DISABLE
+#define PSRAM_DMAx_CHANNEL DMA_CHANNEL_0
+#define PSRAM_DMAx_STREAM DMA2_Stream5
+#define PSRAM_DMAx_IRQn DMA2_Stream5_IRQn
+#define BSP_PSRAM_DMA_IRQHandler DMA2_Stream5_IRQHandler
+
+/** @defgroup STM32F723E_DISCOVERY_PSRAM_Exported_Macro PSRAM Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_PSRAM_Exported_Functions PSRAM Exported Functions
+ * @{
+ */
+uint8_t BSP_PSRAM_Init(void);
+uint8_t BSP_PSRAM_DeInit(void);
+uint8_t BSP_PSRAM_ReadData(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+uint8_t BSP_PSRAM_ReadData_DMA(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+uint8_t BSP_PSRAM_WriteData(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+uint8_t BSP_PSRAM_WriteData_DMA(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_PSRAM_MspInit(SRAM_HandleTypeDef *hsram, void *Params);
+void BSP_PSRAM_MspDeInit(SRAM_HandleTypeDef *hsram, void *Params);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F723E_DISCOVERY_PSRAM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_qspi.c b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_qspi.c
new file mode 100644
index 00000000..759e3b3c
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_qspi.c
@@ -0,0 +1,1182 @@
+/**
+ ******************************************************************************
+ * @file stm32f723e_discovery_qspi.c
+ * @author MCD Application Team
+ * @brief This file includes a standard driver for the MX25L512 QSPI
+ * memory mounted on STM32F723E-Discovery board.
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) This driver is used to drive the MX25L512 QSPI external
+ memory mounted on STM32F723E-Discovery board.
+
+ (#) This driver need a specific component driver (MX25L51245G) to be included with.
+
+ (#) Initialization steps:
+ (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ QSPI interface with the external memory.
+
+ (#) QSPI memory operations
+ (++) QSPI memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_QSPI_Read()/BSP_QSPI_Write().
+ (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory.
+ (see the QSPI memory data sheet)
+ (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by
+ specifying the block address. You can perform an erase operation of the whole
+ chip by calling the function BSP_QSPI_Erase_Chip().
+ (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory.
+ (see the QSPI memory data sheet)
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F723E_DISCOVERY
+ * @{
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F723E_DISCOVERY_QSPI_H
+#define __STM32F723E_DISCOVERY_QSPI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+#include "../Components/mx25l512/mx25l512.h"
+
+/** @addtogroup STM32F723E_DISCOVERY_QSPI
+ * @{
+ */
+
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup STM32F723E_DISCOVERY_QSPI_Exported_Constants STM32F723E_DISCOVERY_QSPI Exported Constants
+ * @{
+ */
+/* QSPI Error codes */
+#define QSPI_OK ((uint8_t)0x00)
+#define QSPI_ERROR ((uint8_t)0x01)
+#define QSPI_BUSY ((uint8_t)0x02)
+#define QSPI_NOT_SUPPORTED ((uint8_t)0x04)
+#define QSPI_SUSPENDED ((uint8_t)0x08)
+
+
+/* Definition for QSPI clock resources */
+#define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE()
+#define QSPI_CLK_DISABLE() __HAL_RCC_QSPI_CLK_DISABLE()
+#define QSPI_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define QSPI_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define QSPI_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define QSPI_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define QSPI_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
+#define QSPI_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
+
+#define QSPI_FORCE_RESET() __HAL_RCC_QSPI_FORCE_RESET()
+#define QSPI_RELEASE_RESET() __HAL_RCC_QSPI_RELEASE_RESET()
+
+/* Definition for QSPI Pins */
+/* QSPI_CS */
+#define QSPI_CS_PIN GPIO_PIN_6
+#define QSPI_CS_GPIO_PORT GPIOB
+#define QSPI_CS_PIN_AF GPIO_AF10_QUADSPI
+/* QSPI_CLK */
+#define QSPI_CLK_PIN GPIO_PIN_2
+#define QSPI_CLK_GPIO_PORT GPIOB
+#define QSPI_CLK_PIN_AF GPIO_AF9_QUADSPI
+/* QSPI_D0 */
+#define QSPI_D0_PIN GPIO_PIN_9
+#define QSPI_D0_GPIO_PORT GPIOC
+#define QSPI_D0_PIN_AF GPIO_AF9_QUADSPI
+/* QSPI_D1 */
+#define QSPI_D1_PIN GPIO_PIN_10
+#define QSPI_D1_GPIO_PORT GPIOC
+#define QSPI_D1_PIN_AF GPIO_AF9_QUADSPI
+/* QSPI_D2 */
+#define QSPI_D2_PIN GPIO_PIN_2
+#define QSPI_D2_GPIO_PORT GPIOE
+#define QSPI_D2_PIN_AF GPIO_AF9_QUADSPI
+/* QSPI_D3 */
+#define QSPI_D3_PIN GPIO_PIN_13
+#define QSPI_D3_GPIO_PORT GPIOD
+#define QSPI_D3_PIN_AF GPIO_AF9_QUADSPI
+
+/**
+ * @}
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup STM32F723E_DISCOVERY_QSPI_Exported_Types STM32F723E_DISCOVERY_QSPI Exported Types
+ * @{
+ */
+/* QSPI Info */
+typedef struct {
+ uint32_t FlashSize; /*!< Size of the flash */
+ uint32_t EraseSectorSize; /*!< Size of sectors for the erase operation */
+ uint32_t EraseSectorsNumber; /*!< Number of sectors for the erase operation */
+ uint32_t ProgPageSize; /*!< Size of pages for the program operation */
+ uint32_t ProgPagesNumber; /*!< Number of pages for the program operation */
+} QSPI_Info;
+
+/**
+ * @}
+ */
+
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup STM32F723E_DISCOVERY_QSPI_Exported_Functions
+ * @{
+ */
+uint8_t BSP_QSPI_Init (void);
+uint8_t BSP_QSPI_DeInit (void);
+uint8_t BSP_QSPI_Read (uint8_t* pData, uint32_t ReadAddr, uint32_t Size);
+uint8_t BSP_QSPI_Write (uint8_t* pData, uint32_t WriteAddr, uint32_t Size);
+uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress);
+uint8_t BSP_QSPI_Erase_Chip (void);
+uint8_t BSP_QSPI_GetStatus (void);
+uint8_t BSP_QSPI_GetInfo (QSPI_Info* pInfo);
+uint8_t BSP_QSPI_EnableMemoryMappedMode(void);
+
+/* These functions can be modified in case the current settings
+ need to be changed for specific application needs */
+void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params);
+void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F723E_DISCOVERY_QSPI_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_ts.c b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_ts.c
new file mode 100644
index 00000000..1b2fca63
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_ts.c
@@ -0,0 +1,485 @@
+/**
+ ******************************************************************************
+ * @file stm32f723e_discovery_ts.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the Touch
+ * Screen on STM32F723E-DISCOVERY evaluation board.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* File Info : -----------------------------------------------------------------
+ User NOTES
+1. How To use this driver:
+--------------------------
+ - This driver is used to drive the touch screen module of the STM32F723E-DISCOVERY
+ evaluation board on the FRIDA LCD mounted on MB1260 discovery board.
+ The touch screen driver IC is a FT6x36 type which share the same register naming
+ with FT6206 type.
+
+2. Driver description:
+---------------------
+ + Initialization steps:
+ o Initialize the TS module using the BSP_TS_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ communication layer configuration to start the TS use. The LCD size properties
+ (x and y) are passed as parameters.
+ Note: The FT6x36 requires a calibration. This should be done at application level.
+ Refer to BSP example to correctly calibrate the touch screen.
+ o If TS interrupt mode is desired, you must configure the TS interrupt mode
+ by calling the function BSP_TS_ITConfig(). The TS interrupt mode is generated
+ as an external interrupt whenever a touch is detected.
+
+ + Touch screen use
+ o The touch screen state is captured whenever the function BSP_TS_GetState() is
+ used. This function returns information about the last LCD touch occurred
+ in the TS_StateTypeDef structure.
+------------------------------------------------------------------------------*/
+
+/* Dependencies
+- stm32f723e_discovery_lcd.c
+- ft6x06.c
+EndDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f723e_discovery_ts.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F723E_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32F723E_DISCOVERY_TS STM32F723E-DISCOVERY TS
+ * @{
+ */
+
+/** @defgroup STM32F723E-DISCOVERY_TS_Private_Types_Definitions TS Private Types Definitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F723E-DISCOVERY_TS_Private_Defines TS Private Types Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F723E-DISCOVERY_TS_Private_Macros TS Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F723E-DISCOVERY_TS_Imported_Variables TS Imported Variables
+ * @{
+ */
+ /**
+ * @}
+ */
+
+/** @defgroup STM32F723E-DISCOVERY_TS_Private_Variables TS Private Variables
+ * @{
+ */
+static TS_DrvTypeDef *tsDriver;
+static uint8_t I2C_Address = 0;
+static uint8_t tsOrientation = TS_SWAP_NONE;
+
+/* Table for touchscreen event information display on LCD : table indexed on enum @ref TS_TouchEventTypeDef information */
+char * ts_event_string_tab[TOUCH_EVENT_NB_MAX] = { "None",
+ "Press down",
+ "Lift up",
+ "Contact"
+ };
+
+/* Table for touchscreen gesture Id information display on LCD : table indexed on enum @ref TS_GestureIdTypeDef information */
+char * ts_gesture_id_string_tab[GEST_ID_NB_MAX] = { "None",
+ "Move Up",
+ "Move Right",
+ "Move Down",
+ "Move Left",
+ "Zoom In",
+ "Zoom Out"
+ };
+/**
+ * @}
+ */
+
+/** @defgroup STM32F723E-DISCOVERY_TS_Private_Function_Prototypes TS Private Function Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F723E-DISCOVERY_TS_Public_Functions TS Public Functions
+ * @{
+ */
+/**
+ * @brief Initializes and configures the touch screen functionalities and
+ * configures all necessary hardware resources (GPIOs, I2C, clocks..).
+ * @param ts_SizeX : Maximum X size of the TS area on LCD
+ * @param ts_SizeY : Maximum Y size of the TS area on LCD
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_Init(uint16_t ts_SizeX, uint16_t ts_SizeY)
+{
+ return (BSP_TS_InitEx(ts_SizeX, ts_SizeY, TS_ORIENTATION_LANDSCAPE));
+}
+
+/**
+ * @brief Initializes and configures the touch screen functionalities and
+ * configures all necessary hardware resources (GPIOs, I2C, clocks..)
+ * with a given orientation
+ * @param ts_SizeX : Maximum X size of the TS area on LCD
+ * @param ts_SizeY : Maximum Y size of the TS area on LCD
+ * @param orientation : TS_ORIENTATION_LANDSCAPE or TS_ORIENTATION_PORTRAIT
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_InitEx(uint16_t ts_SizeX, uint16_t ts_SizeY, uint8_t orientation)
+{
+ uint8_t ts_status = TS_OK;
+
+ /* Note : I2C_Address is un-initialized here, but is not used at all in init function */
+ /* but the prototype of Init() is like that in template and should be respected */
+
+ /* Initialize the communication channel to sensor (I2C) if necessary */
+ /* that is initialization is done only once after a power up */
+ ft6x06_ts_drv.Init(I2C_Address);
+
+ /* Scan FT6x36 TouchScreen IC controller ID register by I2C Read */
+ /* Verify this is a FT6x36, otherwise this is an error case */
+ if(ft6x06_ts_drv.ReadID(TS_I2C_ADDRESS) == FT6x36_ID_VALUE)
+ {
+ /* Found FT6x36 : Initialize the TS driver structure */
+ tsDriver = &ft6x06_ts_drv;
+
+ I2C_Address = TS_I2C_ADDRESS;
+
+ /* Get LCD chosen orientation */
+ if(orientation == TS_ORIENTATION_PORTRAIT)
+ {
+ tsOrientation = TS_SWAP_X | TS_SWAP_Y;
+ }
+ else if(orientation == TS_ORIENTATION_LANDSCAPE_ROT180)
+ {
+ tsOrientation = TS_SWAP_XY;
+ }
+ else
+ {
+ tsOrientation = TS_SWAP_XY | TS_SWAP_Y;
+ }
+
+ if(ts_status == TS_OK)
+ {
+ /* Software reset the TouchScreen */
+ tsDriver->Reset(I2C_Address);
+
+ /* Calibrate, Configure and Start the TouchScreen driver */
+ tsDriver->Start(I2C_Address);
+
+ } /* of if(ts_status == TS_OK) */
+ }
+ else
+ {
+ ts_status = TS_DEVICE_NOT_FOUND;
+ }
+
+ return (ts_status);
+}
+
+/**
+ * @brief Configures and enables the touch screen interrupts.
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_ITConfig(void)
+{
+ uint8_t ts_status = TS_OK;
+ GPIO_InitTypeDef gpio_init_structure;
+
+ /* Msp Init of GPIO used for TS_INT pin coming from TouchScreen driver IC FT6x36 */
+ /* When touchscreen is operated in interrupt mode */
+ BSP_TS_INT_MspInit();
+
+ /* Configure Interrupt mode for TS_INT pin falling edge : when a new touch is available */
+ /* TS_INT pin is active on low level on new touch available */
+ gpio_init_structure.Pin = TS_INT_PIN;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_FAST;
+ gpio_init_structure.Mode = GPIO_MODE_IT_FALLING;
+ HAL_GPIO_Init(TS_INT_GPIO_PORT, &gpio_init_structure);
+
+ /* Enable and set the TS_INT EXTI Interrupt to an intermediate priority */
+ HAL_NVIC_SetPriority((IRQn_Type)(TS_INT_EXTI_IRQn), 0x0F, 0x00);
+ HAL_NVIC_EnableIRQ((IRQn_Type)(TS_INT_EXTI_IRQn));
+
+ /* Enable the TS in interrupt mode */
+ /* In that case the INT output of FT6206 when new touch is available */
+ /* is active on low level and directed on EXTI */
+ tsDriver->EnableIT(I2C_Address);
+
+ return (ts_status);
+}
+
+/**
+ * @brief Returns status and positions of the touch screen.
+ * @param TS_State: Pointer to touch screen current state structure
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_GetState(TS_StateTypeDef *TS_State)
+{
+ static uint32_t _x[TS_MAX_NB_TOUCH] = {0, 0};
+ static uint32_t _y[TS_MAX_NB_TOUCH] = {0, 0};
+ uint8_t ts_status = TS_OK;
+ uint16_t tmp;
+ uint16_t Raw_x[TS_MAX_NB_TOUCH];
+ uint16_t Raw_y[TS_MAX_NB_TOUCH];
+ uint16_t xDiff;
+ uint16_t yDiff;
+ uint32_t index;
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+ uint32_t weight = 0;
+ uint32_t area = 0;
+ uint32_t event = 0;
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+ /* Check and update the number of touches active detected */
+ TS_State->touchDetected = tsDriver->DetectTouch(I2C_Address);
+ if(TS_State->touchDetected)
+ {
+ for(index=0; index < TS_State->touchDetected; index++)
+ {
+ /* Get each touch coordinates */
+ tsDriver->GetXY(I2C_Address, &(Raw_x[index]), &(Raw_y[index]));
+
+ if(tsOrientation & TS_SWAP_XY)
+ {
+ tmp = Raw_x[index];
+ Raw_x[index] = Raw_y[index];
+ Raw_y[index] = tmp;
+ }
+
+ if(tsOrientation & TS_SWAP_X)
+ {
+ Raw_x[index] = FT_6206_MAX_WIDTH_HEIGHT - 1 - Raw_x[index];
+ }
+
+ if(tsOrientation & TS_SWAP_Y)
+ {
+ Raw_y[index] = FT_6206_MAX_WIDTH_HEIGHT - 1 - Raw_y[index];
+ }
+
+ xDiff = Raw_x[index] > _x[index]? (Raw_x[index] - _x[index]): (_x[index] - Raw_x[index]);
+ yDiff = Raw_y[index] > _y[index]? (Raw_y[index] - _y[index]): (_y[index] - Raw_y[index]);
+
+ if ((xDiff + yDiff) > 5)
+ {
+ _x[index] = Raw_x[index];
+ _y[index] = Raw_y[index];
+ }
+
+
+ TS_State->touchX[index] = _x[index];
+ TS_State->touchY[index] = _y[index];
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+
+ /* Get touch info related to the current touch */
+ ft6x06_TS_GetTouchInfo(I2C_Address, index, &weight, &area, &event);
+
+ /* Update TS_State structure */
+ TS_State->touchWeight[index] = weight;
+ TS_State->touchArea[index] = area;
+
+ /* Remap touch event */
+ switch(event)
+ {
+ case FT6206_TOUCH_EVT_FLAG_PRESS_DOWN :
+ TS_State->touchEventId[index] = TOUCH_EVENT_PRESS_DOWN;
+ break;
+ case FT6206_TOUCH_EVT_FLAG_LIFT_UP :
+ TS_State->touchEventId[index] = TOUCH_EVENT_LIFT_UP;
+ break;
+ case FT6206_TOUCH_EVT_FLAG_CONTACT :
+ TS_State->touchEventId[index] = TOUCH_EVENT_CONTACT;
+ break;
+ case FT6206_TOUCH_EVT_FLAG_NO_EVENT :
+ TS_State->touchEventId[index] = TOUCH_EVENT_NO_EVT;
+ break;
+ default :
+ ts_status = TS_ERROR;
+ break;
+ } /* of switch(event) */
+
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+ } /* of for(index=0; index < TS_State->touchDetected; index++) */
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+ /* Get gesture Id */
+ ts_status = BSP_TS_Get_GestureId(TS_State);
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+ } /* end of if(TS_State->touchDetected != 0) */
+
+ return (ts_status);
+}
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+/**
+ * @brief Update gesture Id following a touch detected.
+ * @param TS_State: Pointer to touch screen current state structure
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_Get_GestureId(TS_StateTypeDef *TS_State)
+{
+ uint32_t gestureId = 0;
+ uint8_t ts_status = TS_OK;
+
+ /* Get gesture Id */
+ ft6x06_TS_GetGestureID(I2C_Address, &gestureId);
+
+ /* Remap gesture Id to a TS_GestureIdTypeDef value */
+ switch(gestureId)
+ {
+ case FT6206_GEST_ID_NO_GESTURE :
+ TS_State->gestureId = GEST_ID_NO_GESTURE;
+ break;
+ case FT6206_GEST_ID_MOVE_UP :
+ TS_State->gestureId = GEST_ID_MOVE_UP;
+ break;
+ case FT6206_GEST_ID_MOVE_RIGHT :
+ TS_State->gestureId = GEST_ID_MOVE_RIGHT;
+ break;
+ case FT6206_GEST_ID_MOVE_DOWN :
+ TS_State->gestureId = GEST_ID_MOVE_DOWN;
+ break;
+ case FT6206_GEST_ID_MOVE_LEFT :
+ TS_State->gestureId = GEST_ID_MOVE_LEFT;
+ break;
+ case FT6206_GEST_ID_ZOOM_IN :
+ TS_State->gestureId = GEST_ID_ZOOM_IN;
+ break;
+ case FT6206_GEST_ID_ZOOM_OUT :
+ TS_State->gestureId = GEST_ID_ZOOM_OUT;
+ break;
+ default :
+ ts_status = TS_ERROR;
+ break;
+ } /* of switch(gestureId) */
+
+ return(ts_status);
+}
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+
+/** @defgroup STM32F723E-DISCOVERY_TS_Private_Functions TS Private Functions
+ * @{
+ */
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+/**
+ * @brief Function used to reset all touch data before a new acquisition
+ * of touch information.
+ * @param TS_State: Pointer to touch screen current state structure
+ * @retval TS_OK if OK, TE_ERROR if problem found.
+ */
+uint8_t BSP_TS_ResetTouchData(TS_StateTypeDef *TS_State)
+{
+ uint8_t ts_status = TS_ERROR;
+ uint32_t index;
+
+ if (TS_State != (TS_StateTypeDef *)NULL)
+ {
+ TS_State->gestureId = GEST_ID_NO_GESTURE;
+ TS_State->touchDetected = 0;
+
+ for(index = 0; index < TS_MAX_NB_TOUCH; index++)
+ {
+ TS_State->touchX[index] = 0;
+ TS_State->touchY[index] = 0;
+ TS_State->touchArea[index] = 0;
+ TS_State->touchEventId[index] = TOUCH_EVENT_NO_EVT;
+ TS_State->touchWeight[index] = 0;
+ }
+
+ ts_status = TS_OK;
+
+ } /* of if (TS_State != (TS_StateTypeDef *)NULL) */
+
+ return (ts_status);
+}
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+/**
+ * @brief Initializes the TS_INT pin MSP.
+ * @retval None
+ */
+__weak void BSP_TS_INT_MspInit(void)
+{
+ GPIO_InitTypeDef gpio_init_structure;
+
+ TS_INT_GPIO_CLK_ENABLE();
+
+ /* GPIO configuration in input for TouchScreen interrupt signal on TS_INT pin */
+ gpio_init_structure.Pin = TS_INT_PIN;
+
+ gpio_init_structure.Mode = GPIO_MODE_INPUT;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_HIGH;
+ HAL_GPIO_Init(TS_INT_GPIO_PORT, &gpio_init_structure);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_ts.h b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_ts.h
new file mode 100644
index 00000000..6c7c4601
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F723E-Discovery/stm32f723e_discovery_ts.h
@@ -0,0 +1,215 @@
+/**
+ ******************************************************************************
+ * @file stm32f723e_discovery_ts.h
+ * @author MCD Application Team
+ * @brief This file contains the common defines and functions prototypes for
+ * the stm32f723E_discovery_ts.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
Release
+Notes for STM32F7308-Discovery Board Drivers
+
Copyright
+2018 STMicroelectronics
+
+
+
+
+
+
+
+
+
+
The BSP (Board Specific
+Package) drivers are parts of the STM32Cube package based on the HAL
+drivers and provide a set of high level APIs relative to the hardware
+components and features in the evaluation boards, discovery kits and nucleo
+boards coming with the STM32Cube package for a given STM32 serie.
+
The BSP drivers allow a quick access to the boards’
+services using high level APIs and without any specific configuration as the
+link with the HAL and the external components is done in intrinsic within the drivers.
+
+
From project settings points of view, user has only
+to add the necessary driver’s files in the workspace and call the needed
+functions from examples. However some low level
+configuration functions are weak and can be overridden by the applications if user
+wants to change some BSP drivers default behavior.
+
+
+
Update History
V1.0.0 / 19-October-2018
+
+
Main
+Changes
+
+
First official Release for STM32F7308-Discovery
+board drivers.
Dependencies
+
+
+
+
+
+
+
STM32F7xx_HAL_Driver V1.2.6
+
BSP Common V4.0.1
License
+
+
This software component is licensed by ST under BSD 3-Clause
+license, the "License"; You may not use this component except
+in compliance with the License. You may obtain a copy of the License at:
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F7308_DISCOVERY_H
+#define __STM32F7308_DISCOVERY_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+ /* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F7308_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F7308_DISCOVERY_LOW_LEVEL
+ * @{
+ */
+
+/** @defgroup STM32F7308_DISCOVERY_LOW_LEVEL_Exported_Types STM32F7308 Discovery Low Level Exported Types
+ * @{
+ */
+
+/**
+ * @brief Define for STM32F7308_DISCOVERY board
+ */
+#if !defined (USE_STM32F7308_DISCO)
+ #define USE_STM32F7308_DISCO
+#endif
+
+/** @brief Led_TypeDef
+ * STM32F7308_Discovery board leds definitions.
+ */
+typedef enum
+{
+ LED5 = 0,
+ LED_RED = LED5,
+ LED6 = 1,
+ LED_GREEN = LED6
+} Led_TypeDef;
+
+/** @brief Button_TypeDef
+ * STM32F7308_Discovery board Buttons definitions.
+ */
+typedef enum
+{
+ BUTTON_WAKEUP = 0,
+} Button_TypeDef;
+
+#define BUTTON_USER BUTTON_WAKEUP
+
+/** @brief ButtonMode_TypeDef
+ * STM32F7308_Discovery board Buttons Modes definitions.
+ */
+typedef enum
+{
+ BUTTON_MODE_GPIO = 0,
+ BUTTON_MODE_EXTI = 1
+
+} ButtonMode_TypeDef;
+
+typedef enum
+{
+ PB_SET = 0,
+ PB_RESET = !PB_SET
+} ButtonValue_TypeDef;
+
+typedef enum
+{
+ COM1 = 0,
+}COM_TypeDef;
+
+/** @brief DISCO_Status_TypeDef
+ * STM32F7308_DISCO board Status return possible values.
+ */
+typedef enum
+{
+ DISCO_OK = 0,
+ DISCO_ERROR = 1
+
+} DISCO_Status_TypeDef;
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F7308_DISCOVERY_LOW_LEVEL_LED STM32F7308 Discovery Low Level Led
+ * @{
+ */
+/* Always four leds for all revisions of Discovery boards */
+#define LEDn ((uint8_t)2)
+
+
+/* 2 Leds are connected to MCU directly on PA7 and PB1 */
+#define LED5_GPIO_PORT ((GPIO_TypeDef*)GPIOA)
+#define LED6_GPIO_PORT ((GPIO_TypeDef*)GPIOB)
+
+#define LED5_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define LED6_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+
+#define LED5_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define LED6_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
+
+
+#define LEDx_GPIO_CLK_ENABLE(__INDEX__) do{if((__INDEX__) == 0) LED5_GPIO_CLK_ENABLE(); else \
+ if((__INDEX__) == 1) LED6_GPIO_CLK_ENABLE(); \
+ }while(0)
+
+#define LEDx_GPIO_CLK_DISABLE(__INDEX__) do{if((__INDEX__) == 0) LED5_GPIO_CLK_DISABLE(); else \
+ if((__INDEX__) == 1) LED6_GPIO_CLK_DISABLE(); \
+ }while(0)
+
+#define LED5_PIN ((uint32_t)GPIO_PIN_7)
+#define LED6_PIN ((uint32_t)GPIO_PIN_1)
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F7308_DISCOVERY_LOW_LEVEL_BUTTON STM32F7308 Discovery Low Level Button
+ * @{
+ */
+/* Only one User/Wakeup button */
+#define BUTTONn ((uint8_t)1)
+
+/**
+ * @brief Wakeup push-button
+ */
+#define WAKEUP_BUTTON_PIN GPIO_PIN_0
+#define WAKEUP_BUTTON_GPIO_PORT GPIOA
+#define WAKEUP_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define WAKEUP_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define WAKEUP_BUTTON_EXTI_IRQn EXTI0_IRQn
+
+/* Define the USER button as an alias of the Wakeup button */
+#define USER_BUTTON_PIN WAKEUP_BUTTON_PIN
+#define USER_BUTTON_GPIO_PORT WAKEUP_BUTTON_GPIO_PORT
+#define USER_BUTTON_GPIO_CLK_ENABLE() WAKEUP_BUTTON_GPIO_CLK_ENABLE()
+#define USER_BUTTON_GPIO_CLK_DISABLE() WAKEUP_BUTTON_GPIO_CLK_DISABLE()
+#define USER_BUTTON_EXTI_IRQn WAKEUP_BUTTON_EXTI_IRQn
+
+#define BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7308_DISCOVERY_LOW_LEVEL_Exported_Constants LOW_LEVEL Exported Constants
+ * @{
+ */
+/**
+ * @brief USB OTG HS Over Current signal
+ */
+#define OTG_HS_OVER_CURRENT_PIN GPIO_PIN_10
+#define OTG_HS_OVER_CURRENT_PORT GPIOH
+#define OTG_HS_OVER_CURRENT_PORT_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+
+/**
+ * @brief USB OTG FS Over Current signal
+ */
+#define OTG_FS_OVER_CURRENT_PIN GPIO_PIN_8
+#define OTG_FS_OVER_CURRENT_PORT GPIOC
+#define OTG_FS_OVER_CURRENT_PORT_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+
+/**
+ * @brief TS_INT signal from TouchScreen
+ */
+#define TS_INT_PIN ((uint32_t)GPIO_PIN_9)
+#define TS_INT_GPIO_PORT ((GPIO_TypeDef*)GPIOI)
+#define TS_INT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define TS_INT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define TS_INT_EXTI_IRQn EXTI9_5_IRQn
+
+/**
+ * @brief TS RESET pin
+ */
+#define TS_RESET_PIN GPIO_PIN_9
+#define TS_RESET_GPIO_PORT GPIOH
+#define TS_RESET_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+#define TS_RESET_GPIO_CLK_DISABLE() __HAL_RCC_GPIOH_CLK_DISABLE()
+#define TS_RESET_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @brief Definition for I2C3 Touchscreen Pins
+ * resources (touchescreen).
+ * Definition for I2C3 clock resources
+ */
+#define TS_I2Cx I2C3
+#define TS_I2Cx_CLK_ENABLE() __HAL_RCC_I2C3_CLK_ENABLE()
+#define TS_I2Cx_SCL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define TS_I2Cx_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+
+#define TS_I2Cx_FORCE_RESET() __HAL_RCC_I2C3_FORCE_RESET()
+#define TS_I2Cx_RELEASE_RESET() __HAL_RCC_I2C3_RELEASE_RESET()
+
+/** @brief Definition for Touchscreen Pins
+ */
+#define TS_I2Cx_SCL_PIN GPIO_PIN_8
+#define TS_I2Cx_SCL_AF GPIO_AF4_I2C3
+#define TS_I2Cx_SCL_GPIO_PORT GPIOA
+#define TS_I2Cx_SDA_PIN GPIO_PIN_8
+#define TS_I2Cx_SDA_AF GPIO_AF4_I2C3
+#define TS_I2Cx_SDA_GPIO_PORT GPIOH
+
+#define TS_I2Cx_EV_IRQn I2C3_EV_IRQn
+#define TS_I2Cx_ER_IRQn I2C3_ER_IRQn
+
+/**
+ * @brief TouchScreen FT6206 Slave I2C address
+ */
+#define TS_I2C_ADDRESS ((uint16_t)0x70)
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F7308_DISCOVERY_LOW_LEVEL_COM STM32F7308 DISCOVERY Low Level COM
+ * @{
+ */
+#define COMn ((uint8_t)1)
+
+/**
+ * @brief Definition for COM port1, connected to USART2
+ */
+#define DISCOVERY_COM1 USART2
+#define DISCOVERY_COM1_CLK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE()
+#define DISCOVERY_COM1_CLK_DISABLE() __HAL_RCC_USART2_CLK_DISABLE()
+
+#define DISCOVERY_COM1_TX_PIN GPIO_PIN_3
+#define DISCOVERY_COM1_TX_GPIO_PORT GPIOA
+#define DISCOVERY_COM1_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define DISCOVERY_COM1_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define DISCOVERY_COM1_TX_AF GPIO_AF7_USART2
+
+#define DISCOVERY_COM1_RX_PIN GPIO_PIN_2
+#define DISCOVERY_COM1_RX_GPIO_PORT GPIOA
+#define DISCOVERY_COM1_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define DISCOVERY_COM1_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define DISCOVERY_COM1_RX_AF GPIO_AF7_USART2
+
+#define DISCOVERY_COM1_IRQn USART2_IRQn
+
+#define DISCOVERY_COMx_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) {DISCOVERY_COM1_CLK_ENABLE();} } while(0)
+#define DISCOVERY_COMx_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? DISCOVERY_COM1_CLK_DISABLE() : 0)
+
+#define DISCOVERY_COMx_TX_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) {DISCOVERY_COM1_TX_GPIO_CLK_ENABLE();} } while(0)
+#define DISCOVERY_COMx_TX_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? DISCOVERY_COM1_TX_GPIO_CLK_DISABLE() : 0)
+
+#define DISCOVERY_COMx_RX_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) {DISCOVERY_COM1_RX_GPIO_CLK_ENABLE();} } while(0)
+#define DISCOVERY_COMx_RX_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? DISCOVERY_COM1_RX_GPIO_CLK_DISABLE() : 0)
+
+
+/**
+ * @brief Audio I2C Slave address
+ */
+#define AUDIO_I2C_ADDRESS ((uint16_t)0x34)
+
+/**
+ * @brief User can use this section to tailor I2C1 instance used and associated
+ * resources (audio codec).
+ * Definition for I2C1 clock resources
+ */
+#define DISCOVERY_AUDIO_I2Cx I2C1
+#define DISCOVERY_AUDIO_I2Cx_CLK_ENABLE() __HAL_RCC_I2C1_CLK_ENABLE()
+#define DISCOVERY_AUDIO_I2Cx_SCL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define DISCOVERY_AUDIO_I2Cx_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+
+#define DISCOVERY_AUDIO_I2Cx_FORCE_RESET() __HAL_RCC_I2C1_FORCE_RESET()
+#define DISCOVERY_AUDIO_I2Cx_RELEASE_RESET() __HAL_RCC_I2C1_RELEASE_RESET()
+
+/** @brief Definition for I2C1 Pins
+ */
+#define DISCOVERY_AUDIO_I2Cx_SCL_PIN GPIO_PIN_8 /*!< PB8 */
+#define DISCOVERY_AUDIO_I2Cx_SCL_AF GPIO_AF4_I2C1
+#define DISCOVERY_AUDIO_I2Cx_SCL_GPIO_PORT GPIOB
+#define DISCOVERY_AUDIO_I2Cx_SDA_PIN GPIO_PIN_9 /*!< PB9 */
+#define DISCOVERY_AUDIO_I2Cx_SDA_AF GPIO_AF4_I2C1
+#define DISCOVERY_AUDIO_I2Cx_SDA_GPIO_PORT GPIOB
+/** @brief Definition of I2C1 interrupt requests
+ */
+#define DISCOVERY_AUDIO_I2Cx_EV_IRQn I2C1_EV_IRQn
+#define DISCOVERY_AUDIO_I2Cx_ER_IRQn I2C1_ER_IRQn
+
+
+/* Definition for external, camera and Arduino connector I2Cx resources */
+#define DISCOVERY_EXT_I2Cx I2C2
+#define DISCOVERY_EXT_I2Cx_CLK_ENABLE() __HAL_RCC_I2C2_CLK_ENABLE()
+#define DISCOVERY_EXT_DMAx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
+#define DISCOVERY_EXT_I2Cx_SCL_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+
+#define DISCOVERY_EXT_I2Cx_FORCE_RESET() __HAL_RCC_I2C2_FORCE_RESET()
+#define DISCOVERY_EXT_I2Cx_RELEASE_RESET() __HAL_RCC_I2C2_RELEASE_RESET()
+
+/* Definition for I2Cx Pins */
+#define DISCOVERY_EXT_I2Cx_SCL_PIN GPIO_PIN_4
+#define DISCOVERY_EXT_I2Cx_SCL_SDA_GPIO_PORT GPIOH
+#define DISCOVERY_EXT_I2Cx_SCL_SDA_AF GPIO_AF4_I2C2
+#define DISCOVERY_EXT_I2Cx_SDA_PIN GPIO_PIN_5
+
+/* I2C interrupt requests */
+#define DISCOVERY_EXT_I2Cx_EV_IRQn I2C2_EV_IRQn
+#define DISCOVERY_EXT_I2Cx_ER_IRQn I2C2_ER_IRQn
+
+
+/* I2C TIMING Register define when I2C clock source is SYSCLK */
+/* I2C TIMING is calculated from APB1 source clock = 50 MHz */
+/* Due to the big MOFSET capacity for adapting the camera level the rising time is very large (>1us) */
+/* 0x40912732 takes in account the big rising and aims a clock of 100khz */
+#ifndef DISCOVERY_I2Cx_TIMING
+#define DISCOVERY_I2Cx_TIMING ((uint32_t)0x40912732)
+#endif /* DISCOVERY_I2Cx_TIMING */
+
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7308_DISCOVERY_LOW_LEVEL_Exported_Macros STM32F7308 Discovery Low Level Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7308_DISCOVERY_LOW_LEVEL_Exported_Functions STM32F7308 Discovery Low Level Exported Functions
+ * @{
+ */
+uint32_t BSP_GetVersion(void);
+void BSP_LED_Init(Led_TypeDef Led);
+void BSP_LED_DeInit(Led_TypeDef Led);
+void BSP_LED_On(Led_TypeDef Led);
+void BSP_LED_Off(Led_TypeDef Led);
+void BSP_LED_Toggle(Led_TypeDef Led);
+void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef Button_Mode);
+void BSP_PB_DeInit(Button_TypeDef Button);
+uint32_t BSP_PB_GetState(Button_TypeDef Button);
+void BSP_COM_Init(COM_TypeDef COM, UART_HandleTypeDef *huart);
+void BSP_COM_DeInit(COM_TypeDef COM, UART_HandleTypeDef *huart);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F7308_DISCOVERY_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F7308-Discovery/stm32f7308_discovery_audio.c b/src/port_stm32f7/common/bsp_drivers/STM32F7308-Discovery/stm32f7308_discovery_audio.c
new file mode 100644
index 00000000..b7111a7d
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F7308-Discovery/stm32f7308_discovery_audio.c
@@ -0,0 +1,1430 @@
+/**
+ ******************************************************************************
+ * @file stm32f7308_discovery_audio.c
+ * @author MCD Application Team
+ * @brief This file provides the Audio driver for the STM32F7308-DISCOVERY
+ * board.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ + This driver supports STM32F7xx devices on STM32F7308-DISCOVERY (MB1260) Evaluation boards.
+ + Call the function BSP_AUDIO_OUT_Init(
+ OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER,
+ OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
+ Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
+ AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...)
+ this parameter is relative to the audio file/stream type.
+ )
+ This function configures all the hardware required for the audio application (codec, I2C, SAI,
+ GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
+ If the returned value is different from AUDIO_OK or the function is stuck then the communication with
+ the codec has failed (try to un-plug the power or reset device in this case).
+ - OUTPUT_DEVICE_SPEAKER : only speaker will be set as output for the audio stream.
+ - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
+ - OUTPUT_DEVICE_BOTH : both Speaker and Headphone are used as outputs for the audio stream
+ at the same time.
+ + Call the function BSP_DISCOVERY_AUDIO_OUT_Play(
+ pBuffer: pointer to the audio data file address
+ Size : size of the buffer to be sent in Bytes
+ )
+ to start playing (for the first time) from the audio file/stream.
+ + Call the function BSP_AUDIO_OUT_Pause() to pause playing
+ + Call the function BSP_AUDIO_OUT_Resume() to resume playing.
+ Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
+ for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
+ Note. This function should be called only when the audio file is played or paused (not stopped).
+ + For each mode, you may need to implement the relative callback functions into your code.
+ The Callback functions are named AUDIO_OUT_XXX_CallBack() and only their prototypes are declared in
+ the stm32f7308_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
+ + To Stop playing, to modify the volume level, the frequency, the audio frame slot,
+ the device output mode the mute or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(),
+ AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetAudioFrameSlot(), BSP_AUDIO_OUT_SetOutputMode(),
+ BSP_AUDIO_OUT_SetMute() and BSP_AUDIO_OUT_Stop().
+ + The driver API and the callback functions are at the end of the stm32f7308_discovery_audio.h file.
+
+ + Call the function BSP_AUDIO_IN_Init(
+ InputDevice: physical input mode (INPUT_DEVICE_DIGITAL_MICROPHONE_1,
+ INPUT_DEVICE_DIGITAL_MICROPHONE_2, INPUT_DEVICE_DIGITAL_MIC1_MIC2
+ or INPUT_DEVICE_INPUT_LINE_1)
+ Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
+ AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000...)
+ this parameter is relative to the audio file/stream type.
+ )
+ This function configures all the hardware required for the AUDIO IN application (SAI blocks,
+ SAI clock source, GPIOs, DMA and interrupt if needed).
+ This function returns AUDIO_OK if configuration is OK.If the returned value is different from AUDIO_OK then
+ the configuration should be wrong.
+ Note: On STM32F7308-DISCOVERY, two SAI blocks are configured and their DMA streams are configured
+ in CIRCULAR mode.
+ + Call the function BSP_AUDIO_IN_RECORD(
+ pBuf: pointer to the recorded audio data file address
+ Size: size of the buffer to be written in Bytes
+ )
+ to start recording from microphones.
+
+ + Call the function BSP_AUDIO_IN_Pause() to pause recording
+ + Call the function BSP_AUDIO_IN_Resume() to recording playing.
+ Note. After calling BSP_AUDIO_IN_Pause() function for pause, only BSP_AUDIO_IN_Resume() should be called
+ for resume (it is not allowed to call BSP_AUDIO_IN_RECORD() in this case).
+ + Call the function BSP_AUDIO_IN_Stop() to stop recording
+ + For each mode, you may need to implement the relative callback functions into your code.
+ The Callback functions are named BSP_AUDIO_IN_XXX_CallBack() and only their prototypes are declared in
+ the stm32f7308_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
+
+ + Call the function BSP_AUDIO_IN_OUT_Init(
+ InputDevice : physical input mode (INPUT_DEVICE_DIGITAL_MICROPHONE_1,
+ INPUT_DEVICE_DIGITAL_MICROPHONE_2, INPUT_DEVICE_DIGITAL_MIC1_MIC2
+ or INPUT_DEVICE_INPUT_LINE_1)
+ OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER,
+ OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
+ Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
+ AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...)
+ this parameter is relative to the audio file/stream type.
+ )
+ This function configures all the hardware required for the AUDIO IN(record) and AUDIO OUT(play)
+ application (SAI blocks, SAI clock source, GPIOs, DMA and interrupt if needed).
+
+ Driver architecture:
+ --------------------
+ + This driver provides the High Audio Layer: consists of the function API exported in the stm32f7308_discovery_audio.h file
+ (BSP_AUDIO_OUT_Init(), BSP_AUDIO_OUT_Play() ...)
+ + This driver provide also the Media Access Layer (MAL): which consists of functions allowing to access the media containing/
+ providing the audio file/stream. These functions are also included as local functions into
+ the stm32f7308_discovery_audio.c file (SAIx_Out_Init() and SAIx_Out_DeInit(), SAIx_In_Init() and SAIx_In_DeInit())
+
+ Known Limitations:
+ ------------------
+ 1- If the TDM Format used to play in parallel 2 audio Stream (the first Stream is configured in codec SLOT0 and second
+ Stream in SLOT1) the Pause/Resume, volume and mute feature will control the both streams.
+ 2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size,
+ File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
+ 3- Supports only Stereo audio streaming.
+ 4- Supports only 16-bits audio data size.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
Release
+Notes for STM32F7508-Discovery BSP Driver
+
Copyright
+2018 STMicroelectronics
+
+
+
+
+
+
+
+
+
+
The BSP (Board Specific
+Package) drivers are parts of the STM32Cube package based on the HAL
+drivers and provide a set of high level APIs relative to the hardware
+components and features in the evaluation boards, discovery kits and nucleo
+boards coming with the STM32Cube package for a given STM32 serie.
+
The BSP drivers allow a quick access to the boards’
+services using high level APIs and without any specific configuration as the
+link with the HAL and the external components is done in intrinsic within the drivers.
+
+
From project settings points of view, user has only
+to add the necessary driver’s files in the workspace and call the needed
+functions from examples. However some low level
+configuration functions are weak and can be overridden by the applications if user
+wants to change some BSP drivers default behavior.
First official release
+of the STM32F7508-DISCO board BSP
+drivers
+
Dependencies
+
+
+
+
+
+
+
STM32F7xx_HAL_Driver V1.2.6
+
BSP Common V4.0.1
License
+
This software component is licensed by ST under BSD 3-Clause
+license, the "License"; You may not use this component except
+in compliance with the License. You may obtain a copy of the License at:
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery.c b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery.c
new file mode 100644
index 00000000..bcb6e2fd
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery.c
@@ -0,0 +1,886 @@
+/**
+ ******************************************************************************
+ * @file stm32f7508_discovery.c
+ * @author MCD Application Team
+ * @brief This file provides a set of firmware functions to manage LEDs,
+ * push-buttons and COM ports available on STM32F7508-Discovery
+ * board(MB1191) from STMicroelectronics.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F7508_DISCOVERY_H
+#define __STM32F7508_DISCOVERY_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY_LOW_LEVEL
+ * @{
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_LOW_LEVEL_Exported_Types STM32F7508_DISCOVERY_LOW_LEVEL Exported Types
+ * @{
+ */
+typedef enum
+{
+LED1 = 0,
+LED_GREEN = LED1,
+}Led_TypeDef;
+
+typedef enum
+{
+ BUTTON_WAKEUP = 0,
+ BUTTON_TAMPER = 1,
+ BUTTON_KEY = 2
+}Button_TypeDef;
+
+typedef enum
+{
+ BUTTON_MODE_GPIO = 0,
+ BUTTON_MODE_EXTI = 1
+}ButtonMode_TypeDef;
+
+typedef enum
+{
+ COM1 = 0,
+ COM2 = 1
+}COM_TypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_LOW_LEVEL_Exported_Constants STM32F7508_DISCOVERY_LOW_LEVEL Exported Constants
+ * @{
+ */
+
+/**
+ * @brief Define for STM32F7508_DISCOVERY board
+ */
+#if !defined (USE_STM32F7508_DISCO)
+ #define USE_STM32F7508_DISCO
+#endif
+
+/** @addtogroup STM32F7508_DISCOVERY_LOW_LEVEL_LED
+ * @{
+ */
+
+#define LEDn ((uint8_t)1)
+
+#define LED1_GPIO_PORT GPIOI
+#define LED1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define LED1_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define LED1_PIN GPIO_PIN_1
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY_LOW_LEVEL_BUTTON
+ * @{
+ */
+#define BUTTONn ((uint8_t)3)
+
+/**
+ * @brief Wakeup push-button
+ */
+#define WAKEUP_BUTTON_PIN GPIO_PIN_11
+#define WAKEUP_BUTTON_GPIO_PORT GPIOI
+#define WAKEUP_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define WAKEUP_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define WAKEUP_BUTTON_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @brief Tamper push-button
+ */
+#define TAMPER_BUTTON_PIN GPIO_PIN_11
+#define TAMPER_BUTTON_GPIO_PORT GPIOI
+#define TAMPER_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define TAMPER_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define TAMPER_BUTTON_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @brief Key push-button
+ */
+#define KEY_BUTTON_PIN GPIO_PIN_11
+#define KEY_BUTTON_GPIO_PORT GPIOI
+#define KEY_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define KEY_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define KEY_BUTTON_EXTI_IRQn EXTI15_10_IRQn
+
+#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == 0) WAKEUP_BUTTON_GPIO_CLK_ENABLE(); else\
+ if((__INDEX__) == 1) TAMPER_BUTTON_GPIO_CLK_ENABLE(); else\
+ KEY_BUTTON_GPIO_CLK_ENABLE(); } while(0)
+
+#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? WAKEUP_BUTTON_GPIO_CLK_DISABLE() :\
+ ((__INDEX__) == 1) ? TAMPER_BUTTON_GPIO_CLK_DISABLE() : KEY_BUTTON_GPIO_CLK_DISABLE())
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY_LOW_LEVEL_SIGNAL
+ * @{
+ */
+#define SIGNALn ((uint8_t)1)
+
+/**
+ * @brief SD-detect signal
+ */
+#define SD_DETECT_PIN GPIO_PIN_13
+#define SD_DETECT_GPIO_PORT GPIOC
+#define SD_DETECT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define SD_DETECT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
+#define SD_DETECT_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @brief Touch screen interrupt signal
+ */
+#define TS_INT_PIN GPIO_PIN_13
+#define TS_INT_GPIO_PORT GPIOI
+#define TS_INT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define TS_INT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define TS_INT_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY_LOW_LEVEL_COM
+ * @{
+ */
+#define COMn ((uint8_t)1)
+
+/**
+ * @brief Definition for COM port1, connected to USART1
+ */
+#define DISCOVERY_COM1 USART1
+#define DISCOVERY_COM1_CLK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE()
+#define DISCOVERY_COM1_CLK_DISABLE() __HAL_RCC_USART1_CLK_DISABLE()
+
+#define DISCOVERY_COM1_TX_PIN GPIO_PIN_9
+#define DISCOVERY_COM1_TX_GPIO_PORT GPIOA
+#define DISCOVERY_COM1_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define DISCOVERY_COM1_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define DISCOVERY_COM1_TX_AF GPIO_AF7_USART1
+
+#define DISCOVERY_COM1_RX_PIN GPIO_PIN_7
+#define DISCOVERY_COM1_RX_GPIO_PORT GPIOB
+#define DISCOVERY_COM1_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define DISCOVERY_COM1_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
+#define DISCOVERY_COM1_RX_AF GPIO_AF7_USART1
+
+#define DISCOVERY_COM1_IRQn USART1_IRQn
+
+#define DISCOVERY_COMx_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) DISCOVERY_COM1_CLK_ENABLE(); } while(0)
+#define DISCOVERY_COMx_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? DISCOVERY_COM1_CLK_DISABLE() : 0)
+
+#define DISCOVERY_COMx_TX_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) DISCOVERY_COM1_TX_GPIO_CLK_ENABLE(); } while(0)
+#define DISCOVERY_COMx_TX_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? DISCOVERY_COM1_TX_GPIO_CLK_DISABLE() : 0)
+
+#define DISCOVERY_COMx_RX_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) DISCOVERY_COM1_RX_GPIO_CLK_ENABLE(); } while(0)
+#define DISCOVERY_COMx_RX_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? DISCOVERY_COM1_RX_GPIO_CLK_DISABLE() : 0)
+
+/* Exported constant IO ------------------------------------------------------*/
+
+#define LCD_I2C_ADDRESS ((uint16_t)0x70)
+#define CAMERA_I2C_ADDRESS ((uint16_t)0x60)
+#define AUDIO_I2C_ADDRESS ((uint16_t)0x34)
+#define EEPROM_I2C_ADDRESS_A01 ((uint16_t)0xA0)
+#define EEPROM_I2C_ADDRESS_A02 ((uint16_t)0xA6)
+#define TS_I2C_ADDRESS ((uint16_t)0x70)
+
+/* I2C clock speed configuration (in Hz)
+ WARNING:
+ Make sure that this define is not already declared in other files (ie.
+ stm32f7508_discovery.h file). It can be used in parallel by other modules. */
+#ifndef I2C_SPEED
+ #define I2C_SPEED ((uint32_t)100000)
+#endif /* I2C_SPEED */
+
+/* User can use this section to tailor I2Cx/I2Cx instance used and associated
+ resources */
+/* Definition for AUDIO and LCD I2Cx resources */
+#define DISCOVERY_AUDIO_I2Cx I2C3
+#define DISCOVERY_AUDIO_I2Cx_CLK_ENABLE() __HAL_RCC_I2C3_CLK_ENABLE()
+#define DISCOVERY_AUDIO_DMAx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
+#define DISCOVERY_AUDIO_I2Cx_SCL_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+
+#define DISCOVERY_AUDIO_I2Cx_FORCE_RESET() __HAL_RCC_I2C3_FORCE_RESET()
+#define DISCOVERY_AUDIO_I2Cx_RELEASE_RESET() __HAL_RCC_I2C3_RELEASE_RESET()
+
+/* Definition for I2Cx Pins */
+#define DISCOVERY_AUDIO_I2Cx_SCL_PIN GPIO_PIN_7
+#define DISCOVERY_AUDIO_I2Cx_SCL_SDA_GPIO_PORT GPIOH
+#define DISCOVERY_AUDIO_I2Cx_SCL_SDA_AF GPIO_AF4_I2C3
+#define DISCOVERY_AUDIO_I2Cx_SDA_PIN GPIO_PIN_8
+
+/* I2C interrupt requests */
+#define DISCOVERY_AUDIO_I2Cx_EV_IRQn I2C3_EV_IRQn
+#define DISCOVERY_AUDIO_I2Cx_ER_IRQn I2C3_ER_IRQn
+
+/* Definition for external, camera and Arduino connector I2Cx resources */
+#define DISCOVERY_EXT_I2Cx I2C1
+#define DISCOVERY_EXT_I2Cx_CLK_ENABLE() __HAL_RCC_I2C1_CLK_ENABLE()
+#define DISCOVERY_EXT_DMAx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
+#define DISCOVERY_EXT_I2Cx_SCL_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+
+#define DISCOVERY_EXT_I2Cx_FORCE_RESET() __HAL_RCC_I2C1_FORCE_RESET()
+#define DISCOVERY_EXT_I2Cx_RELEASE_RESET() __HAL_RCC_I2C1_RELEASE_RESET()
+
+/* Definition for I2Cx Pins */
+#define DISCOVERY_EXT_I2Cx_SCL_PIN GPIO_PIN_8
+#define DISCOVERY_EXT_I2Cx_SCL_SDA_GPIO_PORT GPIOB
+#define DISCOVERY_EXT_I2Cx_SCL_SDA_AF GPIO_AF4_I2C1
+#define DISCOVERY_EXT_I2Cx_SDA_PIN GPIO_PIN_9
+
+/* I2C interrupt requests */
+#define DISCOVERY_EXT_I2Cx_EV_IRQn I2C1_EV_IRQn
+#define DISCOVERY_EXT_I2Cx_ER_IRQn I2C1_ER_IRQn
+
+/* I2C TIMING Register define when I2C clock source is SYSCLK */
+/* I2C TIMING is calculated from APB1 source clock = 50 MHz */
+/* Due to the big MOFSET capacity for adapting the camera level the rising time is very large (>1us) */
+/* 0x40912732 takes in account the big rising and aims a clock of 100khz */
+#ifndef DISCOVERY_I2Cx_TIMING
+#define DISCOVERY_I2Cx_TIMING ((uint32_t)0x40912732)
+#endif /* DISCOVERY_I2Cx_TIMING */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_LOW_LEVEL_Exported_Macros STM32F7508_DISCOVERY_LOW_LEVEL Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY_LOW_LEVEL_Exported_Functions
+ * @{
+ */
+uint32_t BSP_GetVersion(void);
+void BSP_LED_Init(Led_TypeDef Led);
+void BSP_LED_DeInit(Led_TypeDef Led);
+void BSP_LED_On(Led_TypeDef Led);
+void BSP_LED_Off(Led_TypeDef Led);
+void BSP_LED_Toggle(Led_TypeDef Led);
+void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode);
+void BSP_PB_DeInit(Button_TypeDef Button);
+uint32_t BSP_PB_GetState(Button_TypeDef Button);
+void BSP_COM_Init(COM_TypeDef COM, UART_HandleTypeDef *husart);
+void BSP_COM_DeInit(COM_TypeDef COM, UART_HandleTypeDef *huart);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F7508_DISCOVERY_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_audio.c b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_audio.c
new file mode 100644
index 00000000..2cb86269
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_audio.c
@@ -0,0 +1,1364 @@
+/**
+ ******************************************************************************
+ * @file stm32f7508_discovery_audio.c
+ * @author MCD Application Team
+ * @brief This file provides the Audio driver for the STM32F7508-Discovery board.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ + This driver supports STM32F7xx devices on STM32F7508-Discovery (MB1191) board.
+ + Call the function BSP_AUDIO_OUT_Init(
+ OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER,
+ OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
+ Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
+ AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...)
+ this parameter is relative to the audio file/stream type.
+ )
+ This function configures all the hardware required for the audio application (codec, I2C, SAI,
+ GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
+ If the returned value is different from AUDIO_OK or the function is stuck then the communication with
+ the codec or the MFX has failed (try to un-plug the power or reset device in this case).
+ - OUTPUT_DEVICE_SPEAKER : only speaker will be set as output for the audio stream.
+ - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
+ - OUTPUT_DEVICE_BOTH : both Speaker and Headphone are used as outputs for the audio stream
+ at the same time.
+ Note. On STM32F7508-Discovery SAI_DMA is configured in CIRCULAR mode. Due to this the application
+ does NOT need to call BSP_AUDIO_OUT_ChangeBuffer() to assure streaming.
+ + Call the function BSP_DISCOVERY_AUDIO_OUT_Play(
+ pBuffer: pointer to the audio data file address
+ Size : size of the buffer to be sent in Bytes
+ )
+ to start playing (for the first time) from the audio file/stream.
+ + Call the function BSP_AUDIO_OUT_Pause() to pause playing
+ + Call the function BSP_AUDIO_OUT_Resume() to resume playing.
+ Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
+ for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
+ Note. This function should be called only when the audio file is played or paused (not stopped).
+ + For each mode, you may need to implement the relative callback functions into your code.
+ The Callback functions are named AUDIO_OUT_XXX_CallBack() and only their prototypes are declared in
+ the stm32f7508_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
+ + To Stop playing, to modify the volume level, the frequency, the audio frame slot,
+ the device output mode the mute or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(),
+ AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetAudioFrameSlot(), BSP_AUDIO_OUT_SetOutputMode(),
+ BSP_AUDIO_OUT_SetMute() and BSP_AUDIO_OUT_Stop().
+ + The driver API and the callback functions are at the end of the stm32f7508_discovery_audio.h file.
+
+ Driver architecture:
+ --------------------
+ + This driver provides the High Audio Layer: consists of the function API exported in the stm32f7508_discovery_audio.h file
+ (BSP_AUDIO_OUT_Init(), BSP_AUDIO_OUT_Play() ...)
+ + This driver provide also the Media Access Layer (MAL): which consists of functions allowing to access the media containing/
+ providing the audio file/stream. These functions are also included as local functions into
+ the stm32f7508_discovery_audio_codec.c file (SAIx_Out_Init() and SAIx_Out_DeInit(), SAIx_In_Init() and SAIx_In_DeInit())
+
+ Known Limitations:
+ ------------------
+ 1- If the TDM Format used to play in parallel 2 audio Stream (the first Stream is configured in codec SLOT0 and second
+ Stream in SLOT1) the Pause/Resume, volume and mute feature will control the both streams.
+ 2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size,
+ File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
+ 3- Supports only Stereo audio streaming.
+ 4- Supports only 16-bits audio data size.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F7508_DISCOVERY_AUDIO_H
+#define __STM32F7508_DISCOVERY_AUDIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include audio component Driver */
+#include "../Components/wm8994/wm8994.h"
+#include "stm32f7508_discovery.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_AUDIO STM32F7508_DISCOVERY_AUDIO
+ * @{
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_AUDIO_Exported_Types STM32F7508_DISCOVERY_AUDIO Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_AUDIO_Exported_Constants STM32F7508_DISCOVERY_AUDIO Exported Constants
+ * @{
+ */
+
+/*------------------------------------------------------------------------------
+ USER SAI defines parameters
+ -----------------------------------------------------------------------------*/
+/* CODEC_AudioFrame_SLOT_TDMMode
+ In W8994 codec the Audio frame contains 4 slots : TDM Mode
+ TDM format :
+ +------------------|------------------|--------------------|-------------------+
+ | CODEC_SLOT0 Left | CODEC_SLOT1 Left | CODEC_SLOT0 Right | CODEC_SLOT1 Right |
+ +------------------------------------------------------------------------------+
+ */
+/* To have 2 separate audio stream in Both headphone and speaker the 4 slot must be activated */
+#define CODEC_AUDIOFRAME_SLOT_0123 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_2 | SAI_SLOTACTIVE_3
+/* To have an audio stream in headphone only SAI Slot 0 and Slot 2 must be activated */
+#define CODEC_AUDIOFRAME_SLOT_02 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_2
+/* To have an audio stream in speaker only SAI Slot 1 and Slot 3 must be activated */
+#define CODEC_AUDIOFRAME_SLOT_13 SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_3
+
+/* SAI OUT peripheral configuration defines */
+#define AUDIO_OUT_SAIx SAI2_Block_A
+#define AUDIO_OUT_SAIx_CLK_ENABLE() __HAL_RCC_SAI2_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_CLK_DISABLE() __HAL_RCC_SAI2_CLK_DISABLE()
+#define AUDIO_OUT_SAIx_SCK_AF GPIO_AF10_SAI2
+#define AUDIO_OUT_SAIx_FS_SD_MCLK_AF GPIO_AF10_SAI2
+
+#define AUDIO_OUT_SAIx_MCLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_MCLK_GPIO_PORT GPIOI
+#define AUDIO_OUT_SAIx_MCLK_PIN GPIO_PIN_4
+#define AUDIO_OUT_SAIx_SCK_SD_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT GPIOI
+#define AUDIO_OUT_SAIx_SCK_PIN GPIO_PIN_5
+#define AUDIO_OUT_SAIx_SD_PIN GPIO_PIN_6
+#define AUDIO_OUT_SAIx_FS_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_FS_GPIO_PORT GPIOI
+#define AUDIO_OUT_SAIx_FS_PIN GPIO_PIN_7
+
+/* SAI DMA Stream definitions */
+#define AUDIO_OUT_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_DMAx_STREAM DMA2_Stream4
+#define AUDIO_OUT_SAIx_DMAx_CHANNEL DMA_CHANNEL_3
+#define AUDIO_OUT_SAIx_DMAx_IRQ DMA2_Stream4_IRQn
+#define AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
+#define AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
+#define DMA_MAX_SZE ((uint16_t)0xFFFF)
+
+#define AUDIO_OUT_SAIx_DMAx_IRQHandler DMA2_Stream4_IRQHandler
+
+/* Select the interrupt preemption priority for the DMA interrupt */
+#define AUDIO_OUT_IRQ_PREPRIO ((uint32_t)0x0E) /* Select the preemption priority level(0 is the highest) */
+
+/*------------------------------------------------------------------------------
+ AUDIO IN CONFIGURATION
+------------------------------------------------------------------------------*/
+/* SAI IN peripheral configuration defines */
+#define AUDIO_IN_SAIx SAI2_Block_B
+#define AUDIO_IN_SAIx_CLK_ENABLE() __HAL_RCC_SAI2_CLK_ENABLE()
+#define AUDIO_IN_SAIx_CLK_DISABLE() __HAL_RCC_SAI2_CLK_DISABLE()
+#define AUDIO_IN_SAIx_SD_AF GPIO_AF10_SAI2
+
+#define AUDIO_IN_SAIx_SD_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
+#define AUDIO_IN_SAIx_SD_GPIO_PORT GPIOG
+#define AUDIO_IN_SAIx_SD_PIN GPIO_PIN_10
+
+#define AUDIO_IN_INT_GPIO_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+#define AUDIO_IN_INT_GPIO_PORT GPIOH
+#define AUDIO_IN_INT_GPIO_PIN GPIO_PIN_15
+#define AUDIO_IN_INT_IRQ EXTI15_10_IRQn
+
+/* SAI DMA Stream definitions */
+#define AUDIO_IN_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
+#define AUDIO_IN_SAIx_DMAx_STREAM DMA2_Stream7
+#define AUDIO_IN_SAIx_DMAx_CHANNEL DMA_CHANNEL_0
+#define AUDIO_IN_SAIx_DMAx_IRQ DMA2_Stream7_IRQn
+#define AUDIO_IN_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
+#define AUDIO_IN_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
+
+#define AUDIO_IN_SAIx_DMAx_IRQHandler DMA2_Stream7_IRQHandler
+#define AUDIO_IN_INT_IRQHandler EXTI15_10_IRQHandler
+
+/* Select the interrupt preemption priority and subpriority for the IT/DMA interrupt */
+#define AUDIO_IN_IRQ_PREPRIO ((uint32_t)0x0F) /* Select the preemption priority level(0 is the highest) */
+
+/*------------------------------------------------------------------------------
+ CONFIGURATION: Audio Driver Configuration parameters
+------------------------------------------------------------------------------*/
+
+#define AUDIODATA_SIZE ((uint16_t)2) /* 16-bits audio data size */
+
+/* Audio status definition */
+#define AUDIO_OK ((uint8_t)0)
+#define AUDIO_ERROR ((uint8_t)1)
+#define AUDIO_TIMEOUT ((uint8_t)2)
+
+/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */
+#define DEFAULT_AUDIO_IN_FREQ I2S_AUDIOFREQ_16K
+#define DEFAULT_AUDIO_IN_BIT_RESOLUTION ((uint8_t)16)
+#define DEFAULT_AUDIO_IN_CHANNEL_NBR ((uint8_t)2) /* Mono = 1, Stereo = 2 */
+#define DEFAULT_AUDIO_IN_VOLUME ((uint16_t)64)
+
+/*------------------------------------------------------------------------------
+ OPTIONAL Configuration defines parameters
+------------------------------------------------------------------------------*/
+
+/* Delay for the Codec to be correctly reset */
+#define CODEC_RESET_DELAY ((uint8_t)5)
+
+
+/*------------------------------------------------------------------------------
+ OUTPUT DEVICES definition
+------------------------------------------------------------------------------*/
+/* Alias on existing output devices to adapt for 2 headphones output */
+#define OUTPUT_DEVICE_HEADPHONE1 OUTPUT_DEVICE_HEADPHONE
+#define OUTPUT_DEVICE_HEADPHONE2 OUTPUT_DEVICE_SPEAKER /* Headphone2 is connected to Speaker output of the wm8994 */
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_AUDIO_Exported_Variables STM32F7508_DISCOVERY_AUDIO Exported Variables
+ * @{
+ */
+extern __IO uint16_t AudioInVolume;
+ /**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_AUDIO_Exported_Macros STM32F7508_DISCOVERY_AUDIO Exported Macros
+ * @{
+ */
+#define DMA_MAX(x) (((x) <= DMA_MAX_SZE)? (x):DMA_MAX_SZE)
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY_AUDIO_OUT_Exported_Functions
+ * @{
+ */
+uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq);
+uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size);
+void BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size);
+uint8_t BSP_AUDIO_OUT_Pause(void);
+uint8_t BSP_AUDIO_OUT_Resume(void);
+uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option);
+uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume);
+void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq);
+void BSP_AUDIO_OUT_SetAudioFrameSlot(uint32_t AudioFrameSlot);
+uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd);
+uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output);
+void BSP_AUDIO_OUT_DeInit(void);
+
+/* User Callbacks: user has to implement these functions in his code if they are needed. */
+/* This function is called when the requested data has been completely transferred.*/
+void BSP_AUDIO_OUT_TransferComplete_CallBack(void);
+
+/* This function is called when half of the requested buffer has been transferred. */
+void BSP_AUDIO_OUT_HalfTransfer_CallBack(void);
+
+/* This function is called when an Interrupt due to transfer error on or peripheral
+ error occurs. */
+void BSP_AUDIO_OUT_Error_CallBack(void);
+
+/* These function can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_AUDIO_OUT_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params);
+void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params);
+void BSP_AUDIO_OUT_MspDeInit(SAI_HandleTypeDef *hsai, void *Params);
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_AUDIO_IN_Exported_Functions STM32F7508_DISCOVERY_AUDIO_IN Exported Functions
+ * @{
+ */
+uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_InitEx(uint16_t InputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_OUT_Init(uint16_t InputDevice, uint16_t OutputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_Record(uint16_t *pData, uint32_t Size);
+uint8_t BSP_AUDIO_IN_Stop(uint32_t Option);
+uint8_t BSP_AUDIO_IN_Pause(void);
+uint8_t BSP_AUDIO_IN_Resume(void);
+uint8_t BSP_AUDIO_IN_SetVolume(uint8_t Volume);
+void BSP_AUDIO_IN_DeInit(void);
+/* User Callbacks: user has to implement these functions in his code if they are needed. */
+/* This function should be implemented by the user application.
+ It is called into this driver when the current buffer is filled to prepare the next
+ buffer pointer and its size. */
+void BSP_AUDIO_IN_TransferComplete_CallBack(void);
+void BSP_AUDIO_IN_HalfTransfer_CallBack(void);
+
+/* This function is called when an Interrupt due to transfer error on or peripheral
+ error occurs. */
+void BSP_AUDIO_IN_Error_CallBack(void);
+
+/* These function can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_AUDIO_IN_MspInit(SAI_HandleTypeDef *hsai, void *Params);
+void BSP_AUDIO_IN_MspDeInit(SAI_HandleTypeDef *hsai, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F7508_DISCOVERY_AUDIO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_camera.c b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_camera.c
new file mode 100644
index 00000000..35a6f8b9
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_camera.c
@@ -0,0 +1,643 @@
+/**
+ ******************************************************************************
+ * @file stm32f7508_discovery_camera.c
+ * @author MCD Application Team
+ * @brief This file includes the driver for Camera modules mounted on
+ * STM32F7508-Discovery board.
+ @verbatim
+ How to use this driver:
+ ------------------------
+ - This driver is used to drive the camera.
+ - The OV9655 component driver MUST be included with this driver.
+
+ Driver description:
+ -------------------
+ + Initialization steps:
+ o Initialize the camera using the BSP_CAMERA_Init() function.
+ o Start the camera capture/snapshot using the CAMERA_Start() function.
+ o Suspend, resume or stop the camera capture using the following functions:
+ - BSP_CAMERA_Suspend()
+ - BSP_CAMERA_Resume()
+ - BSP_CAMERA_Stop()
+
+ + Options
+ o Increase or decrease on the fly the brightness and/or contrast
+ using the following function:
+ - BSP_CAMERA_ContrastBrightnessConfig
+ o Add a special effect on the fly using the following functions:
+ - BSP_CAMERA_BlackWhiteConfig()
+ - BSP_CAMERA_ColorEffectConfig()
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F7508_DISCOVERY_CAMERA_H
+#define __STM32F7508_DISCOVERY_CAMERA_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include Camera component Driver */
+#include "../Components/ov9655/ov9655.h"
+#include "stm32f7508_discovery.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY_CAMERA
+ * @{
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_CAMERA_Exported_Types STM32F7508_DISCOVERY_CAMERA Exported Types
+ * @{
+ */
+
+/**
+ * @brief Camera State structures definition
+ */
+typedef enum
+{
+ CAMERA_OK = 0x00,
+ CAMERA_ERROR = 0x01,
+ CAMERA_TIMEOUT = 0x02,
+ CAMERA_NOT_DETECTED = 0x03,
+ CAMERA_NOT_SUPPORTED = 0x04
+
+} Camera_StatusTypeDef;
+
+#define RESOLUTION_R160x120 CAMERA_R160x120 /* QQVGA Resolution */
+#define RESOLUTION_R320x240 CAMERA_R320x240 /* QVGA Resolution */
+#define RESOLUTION_R480x272 CAMERA_R480x272 /* 480x272 Resolution */
+#define RESOLUTION_R640x480 CAMERA_R640x480 /* VGA Resolution */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_CAMERA_Exported_Constants STM32F7508_DISCOVERY_CAMERA Exported Constants
+ * @{
+ */
+#define BSP_CAMERA_IRQHandler DCMI_IRQHandler
+#define BSP_CAMERA_DMA_IRQHandler DMA2_Stream1_IRQHandler
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY_CAMERA_Exported_Functions
+ * @{
+ */
+uint8_t BSP_CAMERA_Init(uint32_t Resolution);
+uint8_t BSP_CAMERA_DeInit(void);
+void BSP_CAMERA_ContinuousStart(uint8_t *buff);
+void BSP_CAMERA_SnapshotStart(uint8_t *buff);
+void BSP_CAMERA_Suspend(void);
+void BSP_CAMERA_Resume(void);
+uint8_t BSP_CAMERA_Stop(void);
+void BSP_CAMERA_PwrUp(void);
+void BSP_CAMERA_PwrDown(void);
+void BSP_CAMERA_LineEventCallback(void);
+void BSP_CAMERA_VsyncEventCallback(void);
+void BSP_CAMERA_FrameEventCallback(void);
+void BSP_CAMERA_ErrorCallback(void);
+
+/* Camera features functions prototype */
+void BSP_CAMERA_ContrastBrightnessConfig(uint32_t contrast_level, uint32_t brightness_level);
+void BSP_CAMERA_BlackWhiteConfig(uint32_t Mode);
+void BSP_CAMERA_ColorEffectConfig(uint32_t Effect);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_CAMERA_MspInit(DCMI_HandleTypeDef *hdcmi, void *Params);
+void BSP_CAMERA_MspDeInit(DCMI_HandleTypeDef *hdcmi, void *Params);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F7508_DISCOVERY_CAMERA_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_eeprom.c b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_eeprom.c
new file mode 100644
index 00000000..ed2bd4a0
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_eeprom.c
@@ -0,0 +1,461 @@
+/**
+ ******************************************************************************
+ * @file stm32f7508_discovery_eeprom.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage an I2C M24LR64
+ * EEPROM memory.
+ @verbatim
+ To be able to use this driver, the switch EE_M24LR64 must be defined
+ in your toolchain compiler preprocessor
+
+ ===================================================================
+ Notes:
+ - The I2C EEPROM memory (M24LR64) is available on separate daughter
+ board ANT7-M24LR-A, which is not provided with the STM32F7508_DISCOVERY
+ board.
+ To use this driver you have to connect the ANT7-M24LR-A to CN3
+ connector of STM32F7508_DISCOVERY board.
+ ===================================================================
+
+ It implements a high level communication layer for read and write
+ from/to this memory. The needed STM32F7xx hardware resources (I2C and
+ GPIO) are defined in stm32f7508_discovery.h file, and the initialization is
+ performed in EEPROM_IO_Init() function declared in stm32f7508_discovery.c
+ file.
+ You can easily tailor this driver to any other development board,
+ by just adapting the defines for hardware resources and
+ EEPROM_IO_Init() function.
+
+ @note In this driver, basic read and write functions (BSP_EEPROM_ReadBuffer()
+ and BSP_EEPROM_WritePage()) use DMA mode to perform the data
+ transfer to/from EEPROM memory.
+
+ @note Regarding BSP_EEPROM_WritePage(), it is an optimized function to perform
+ small write (less than 1 page) BUT the number of bytes (combined to write start address) must not
+ cross the EEPROM page boundary. This function can only writes into
+ the boundaries of an EEPROM page.
+ This function doesn't check on boundaries condition (in this driver
+ the function BSP_EEPROM_WriteBuffer() which calls BSP_EEPROM_WritePage() is
+ responsible of checking on Page boundaries).
+
+
+ +-----------------------------------------------------------------+
+ | Pin assignment for M24LR64 EEPROM |
+ +---------------------------------------+-----------+-------------+
+ | STM32F7xx I2C Pins | EEPROM | Pin |
+ +---------------------------------------+-----------+-------------+
+ | . | E0(GND) | 1 (0V) |
+ | . | AC0 | 2 |
+ | . | AC1 | 3 |
+ | . | VSS | 4 (0V) |
+ | SDA | SDA | 5 |
+ | SCL | SCL | 6 |
+ | . | E1(GND) | 7 (0V) |
+ | . | VDD | 8 (3.3V) |
+ +---------------------------------------+-----------+-------------+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Dependencies
+- stm32f7508_discovery.c
+EndDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7508_discovery_eeprom.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY_EEPROM
+ * @brief This file includes the I2C EEPROM driver of STM32F7508-Discovery board.
+ * @{
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_EEPROM_Private_Types STM32F7508_DISCOVERY_EEPROM Private Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_EEPROM_Private_Defines STM32F7508_DISCOVERY_EEPROM Private Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_EEPROM_Private_Macros STM32F7508_DISCOVERY_EEPROM Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_EEPROM_Private_Variables STM32F7508_DISCOVERY_EEPROM Private Variables
+ * @{
+ */
+__IO uint16_t EEPROMAddress = 0;
+__IO uint16_t EEPROMDataRead;
+__IO uint8_t EEPROMDataWrite;
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_EEPROM_Private_Function_Prototypes STM32F7508_DISCOVERY_EEPROM Private Function Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_EEPROM_Exported_Functions STM32F7508_DISCOVERY_EEPROM Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes peripherals used by the I2C EEPROM driver.
+ *
+ * @note There are 2 different versions of M24LR64 (A01 & A02).
+ * Then try to connect on 1st one (EEPROM_I2C_ADDRESS_A01)
+ * and if problem, check the 2nd one (EEPROM_I2C_ADDRESS_A02)
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0)
+ */
+uint32_t BSP_EEPROM_Init(void)
+{
+ /* I2C Initialization */
+ EEPROM_IO_Init();
+
+ /* Select the EEPROM address for A01 and check if OK */
+ EEPROMAddress = EEPROM_I2C_ADDRESS_A01;
+ if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
+ {
+ /* Select the EEPROM address for A02 and check if OK */
+ EEPROMAddress = EEPROM_I2C_ADDRESS_A02;
+ if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
+ {
+ return EEPROM_FAIL;
+ }
+ }
+ return EEPROM_OK;
+}
+
+/**
+ * @brief DeInitializes the EEPROM.
+ * @retval EEPROM state
+ */
+uint8_t BSP_EEPROM_DeInit(void)
+{
+ /* I2C won't be disabled because common to other functionalities */
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Reads a block of data from the EEPROM.
+ * @param pBuffer: pointer to the buffer that receives the data read from
+ * the EEPROM.
+ * @param ReadAddr: EEPROM's internal address to start reading from.
+ * @param NumByteToRead: pointer to the variable holding number of bytes to
+ * be read from the EEPROM.
+ *
+ * @note The variable pointed by NumByteToRead is reset to 0 when all the
+ * data are read from the EEPROM. Application should monitor this
+ * variable in order know when the transfer is complete.
+ *
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
+{
+ uint32_t buffersize = *NumByteToRead;
+
+ /* Set the pointer to the Number of data to be read. This pointer will be used
+ by the DMA Transfer Completer interrupt Handler in order to reset the
+ variable to 0. User should check on this variable in order to know if the
+ DMA transfer has been complete or not. */
+ EEPROMDataRead = *NumByteToRead;
+
+ if(EEPROM_IO_ReadData(EEPROMAddress, ReadAddr, pBuffer, buffersize) != HAL_OK)
+ {
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ return EEPROM_FAIL;
+ }
+
+ /* If all operations OK, return EEPROM_OK (0) */
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Writes more than one byte to the EEPROM with a single WRITE cycle.
+ *
+ * @note The number of bytes (combined to write start address) must not
+ * cross the EEPROM page boundary. This function can only write into
+ * the boundaries of an EEPROM page.
+ * This function doesn't check on boundaries condition (in this driver
+ * the function BSP_EEPROM_WriteBuffer() which calls BSP_EEPROM_WritePage() is
+ * responsible of checking on Page boundaries).
+ *
+ * @param pBuffer: pointer to the buffer containing the data to be written to
+ * the EEPROM.
+ * @param WriteAddr: EEPROM's internal address to write to.
+ * @param NumByteToWrite: pointer to the variable holding number of bytes to
+ * be written into the EEPROM.
+ *
+ * @note The variable pointed by NumByteToWrite is reset to 0 when all the
+ * data are written to the EEPROM. Application should monitor this
+ * variable in order know when the transfer is complete.
+ *
+ * @note This function just configure the communication and enable the DMA
+ * channel to transfer data. Meanwhile, the user application may perform
+ * other tasks in parallel.
+ *
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite)
+{
+ uint32_t buffersize = *NumByteToWrite;
+ uint32_t status = EEPROM_OK;
+
+ /* Set the pointer to the Number of data to be written. This pointer will be used
+ by the DMA Transfer Completer interrupt Handler in order to reset the
+ variable to 0. User should check on this variable in order to know if the
+ DMA transfer has been complete or not. */
+ EEPROMDataWrite = *NumByteToWrite;
+
+ if(EEPROM_IO_WriteData(EEPROMAddress, WriteAddr, pBuffer, buffersize) != HAL_OK)
+ {
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ status = EEPROM_FAIL;
+ }
+
+ if(BSP_EEPROM_WaitEepromStandbyState() != EEPROM_OK)
+ {
+ return EEPROM_FAIL;
+ }
+
+ /* If all operations OK, return EEPROM_OK (0) */
+ return status;
+}
+
+/**
+ * @brief Writes buffer of data to the I2C EEPROM.
+ * @param pBuffer: pointer to the buffer containing the data to be written
+ * to the EEPROM.
+ * @param WriteAddr: EEPROM's internal address to write to.
+ * @param NumByteToWrite: number of bytes to write to the EEPROM.
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_WriteBuffer(uint8_t *pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
+{
+ uint16_t numofpage = 0, numofsingle = 0, count = 0;
+ uint16_t addr = 0;
+ uint8_t dataindex = 0;
+ uint32_t status = EEPROM_OK;
+
+ addr = WriteAddr % EEPROM_PAGESIZE;
+ count = EEPROM_PAGESIZE - addr;
+ numofpage = NumByteToWrite / EEPROM_PAGESIZE;
+ numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
+
+ /* If WriteAddr is EEPROM_PAGESIZE aligned */
+ if(addr == 0)
+ {
+ /* If NumByteToWrite < EEPROM_PAGESIZE */
+ if(numofpage == 0)
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ /* Start writing data */
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ /* If NumByteToWrite > EEPROM_PAGESIZE */
+ else
+ {
+ while(numofpage--)
+ {
+ /* Store the number of data to be written */
+ dataindex = EEPROM_PAGESIZE;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+
+ WriteAddr += EEPROM_PAGESIZE;
+ pBuffer += EEPROM_PAGESIZE;
+ }
+
+ if(numofsingle!=0)
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ }
+ }
+ /* If WriteAddr is not EEPROM_PAGESIZE aligned */
+ else
+ {
+ /* If NumByteToWrite < EEPROM_PAGESIZE */
+ if(numofpage== 0)
+ {
+ /* If the number of data to be written is more than the remaining space
+ in the current page: */
+ if(NumByteToWrite > count)
+ {
+ /* Store the number of data to be written */
+ dataindex = count;
+ /* Write the data contained in same page */
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+
+ /* Store the number of data to be written */
+ dataindex = (NumByteToWrite - count);
+ /* Write the remaining data in the following page */
+ status = BSP_EEPROM_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ else
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ }
+ /* If NumByteToWrite > EEPROM_PAGESIZE */
+ else
+ {
+ NumByteToWrite -= count;
+ numofpage = NumByteToWrite / EEPROM_PAGESIZE;
+ numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
+
+ if(count != 0)
+ {
+ /* Store the number of data to be written */
+ dataindex = count;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ WriteAddr += count;
+ pBuffer += count;
+ }
+
+ while(numofpage--)
+ {
+ /* Store the number of data to be written */
+ dataindex = EEPROM_PAGESIZE;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ WriteAddr += EEPROM_PAGESIZE;
+ pBuffer += EEPROM_PAGESIZE;
+ }
+ if(numofsingle != 0)
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ }
+ }
+
+ /* If all operations OK, return EEPROM_OK (0) */
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Wait for EEPROM Standby state.
+ *
+ * @note This function allows to wait and check that EEPROM has finished the
+ * last operation. It is mostly used after Write operation: after receiving
+ * the buffer to be written, the EEPROM may need additional time to actually
+ * perform the write operation. During this time, it doesn't answer to
+ * I2C packets addressed to it. Once the write operation is complete
+ * the EEPROM responds to its address.
+ *
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_WaitEepromStandbyState(void)
+{
+ /* Check if the maximum allowed number of trials has bee reached */
+ if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
+ {
+ /* If the maximum number of trials has been reached, exit the function */
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ return EEPROM_TIMEOUT;
+ }
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Basic management of the timeout situation.
+ * @retval None
+ */
+__weak void BSP_EEPROM_TIMEOUT_UserCallback(void)
+{
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_eeprom.h b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_eeprom.h
new file mode 100644
index 00000000..d4293d2a
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_eeprom.h
@@ -0,0 +1,122 @@
+/**
+ ******************************************************************************
+ * @file stm32f7508_discovery_eeprom.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for
+ * the stm32f7508_discovery_eeprom.c firmware driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F7508_DISCOVERY_EEPROM_H
+#define __STM32F7508_DISCOVERY_EEPROM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7508_discovery.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY_EEPROM
+ * @brief This file includes the I2C EEPROM driver of STM32F7508-Discovery board.
+ * @{
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_EEPROM_Exported_Types STM32F7508_DISCOVERY_EEPROM Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_EEPROM_Exported_Constants STM32F7508_DISCOVERY_EEPROM Exported Constants
+ * @{
+ */
+/* EEPROM hardware address and page size */
+#define EEPROM_PAGESIZE ((uint8_t)4)
+#define EEPROM_MAX_SIZE ((uint16_t)0x2000) /* 64Kbit */
+
+
+/* Maximum number of trials for EEPROM_WaitEepromStandbyState() function */
+#define EEPROM_MAX_TRIALS ((uint32_t)3000)
+
+#define EEPROM_OK ((uint32_t)0)
+#define EEPROM_FAIL ((uint32_t)1)
+#define EEPROM_TIMEOUT ((uint32_t)2)
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_EEPROM_Exported_Macros STM32F7508_DISCOVERY_EEPROM Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY_EEPROM_Exported_Functions
+ * @{
+ */
+uint32_t BSP_EEPROM_Init(void);
+uint8_t BSP_EEPROM_DeInit(void);
+uint32_t BSP_EEPROM_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead);
+uint32_t BSP_EEPROM_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite);
+uint32_t BSP_EEPROM_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite);
+uint32_t BSP_EEPROM_WaitEepromStandbyState(void);
+
+/* USER Callbacks: This function is declared as __weak in EEPROM driver and
+ should be implemented into user application.
+ BSP_EEPROM_TIMEOUT_UserCallback() function is called whenever a timeout condition
+ occurs during communication (waiting on an event that doesn't occur, bus
+ errors, busy devices ...). */
+void BSP_EEPROM_TIMEOUT_UserCallback(void);
+
+/* Link function for I2C EEPROM peripheral */
+void EEPROM_IO_Init(void);
+HAL_StatusTypeDef EEPROM_IO_WriteData(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef EEPROM_IO_ReadData(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef EEPROM_IO_IsDeviceReady(uint16_t DevAddress, uint32_t Trials);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F7508_DISCOVERY_EEPROM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_lcd.c b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_lcd.c
new file mode 100644
index 00000000..d2b3a1bd
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_lcd.c
@@ -0,0 +1,1647 @@
+/**
+ ******************************************************************************
+ * @file stm32f7508_discovery_lcd.c
+ * @author MCD Application Team
+ * @brief This file includes the driver for Liquid Crystal Display (LCD) module
+ * mounted on STM32F7508-Discovery board.
+ @verbatim
+ 1. How To use this driver:
+ --------------------------
+ - This driver is used to drive directly an LCD TFT using the LTDC controller.
+ - This driver uses timing and setting for RK043FN48H LCD.
+
+ 2. Driver description:
+ ---------------------
+ + Initialization steps:
+ o Initialize the LCD using the BSP_LCD_Init() function.
+ o Apply the Layer configuration using the BSP_LCD_LayerDefaultInit() function.
+ o Select the LCD layer to be used using the BSP_LCD_SelectLayer() function.
+ o Enable the LCD display using the BSP_LCD_DisplayOn() function.
+
+ + Options
+ o Configure and enable the color keying functionality using the
+ BSP_LCD_SetColorKeying() function.
+ o Modify in the fly the transparency and/or the frame buffer address
+ using the following functions:
+ - BSP_LCD_SetTransparency()
+ - BSP_LCD_SetLayerAddress()
+
+ + Display on LCD
+ o Clear the hole LCD using BSP_LCD_Clear() function or only one specified string
+ line using the BSP_LCD_ClearStringLine() function.
+ o Display a character on the specified line and column using the BSP_LCD_DisplayChar()
+ function or a complete string line using the BSP_LCD_DisplayStringAtLine() function.
+ o Display a string line on the specified position (x,y in pixel) and align mode
+ using the BSP_LCD_DisplayStringAtLine() function.
+ o Draw and fill a basic shapes (dot, line, rectangle, circle, ellipse, .. bitmap)
+ on LCD using the available set of functions.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY
+ * @{
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F7508_DISCOVERY_QSPI_H
+#define __STM32F7508_DISCOVERY_QSPI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+#include "../Components/n25q128a/n25q128a.h"
+
+/** @addtogroup STM32F7508_DISCOVERY_QSPI
+ * @{
+ */
+
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup STM32F7508_DISCOVERY_QSPI_Exported_Constants STM32F7508_DISCOVERY_QSPI Exported Constants
+ * @{
+ */
+/* QSPI Error codes */
+#define QSPI_OK ((uint8_t)0x00)
+#define QSPI_ERROR ((uint8_t)0x01)
+#define QSPI_BUSY ((uint8_t)0x02)
+#define QSPI_NOT_SUPPORTED ((uint8_t)0x04)
+#define QSPI_SUSPENDED ((uint8_t)0x08)
+
+
+/* Definition for QSPI clock resources */
+#define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE()
+#define QSPI_CLK_DISABLE() __HAL_RCC_QSPI_CLK_DISABLE()
+#define QSPI_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define QSPI_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define QSPI_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
+#define QSPI_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
+#define QSPI_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
+#define QSPI_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
+
+#define QSPI_FORCE_RESET() __HAL_RCC_QSPI_FORCE_RESET()
+#define QSPI_RELEASE_RESET() __HAL_RCC_QSPI_RELEASE_RESET()
+
+/* Definition for QSPI Pins */
+#define QSPI_CS_PIN GPIO_PIN_6
+#define QSPI_CS_GPIO_PORT GPIOB
+#define QSPI_CLK_PIN GPIO_PIN_2
+#define QSPI_CLK_GPIO_PORT GPIOB
+#define QSPI_D0_PIN GPIO_PIN_11
+#define QSPI_D0_GPIO_PORT GPIOD
+#define QSPI_D1_PIN GPIO_PIN_12
+#define QSPI_D1_GPIO_PORT GPIOD
+#define QSPI_D2_PIN GPIO_PIN_2
+#define QSPI_D2_GPIO_PORT GPIOE
+#define QSPI_D3_PIN GPIO_PIN_13
+#define QSPI_D3_GPIO_PORT GPIOD
+
+/* N25Q128A13EF840E Micron memory */
+/* Size of the flash */
+#define QSPI_FLASH_SIZE 23 /* Address bus width to access whole memory space */
+#define QSPI_PAGE_SIZE 256
+
+/* This alias is added as the name of Memory mapped fucntion changed */
+#define BSP_QSPI_MemoryMappedMode BSP_QSPI_EnableMemoryMappedMode
+/**
+ * @}
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup STM32F7508_DISCOVERY_QSPI_Exported_Types STM32F7508_DISCOVERY_QSPI Exported Types
+ * @{
+ */
+/* QSPI Info */
+typedef struct {
+ uint32_t FlashSize; /*!< Size of the flash */
+ uint32_t EraseSectorSize; /*!< Size of sectors for the erase operation */
+ uint32_t EraseSectorsNumber; /*!< Number of sectors for the erase operation */
+ uint32_t ProgPageSize; /*!< Size of pages for the program operation */
+ uint32_t ProgPagesNumber; /*!< Number of pages for the program operation */
+} QSPI_Info;
+
+/**
+ * @}
+ */
+
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup STM32F7508_DISCOVERY_QSPI_Exported_Functions
+ * @{
+ */
+uint8_t BSP_QSPI_Init (void);
+uint8_t BSP_QSPI_DeInit (void);
+uint8_t BSP_QSPI_Read (uint8_t* pData, uint32_t ReadAddr, uint32_t Size);
+uint8_t BSP_QSPI_Write (uint8_t* pData, uint32_t WriteAddr, uint32_t Size);
+uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress);
+uint8_t BSP_QSPI_Erase_Chip (void);
+uint8_t BSP_QSPI_GetStatus (void);
+uint8_t BSP_QSPI_GetInfo (QSPI_Info* pInfo);
+uint8_t BSP_QSPI_EnableMemoryMappedMode(void);
+
+/* These functions can be modified in case the current settings
+ need to be changed for specific application needs */
+void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params);
+void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F7508_DISCOVERY_QSPI_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_sd.c b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_sd.c
new file mode 100644
index 00000000..06fa040b
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_sd.c
@@ -0,0 +1,590 @@
+/**
+ ******************************************************************************
+ * @file stm32f7508_discovery_sd.c
+ * @author MCD Application Team
+ * @brief This file includes the uSD card driver mounted on STM32F7508-Discovery
+ * board.
+ @verbatim
+ 1. How To use this driver:
+ --------------------------
+ - This driver is used to drive the micro SD external card mounted on STM32F7508-Discovery
+ board.
+ - This driver does not need a specific component driver for the micro SD device
+ to be included with.
+
+ 2. Driver description:
+ ---------------------
+ + Initialization steps:
+ o Initialize the micro SD card using the BSP_SD_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ SDIO interface configuration to interface with the external micro SD. It
+ also includes the micro SD initialization sequence.
+ o To check the SD card presence you can use the function BSP_SD_IsDetected() which
+ returns the detection status
+ o If SD presence detection interrupt mode is desired, you must configure the
+ SD detection interrupt mode by calling the function BSP_SD_ITConfig(). The interrupt
+ is generated as an external interrupt whenever the micro SD card is
+ plugged/unplugged in/from the board.
+ o The function BSP_SD_GetCardInfo() is used to get the micro SD card information
+ which is stored in the structure "HAL_SD_CardInfoTypedef".
+
+ + Micro SD card operations
+ o The micro SD card can be accessed with read/write block(s) operations once
+ it is ready for access. The access can be performed whether using the polling
+ mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks(), or by DMA
+ transfer using the functions BSP_SD_ReadBlocks_DMA()/BSP_SD_WriteBlocks_DMA()
+ o The DMA transfer complete is used with interrupt mode. Once the SD transfer
+ is complete, the SD interrupt is handled using the function BSP_SD_IRQHandler(),
+ the DMA Tx/Rx transfer complete are handled using the functions
+ BSP_SD_DMA_Tx_IRQHandler()/BSP_SD_DMA_Rx_IRQHandler(). The corresponding user callbacks
+ are implemented by the user at application level.
+ o The SD erase block(s) is performed using the function BSP_SD_Erase() with specifying
+ the number of blocks to erase.
+ o The SD runtime status is returned when calling the function BSP_SD_GetCardState().
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F7508_DISCOVERY_SD_H
+#define __STM32F7508_DISCOVERY_SD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7508_discovery.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY_SD
+ * @{
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_SD_Exported_Types STM32F7508_DISCOVERY_SD Exported Types
+ * @{
+ */
+
+/**
+ * @brief SD Card information structure
+ */
+#define BSP_SD_CardInfo HAL_SD_CardInfoTypeDef
+/**
+ * @}
+ */
+
+/**
+ * @brief SD status structure definition
+ */
+#define MSD_OK ((uint8_t)0x00)
+#define MSD_ERROR ((uint8_t)0x01)
+#define MSD_ERROR_SD_NOT_PRESENT ((uint8_t)0x02)
+
+/**
+ * @brief SD transfer state definition
+ */
+#define SD_TRANSFER_OK ((uint8_t)0x00)
+#define SD_TRANSFER_BUSY ((uint8_t)0x01)
+
+/** @defgroup STM32F7508_DISCOVERY_SD_Exported_Constants STM32F7508_DISCOVERY_SD Exported Constants
+ * @{
+ */
+#define SD_PRESENT ((uint8_t)0x01)
+#define SD_NOT_PRESENT ((uint8_t)0x00)
+
+#define SD_DATATIMEOUT ((uint32_t)100000000)
+
+/* DMA definitions for SD DMA transfer */
+#define __DMAx_TxRx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
+#define SD_DMAx_Tx_CHANNEL DMA_CHANNEL_4
+#define SD_DMAx_Rx_CHANNEL DMA_CHANNEL_4
+#define SD_DMAx_Tx_STREAM DMA2_Stream6
+#define SD_DMAx_Rx_STREAM DMA2_Stream3
+#define SD_DMAx_Tx_IRQn DMA2_Stream6_IRQn
+#define SD_DMAx_Rx_IRQn DMA2_Stream3_IRQn
+#define BSP_SDMMC_IRQHandler SDMMC1_IRQHandler
+#define BSP_SDMMC_DMA_Tx_IRQHandler DMA2_Stream6_IRQHandler
+#define BSP_SDMMC_DMA_Rx_IRQHandler DMA2_Stream3_IRQHandler
+#define SD_DetectIRQHandler() HAL_GPIO_EXTI_IRQHandler(SD_DETECT_PIN)
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_SD_Exported_Macro STM32F7508_DISCOVERY_SD Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY_SD_Exported_Functions
+ * @{
+ */
+uint8_t BSP_SD_Init(void);
+uint8_t BSP_SD_DeInit(void);
+uint8_t BSP_SD_ITConfig(void);
+uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout);
+uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout);
+uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks);
+uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks);
+uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr);
+uint8_t BSP_SD_GetCardState(void);
+void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypeDef *CardInfo);
+uint8_t BSP_SD_IsDetected(void);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params);
+void BSP_SD_Detect_MspInit(SD_HandleTypeDef *hsd, void *Params);
+void BSP_SD_MspDeInit(SD_HandleTypeDef *hsd, void *Params);
+void BSP_SD_AbortCallback(void);
+void BSP_SD_WriteCpltCallback(void);
+void BSP_SD_ReadCpltCallback(void);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F7508_DISCOVERY_SD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_sdram.c b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_sdram.c
new file mode 100644
index 00000000..abd6b368
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_sdram.c
@@ -0,0 +1,481 @@
+/**
+ ******************************************************************************
+ * @file stm32f7508_discovery_sdram.c
+ * @author MCD Application Team
+ * @brief This file includes the SDRAM driver for the MT48LC4M32B2B5-7 memory
+ * device mounted on STM32F7508-Discovery board.
+ @verbatim
+ 1. How To use this driver:
+ --------------------------
+ - This driver is used to drive the MT48LC4M32B2B5-7 SDRAM external memory mounted
+ on STM32F7508-Discovery board.
+ - This driver does not need a specific component driver for the SDRAM device
+ to be included with.
+
+ 2. Driver description:
+ ---------------------
+ + Initialization steps:
+ o Initialize the SDRAM external memory using the BSP_SDRAM_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ FMC controller configuration to interface with the external SDRAM memory.
+ o It contains the SDRAM initialization sequence to program the SDRAM external
+ device using the function BSP_SDRAM_Initialization_sequence(). Note that this
+ sequence is standard for all SDRAM devices, but can include some differences
+ from a device to another. If it is the case, the right sequence should be
+ implemented separately.
+
+ + SDRAM read/write operations
+ o SDRAM external memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_SDRAM_ReadData()/BSP_SDRAM_WriteData(), or by DMA transfer using the functions
+ BSP_SDRAM_ReadData_DMA()/BSP_SDRAM_WriteData_DMA().
+ o The AHB access is performed with 32-bit width transaction, the DMA transfer
+ configuration is fixed at single (no burst) word transfer (see the
+ SDRAM_MspInit() static function).
+ o User can implement his own functions for read/write access with his desired
+ configurations.
+ o If interrupt mode is used for DMA transfer, the function BSP_SDRAM_DMA_IRQHandler()
+ is called in IRQ handler file, to serve the generated interrupt once the DMA
+ transfer is complete.
+ o You can send a command to the SDRAM device in runtime using the function
+ BSP_SDRAM_Sendcmd(), and giving the desired command as parameter chosen between
+ the predefined commands of the "FMC_SDRAM_CommandTypeDef" structure.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F7508_DISCOVERY_SDRAM_H
+#define __STM32F7508_DISCOVERY_SDRAM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY_SDRAM
+ * @{
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_SDRAM_Exported_Types STM32F7508_DISCOVERY_SDRAM Exported Types
+ * @{
+ */
+
+/**
+ * @brief SDRAM status structure definition
+ */
+#define SDRAM_OK ((uint8_t)0x00)
+#define SDRAM_ERROR ((uint8_t)0x01)
+
+/** @defgroup STM32F7508_DISCOVERY_SDRAM_Exported_Constants STM32F7508_DISCOVERY_SDRAM Exported Constants
+ * @{
+ */
+#define SDRAM_DEVICE_ADDR ((uint32_t)0xC0000000)
+#define SDRAM_DEVICE_SIZE ((uint32_t)0x800000) /* SDRAM device size in MBytes */
+
+/* #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_8 */
+#define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16
+
+#define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_2
+/* #define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_3 */
+
+#define REFRESH_COUNT ((uint32_t)0x0603) /* SDRAM refresh counter (100Mhz SD clock) */
+
+#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
+
+/* DMA definitions for SDRAM DMA transfer */
+#define __DMAx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
+#define __DMAx_CLK_DISABLE __HAL_RCC_DMA2_CLK_DISABLE
+#define SDRAM_DMAx_CHANNEL DMA_CHANNEL_0
+#define SDRAM_DMAx_STREAM DMA2_Stream0
+#define SDRAM_DMAx_IRQn DMA2_Stream0_IRQn
+#define BSP_SDRAM_DMA_IRQHandler DMA2_Stream0_IRQHandler
+/**
+ * @}
+ */
+
+/**
+ * @brief FMC SDRAM Mode definition register defines
+ */
+#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
+#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
+#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
+#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
+#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
+#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
+#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
+#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
+#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
+#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
+#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
+/**
+ * @}
+ */
+
+/** @defgroup STM32F7508_DISCOVERY_SDRAM_Exported_Macro STM32F7508_DISCOVERY_SDRAM Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F7508_DISCOVERY_SDRAM_Exported_Functions
+ * @{
+ */
+uint8_t BSP_SDRAM_Init(void);
+uint8_t BSP_SDRAM_DeInit(void);
+void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount);
+uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram, void *Params);
+void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram, void *Params);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F7508_DISCOVERY_SDRAM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_ts.c b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_ts.c
new file mode 100644
index 00000000..127e5411
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F7508-Discovery/stm32f7508_discovery_ts.c
@@ -0,0 +1,434 @@
+/**
+ ******************************************************************************
+ * @file stm32f7508_discovery_ts.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the Touch
+ * Screen on STM32F7508-Discovery board.
+ @verbatim
+ 1. How To use this driver:
+ --------------------------
+ - This driver is used to drive the touch screen module of the STM32F7508-Discovery
+ board on the RK043FN48H-CT672B 480x272 LCD screen with capacitive touch screen.
+ - The FT5336 component driver must be included in project files according to
+ the touch screen driver present on this board.
+
+ 2. Driver description:
+ ---------------------
+ + Initialization steps:
+ o Initialize the TS module using the BSP_TS_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ communication layer configuration to start the TS use. The LCD size properties
+ (x and y) are passed as parameters.
+ o If TS interrupt mode is desired, you must configure the TS interrupt mode
+ by calling the function BSP_TS_ITConfig(). The TS interrupt mode is generated
+ as an external interrupt whenever a touch is detected.
+ The interrupt mode internally uses the IO functionalities driver driven by
+ the IO expander, to configure the IT line.
+
+ + Touch screen use
+ o The touch screen state is captured whenever the function BSP_TS_GetState() is
+ used. This function returns information about the last LCD touch occurred
+ in the TS_StateTypeDef structure.
+ o If TS interrupt mode is used, the function BSP_TS_ITGetStatus() is needed to get
+ the interrupt status. To clear the IT pending bits, you should call the
+ function BSP_TS_ITClear().
+ o The IT is handled using the corresponding external interrupt IRQ handler,
+ the user IT callback treatment is implemented on the same external interrupt
+ callback.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
Release
+Notes for STM32F769I-Discovery BSP Drivers
+
Copyright
+2016 STMicroelectronics
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The BSP (Board Specific
+Package) drivers are parts of the STM32Cube package based on the HAL
+drivers and provide a set of high level APIs relative to the hardware
+components and features in the evaluation boards, discovery kits and nucleo
+boards coming with the STM32Cube package for a given STM32 serie.
+
The BSP drivers allow a quick access to the boards’
+services using high level APIs and without any specific configuration as the
+link with the HAL and the external components is done in intrinsic within the drivers.
+
+
From project settings points of view, user has only
+to add the necessary driver’s files in the workspace and call the needed
+functions from examples. However some low level
+configuration functions are weak and can be overridden by the applications if user
+wants to change some BSP drivers default behavior.
First official release
+ of the STM32F769I-Discovery BSP drivers
Dependencies
+
+
+
+
+
+
+
STM32F7xx_HAL_Driver V1.2.0
+
BSP Common V4.0.1
License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery.c
new file mode 100644
index 00000000..34c8314e
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery.c
@@ -0,0 +1,818 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_discovery.c
+ * @author MCD Application Team
+ * @brief This file provides a set of firmware functions to manage LEDs,
+ * push-buttons, external SDRAM, external QSPI Flash, RF EEPROM,
+ * available on STM32F769I-Discovery board (MB1225) from
+ * STMicroelectronics.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_DISCOVERY_H
+#define __STM32F769I_DISCOVERY_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+ /* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_LOW_LEVEL STM32F769I-Discovery LOW LEVEL
+ * @{
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_LOW_LEVEL_Exported_Types STM32F769I Discovery Low Level Exported Types
+ * @{
+ */
+
+/**
+ * @brief Define for STM32F769I_DISCOVERY board
+ */
+#if !defined (USE_STM32F769I_DISCO)
+ #define USE_STM32F769I_DISCO
+#endif
+
+/** @brief Led_TypeDef
+ * STM32F769I_DISCOVERY board leds definitions.
+ */
+typedef enum
+{
+ LED1 = 0,
+ LED_RED = LED1,
+ LED2 = 1,
+ LED_GREEN = LED2
+} Led_TypeDef;
+
+/** @brief Button_TypeDef
+ * STM32F769I_DISCOVERY board Buttons definitions.
+ */
+typedef enum
+{
+ BUTTON_WAKEUP = 0,
+} Button_TypeDef;
+
+#define BUTTON_USER BUTTON_WAKEUP
+
+/** @brief ButtonMode_TypeDef
+ * STM32F769I_DISCOVERY board Buttons Modes definitions.
+ */
+typedef enum
+{
+ BUTTON_MODE_GPIO = 0,
+ BUTTON_MODE_EXTI = 1
+
+} ButtonMode_TypeDef;
+
+/** @addtogroup Exported_types
+ * @{
+ */
+typedef enum
+{
+ PB_SET = 0,
+ PB_RESET = !PB_SET
+} ButtonValue_TypeDef;
+
+
+/** @brief DISCO_Status_TypeDef
+ * STM32F769I_DISCO board Status return possible values.
+ */
+typedef enum
+{
+ DISCO_OK = 0,
+ DISCO_ERROR = 1
+
+} DISCO_Status_TypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_LOW_LEVEL_Exported_Constants STM32F769I Discovery Low Level Exported Constants
+ * @{
+ */
+
+
+/** @addtogroup STM32F769I_DISCOVERY_LOW_LEVEL_LED STM32F769I Discovery Low Level Led
+ * @{
+ */
+/* Always four leds for all revisions of Discovery boards */
+#define LEDn ((uint8_t)2)
+
+
+/* 2 Leds are connected to MCU directly on PJ13 and PJ5 */
+#define LED1_GPIO_PORT ((GPIO_TypeDef*)GPIOJ)
+#define LED2_GPIO_PORT ((GPIO_TypeDef*)GPIOJ)
+
+#define LEDx_GPIO_CLK_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE()
+#define LEDx_GPIO_CLK_DISABLE() __HAL_RCC_GPIOJ_CLK_DISABLE()
+
+#define LED1_PIN ((uint32_t)GPIO_PIN_13)
+#define LED2_PIN ((uint32_t)GPIO_PIN_5)
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY_LOW_LEVEL_BUTTON STM32F769I Discovery Low Level Button
+ * @{
+ */
+/* Only one User/Wakeup button */
+#define BUTTONn ((uint8_t)1)
+
+/**
+ * @brief Wakeup push-button
+ */
+#define WAKEUP_BUTTON_PIN GPIO_PIN_0
+#define WAKEUP_BUTTON_GPIO_PORT GPIOA
+#define WAKEUP_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define WAKEUP_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define WAKEUP_BUTTON_EXTI_IRQn EXTI0_IRQn
+
+/* Define the USER button as an alias of the Wakeup button */
+#define USER_BUTTON_PIN WAKEUP_BUTTON_PIN
+#define USER_BUTTON_GPIO_PORT WAKEUP_BUTTON_GPIO_PORT
+#define USER_BUTTON_GPIO_CLK_ENABLE() WAKEUP_BUTTON_GPIO_CLK_ENABLE()
+#define USER_BUTTON_GPIO_CLK_DISABLE() WAKEUP_BUTTON_GPIO_CLK_DISABLE()
+#define USER_BUTTON_EXTI_IRQn WAKEUP_BUTTON_EXTI_IRQn
+
+#define BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+
+/**
+ * @}
+ */
+
+/**
+ * @brief USB OTG HS Over Current signal
+ */
+#define OTG_HS_OVER_CURRENT_PIN GPIO_PIN_4
+#define OTG_HS_OVER_CURRENT_PORT GPIOD
+#define OTG_HS_OVER_CURRENT_PORT_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
+
+/**
+ * @brief SD-detect signal
+ */
+#define SD_DETECT_PIN ((uint32_t)GPIO_PIN_15)
+#define SD_DETECT_GPIO_PORT ((GPIO_TypeDef*)GPIOI)
+#define SD_DETECT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define SD_DETECT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define SD_DETECT_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @brief Touch screen interrupt signal
+ */
+#define TS_INT_PIN ((uint32_t)GPIO_PIN_13)
+#define TS_INT_GPIO_PORT ((GPIO_TypeDef*)GPIOI)
+#define TS_INT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define TS_INT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define TS_INT_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @brief TouchScreen FT6206 Slave I2C address 1
+ */
+#define TS_I2C_ADDRESS ((uint16_t)0x54)
+
+/**
+ * @brief TouchScreen FT6336G Slave I2C address 2
+ */
+#define TS_I2C_ADDRESS_A02 ((uint16_t)0x70)
+
+/**
+ * @brief LCD DSI Slave I2C address 1
+ */
+#define LCD_DSI_ADDRESS TS_I2C_ADDRESS
+
+/**
+ * @brief LCD DSI Slave I2C address 2
+ */
+#define LCD_DSI_ADDRESS_A02 TS_I2C_ADDRESS_A02
+
+/**
+ * @brief Audio I2C Slave address
+ */
+#define AUDIO_I2C_ADDRESS ((uint16_t)0x34)
+
+/**
+ * @brief EEPROM I2C Slave address 1
+ */
+#define EEPROM_I2C_ADDRESS_A01 ((uint16_t)0xA0)
+
+/**
+ * @brief EEPROM I2C Slave address 2
+ */
+#define EEPROM_I2C_ADDRESS_A02 ((uint16_t)0xA6)
+
+/**
+ * @brief User can use this section to tailor I2C4/I2C4 instance used and associated
+ * resources (audio codec).
+ * Definition for I2C4 clock resources
+ */
+#define DISCOVERY_AUDIO_I2Cx I2C4
+#define DISCOVERY_AUDIO_I2Cx_CLK_ENABLE() __HAL_RCC_I2C4_CLK_ENABLE()
+#define DISCOVERY_AUDIO_I2Cx_SCL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
+#define DISCOVERY_AUDIO_I2Cx_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+
+#define DISCOVERY_AUDIO_I2Cx_FORCE_RESET() __HAL_RCC_I2C4_FORCE_RESET()
+#define DISCOVERY_AUDIO_I2Cx_RELEASE_RESET() __HAL_RCC_I2C4_RELEASE_RESET()
+
+/** @brief Definition for I2C4 Pins
+ */
+#define DISCOVERY_AUDIO_I2Cx_SCL_PIN GPIO_PIN_12 /*!< PD12 */
+#define DISCOVERY_AUDIO_I2Cx_SCL_AF GPIO_AF4_I2C4
+#define DISCOVERY_AUDIO_I2Cx_SCL_GPIO_PORT GPIOD
+#define DISCOVERY_AUDIO_I2Cx_SDA_PIN GPIO_PIN_7 /*!< PB7 */
+#define DISCOVERY_AUDIO_I2Cx_SDA_AF GPIO_AF11_I2C4
+#define DISCOVERY_AUDIO_I2Cx_SDA_GPIO_PORT GPIOB
+/** @brief Definition of I2C4 interrupt requests
+ */
+#define DISCOVERY_AUDIO_I2Cx_EV_IRQn I2C4_EV_IRQn
+#define DISCOVERY_AUDIO_I2Cx_ER_IRQn I2C4_ER_IRQn
+
+/**
+ * @brief User can use this section to tailor I2C1/I2C1 instance used and associated
+ * resources.
+ * Definition for I2C1 clock resources
+ */
+#define DISCOVERY_EXT_I2Cx I2C1
+#define DISCOVERY_EXT_I2Cx_CLK_ENABLE() __HAL_RCC_I2C1_CLK_ENABLE()
+#define DISCOVERY_DMAx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
+#define DISCOVERY_EXT_I2Cx_SCL_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+
+#define DISCOVERY_EXT_I2Cx_FORCE_RESET() __HAL_RCC_I2C1_FORCE_RESET()
+#define DISCOVERY_EXT_I2Cx_RELEASE_RESET() __HAL_RCC_I2C1_RELEASE_RESET()
+
+/** @brief Definition for I2C1 Pins
+ */
+#define DISCOVERY_EXT_I2Cx_SCL_PIN GPIO_PIN_8 /*!< PB8 */
+#define DISCOVERY_EXT_I2Cx_SCL_SDA_GPIO_PORT GPIOB
+#define DISCOVERY_EXT_I2Cx_SCL_SDA_AF GPIO_AF4_I2C1
+#define DISCOVERY_EXT_I2Cx_SDA_PIN GPIO_PIN_9 /*!< PB9 */
+
+/** @brief Definition of I2C interrupt requests
+ */
+#define DISCOVERY_EXT_I2Cx_EV_IRQn I2C1_EV_IRQn
+#define DISCOVERY_EXT_I2Cx_ER_IRQn I2C1_ER_IRQn
+
+/* I2C TIMING Register define when I2C clock source is SYSCLK */
+/* I2C TIMING is calculated from APB1 source clock = 50 MHz */
+/* Due to the big MOFSET capacity for adapting the camera level the rising time is very large (>1us) */
+/* 0x40912732 takes in account the big rising and aims a clock of 100khz */
+#ifndef DISCOVERY_I2Cx_TIMING
+#define DISCOVERY_I2Cx_TIMING ((uint32_t)0x40912732)
+#endif /* DISCOVERY_I2Cx_TIMING */
+
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_LOW_LEVEL_Exported_Macros STM32F769I Discovery Low Level Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_LOW_LEVEL_Exported_Functions STM32F769I Discovery Low Level Exported Functions
+ * @{
+ */
+uint32_t BSP_GetVersion(void);
+void BSP_LED_Init(Led_TypeDef Led);
+void BSP_LED_DeInit(Led_TypeDef Led);
+void BSP_LED_On(Led_TypeDef Led);
+void BSP_LED_Off(Led_TypeDef Led);
+void BSP_LED_Toggle(Led_TypeDef Led);
+void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef Button_Mode);
+void BSP_PB_DeInit(Button_TypeDef Button);
+uint32_t BSP_PB_GetState(Button_TypeDef Button);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_DISCOVERY_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_audio.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_audio.c
new file mode 100644
index 00000000..a4f711e0
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_audio.c
@@ -0,0 +1,2212 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_discovery_audio.c
+ * @author MCD Application Team
+ * @brief This file provides the Audio driver for the STM32F769I-DISCOVERY
+ * board.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ + This driver supports STM32F7xx devices on STM32F769I-DISCOVERY (MB1225) Evaluation boards.
+ + Call the function BSP_AUDIO_OUT_Init(
+ OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER,
+ OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
+ Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
+ AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...)
+ this parameter is relative to the audio file/stream type.
+ )
+ This function configures all the hardware required for the audio application (codec, I2C, SAI,
+ GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
+ If the returned value is different from AUDIO_OK or the function is stuck then the communication with
+ the codec has failed (try to un-plug the power or reset device in this case).
+ - OUTPUT_DEVICE_SPEAKER : only speaker will be set as output for the audio stream.
+ - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
+ - OUTPUT_DEVICE_BOTH : both Speaker and Headphone are used as outputs for the audio stream
+ at the same time.
+ Note. On STM32F769I-DISCOVERY SAI_DMA is configured in CIRCULAR mode. Due to this the application
+ does NOT need to call BSP_AUDIO_OUT_ChangeBuffer() to assure streaming.
+ + Call the function BSP_AUDIO_OUT_Play(
+ pBuffer: pointer to the audio data file address
+ Size : size of the buffer to be sent in Bytes
+ )
+ to start playing (for the first time) from the audio file/stream.
+ + Call the function BSP_AUDIO_OUT_Pause() to pause playing
+ + Call the function BSP_AUDIO_OUT_Resume() to resume playing.
+ Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
+ for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
+ Note. This function should be called only when the audio file is played or paused (not stopped).
+ + For each mode, you may need to implement the relative callback functions into your code.
+ The Callback functions are named BSP_AUDIO_OUT_XXX_CallBack() and only their prototypes are declared in
+ the stm32f769i_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
+ + To Stop playing, to modify the volume level, the frequency, the audio frame slot,
+ the device output mode the mute or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(),
+ AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetAudioFrameSlot(), BSP_AUDIO_OUT_SetOutputMode(),
+ BSP_AUDIO_OUT_SetMute() and BSP_AUDIO_OUT_Stop().
+
+ + Call the function BSP_AUDIO_IN_Init(
+ AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000...)
+ this parameter is relative to the audio file/stream type.
+ BitRes: Bit resolution fixed to 16bit
+ ChnlNbr: Number of channel to be configured for the DFSDM peripheral
+ )
+ This function configures all the hardware required for the audio in application (DFSDM filters and channels,
+ Clock source for DFSDM periphiral, GPIOs, DMA and interrupt if needed).
+ This function returns AUDIO_OK if configuration is OK.If the returned value is different from AUDIO_OK then
+ the configuration should be wrong.
+ Note: On STM32F769I-DISCOVERY, four DFSDM Channel/Filters are configured and their DMA streams are configured
+ in CIRCULAR mode.
+ + Call the function BSP_AUDIO_IN_AllocScratch(
+ pScratch: pointer to scratch tables
+ size: size of scratch buffer)
+ This function must be called before BSP_AUDIO_IN_RECORD() to allocate buffer scratch for each DFSDM channel
+ and its size.
+ Note: These buffers scratch are used as intermidiate buffers to collect data within final record buffer.
+ size is the total size of the four buffers scratch; If size is 512 then the size of each is 128.
+ This function must be called after BSP_AUDIO_IN_Init()
+ + Call the function BSP_AUDIO_IN_RECORD(
+ pBuf: pointer to the recorded audio data file address
+ Size: size of the buffer to be written in Bytes
+ )
+ to start recording from microphones.
+
+ + Call the function BSP_AUDIO_IN_Pause() to pause recording
+ + Call the function BSP_AUDIO_IN_Resume() to recording playing.
+ Note. After calling BSP_AUDIO_IN_Pause() function for pause, only BSP_AUDIO_IN_Resume() should be called
+ for resume (it is not allowed to call BSP_AUDIO_IN_RECORD() in this case).
+ + Call the function BSP_AUDIO_IN_Stop() to stop recording
+ + For each mode, you may need to implement the relative callback functions into your code.
+ The Callback functions are named BSP_AUDIO_IN_XXX_CallBack() and only their prototypes are declared in
+ the stm32f769i_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
+
+ Driver architecture:
+ --------------------
+ + This driver provides the High Audio Layer: consists of the function API exported in the stm32f769i_discovery_audio.h file
+ (BSP_AUDIO_OUT_Init(), BSP_AUDIO_OUT_Play() ...)
+ + This driver provide also the Media Access Layer (MAL): which consists of functions allowing to access the media containing/
+ providing the audio file/stream. These functions are also included as local functions into
+ the stm32f769i_discovery_audio.c file (DFSDMx_Init(), DFSDMx_DeInit(), SAIx_Init() and SAIx_DeInit())
+
+ Known Limitations:
+ ------------------
+ 1- If the TDM Format used to play in parallel 2 audio Stream (the first Stream is configured in codec SLOT0 and second
+ Stream in SLOT1) the Pause/Resume, volume and mute feature will control the both streams.
+ 2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size,
+ File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
+ 3- Supports only Stereo audio streaming.
+ 4- Supports only 16-bits audio data size.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_DISCOVERY_AUDIO_H
+#define __STM32F769I_DISCOVERY_AUDIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include audio component Driver */
+#include "../Components/wm8994/wm8994.h"
+#include "stm32f769i_discovery.h"
+#include
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_AUDIO STM32F769I_DISCOVERY_AUDIO
+ * @{
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_AUDIO_Exported_Types STM32F769I_DISCOVERY_AUDIO Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_AUDIO_Exported_Constants STM32F769I_DISCOVERY_AUDIO Exported Constants
+ * @{
+ */
+
+/** @defgroup BSP_Audio_Sample_Rate BSP Audio Sample Rate
+ * @{
+ */
+#define BSP_AUDIO_FREQUENCY_96K SAI_AUDIO_FREQUENCY_96K
+#define BSP_AUDIO_FREQUENCY_48K SAI_AUDIO_FREQUENCY_48K
+#define BSP_AUDIO_FREQUENCY_44K SAI_AUDIO_FREQUENCY_44K
+#define BSP_AUDIO_FREQUENCY_32K SAI_AUDIO_FREQUENCY_32K
+#define BSP_AUDIO_FREQUENCY_22K SAI_AUDIO_FREQUENCY_22K
+#define BSP_AUDIO_FREQUENCY_16K SAI_AUDIO_FREQUENCY_16K
+#define BSP_AUDIO_FREQUENCY_11K SAI_AUDIO_FREQUENCY_11K
+#define BSP_AUDIO_FREQUENCY_8K SAI_AUDIO_FREQUENCY_8K
+/**
+ * @}
+ */
+
+/*------------------------------------------------------------------------------
+ USER SAI defines parameters
+ -----------------------------------------------------------------------------*/
+/** CODEC_AudioFrame_SLOT_TDMMode In W8994 codec the Audio frame contains 4 slots : TDM Mode
+ * TDM format :
+ * +------------------|------------------|--------------------|-------------------+
+ * | CODEC_SLOT0 Left | CODEC_SLOT1 Left | CODEC_SLOT0 Right | CODEC_SLOT1 Right |
+ * +------------------------------------------------------------------------------+
+ */
+/* To have 2 separate audio stream in Both headphone and speaker the 4 slot must be activated */
+#define CODEC_AUDIOFRAME_SLOT_0123 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_2 | SAI_SLOTACTIVE_3
+
+/* To have an audio stream in headphone only SAI Slot 0 and Slot 2 must be activated */
+#define CODEC_AUDIOFRAME_SLOT_02 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_2
+/* To have an audio stream in speaker only SAI Slot 1 and Slot 3 must be activated */
+#define CODEC_AUDIOFRAME_SLOT_13 SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_3
+
+
+/* SAI peripheral configuration defines */
+#define AUDIO_OUT_SAIx SAI1_Block_A
+#define AUDIO_OUT_SAIx_CLK_ENABLE() __HAL_RCC_SAI1_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_CLK_DISABLE() __HAL_RCC_SAI1_CLK_DISABLE()
+#define AUDIO_OUT_SAIx_AF GPIO_AF6_SAI1
+
+#define AUDIO_OUT_SAIx_MCLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_MCLK_GPIO_PORT GPIOG
+#define AUDIO_OUT_SAIx_MCLK_PIN GPIO_PIN_7
+#define AUDIO_OUT_SAIx_SD_FS_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_SD_FS_SCK_GPIO_PORT GPIOE
+#define AUDIO_OUT_SAIx_FS_PIN GPIO_PIN_4
+#define AUDIO_OUT_SAIx_SCK_PIN GPIO_PIN_5
+#define AUDIO_OUT_SAIx_SD_PIN GPIO_PIN_6
+
+/* SAI DMA Stream definitions */
+#define AUDIO_OUT_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_DMAx_STREAM DMA2_Stream1
+#define AUDIO_OUT_SAIx_DMAx_CHANNEL DMA_CHANNEL_0
+#define AUDIO_OUT_SAIx_DMAx_IRQ DMA2_Stream1_IRQn
+#define AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
+#define AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
+#define DMA_MAX_SZE 0xFFFF
+
+#define AUDIO_OUT_SAIx_DMAx_IRQHandler DMA2_Stream1_IRQHandler
+
+/* Select the interrupt preemption priority and subpriority for the DMA interrupt */
+#define AUDIO_OUT_IRQ_PREPRIO ((uint32_t)0x0E)
+
+/*------------------------------------------------------------------------------
+ AUDIO IN CONFIGURATION
+------------------------------------------------------------------------------*/
+/* SAI peripheral configuration defines */
+#define AUDIO_IN_SAIx SAI1_Block_B
+#define AUDIO_IN_SAIx_CLK_ENABLE() __HAL_RCC_SAI1_CLK_ENABLE()
+#define AUDIO_IN_SAIx_CLK_DISABLE() __HAL_RCC_SAI1_CLK_DISABLE()
+#define AUDIO_IN_SAIx_AF GPIO_AF6_SAI1
+#define AUDIO_IN_SAIx_SD_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
+#define AUDIO_IN_SAIx_SD_GPIO_PORT GPIOE
+#define AUDIO_IN_SAIx_SD_PIN GPIO_PIN_3
+
+/* SAI DMA Stream definitions */
+#define AUDIO_IN_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
+#define AUDIO_IN_SAIx_DMAx_STREAM DMA2_Stream4
+#define AUDIO_IN_SAIx_DMAx_CHANNEL DMA_CHANNEL_1
+#define AUDIO_IN_SAIx_DMAx_IRQ DMA2_Stream4_IRQn
+#define AUDIO_IN_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
+#define AUDIO_IN_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
+
+#define AUDIO_IN_INT_GPIO_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE()
+#define AUDIO_IN_INT_GPIO_PORT GPIOJ
+#define AUDIO_IN_INT_GPIO_PIN GPIO_PIN_12
+#define AUDIO_IN_INT_IRQ EXTI15_10_IRQn
+
+/* DFSDM Configuration defines */
+#define AUDIO_DFSDMx_TOP_RIGHT_CHANNEL DFSDM_CHANNEL_0
+#define AUDIO_DFSDMx_TOP_LEFT_CHANNEL DFSDM_CHANNEL_1
+#define AUDIO_DFSDMx_BUTTOM_RIGHT_CHANNEL DFSDM_CHANNEL_4
+#define AUDIO_DFSDMx_BUTTOM_LEFT_CHANNEL DFSDM_CHANNEL_5
+
+#define AUDIO_DFSDMx_TOP_LEFT_FILTER DFSDM1_Filter0
+#define AUDIO_DFSDMx_TOP_RIGHT_FILTER DFSDM1_Filter1
+#define AUDIO_DFSDMx_BUTTOM_LEFT_FILTER DFSDM1_Filter2
+#define AUDIO_DFSDMx_BUTTOM_RIGHT_FILTER DFSDM1_Filter3
+
+#define AUDIO_DFSDMx_CLK_ENABLE() __HAL_RCC_DFSDM1_CLK_ENABLE()
+#define AUDIO_DFSDMx_CKOUT_PIN GPIO_PIN_3
+#define AUDIO_DFSDMx_CKOUT_DMIC_GPIO_PORT GPIOD
+#define AUDIO_DFSDMx_CKOUT_DMIC_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
+#define AUDIO_DFSDMx_DMIC_DATIN1_PIN GPIO_PIN_3
+#define AUDIO_DFSDMx_DMIC_DATIN5_PIN GPIO_PIN_11
+#define AUDIO_DFSDMx_DMIC_DATIN_GPIO_PORT GPIOC
+#define AUDIO_DFSDMx_DMIC_DATIN_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define AUDIO_DFSDMx_DMIC_DATIN_AF GPIO_AF3_DFSDM1
+#define AUDIO_DFSDMx_CKOUT_AF GPIO_AF3_DFSDM1
+
+/* DFSDM DMA Right and Left channels definitions */
+#define AUDIO_DFSDMx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
+#define AUDIO_DFSDMx_DMAx_CHANNEL DMA_CHANNEL_8
+#define AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_WORD
+#define AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_WORD
+
+#define AUDIO_DFSDMx_DMAx_TOP_LEFT_STREAM DMA2_Stream0
+#define AUDIO_DFSDMx_DMAx_TOP_LEFT_IRQ DMA2_Stream0_IRQn
+#define AUDIO_DFSDMx_DMAx_TOP_LEFT_IRQHandler DMA2_Stream0_IRQHandler
+
+#define AUDIO_DFSDMx_DMAx_TOP_RIGHT_STREAM DMA2_Stream5
+#define AUDIO_DFSDMx_DMAx_TOP_RIGHT_IRQ DMA2_Stream5_IRQn
+#define AUDIO_DFSDMx_DMAx_TOP_RIGHT_IRQHandler DMA2_Stream5_IRQHandler
+
+#define AUDIO_DFSDMx_DMAx_BUTTOM_LEFT_STREAM DMA2_Stream6
+#define AUDIO_DFSDMx_DMAx_BUTTOM_LEFT_IRQ DMA2_Stream6_IRQn
+#define AUDIO_DFSDMx_DMAx_BUTTOM_LEFT_IRQHandler DMA2_Stream6_IRQHandler
+
+#define AUDIO_DFSDMx_DMAx_BUTTOM_RIGHT_STREAM DMA2_Stream7
+#define AUDIO_DFSDMx_DMAx_BUTTOM_RIGHT_IRQ DMA2_Stream7_IRQn
+#define AUDIO_DFSDMx_DMAx_BUTTOM_RIGHT_IRQHandler DMA2_Stream7_IRQHandler
+
+/* Select the interrupt preemption priority and subpriority for the DMA interrupt */
+#define AUDIO_IN_IRQ_PREPRIO ((uint32_t)0x0F)
+
+
+/*------------------------------------------------------------------------------
+ CONFIGURATION: Audio Driver Configuration parameters
+------------------------------------------------------------------------------*/
+
+#define AUDIODATA_SIZE 2 /* 16-bits audio data size */
+
+/* Audio status definition */
+#define AUDIO_OK ((uint8_t)0)
+#define AUDIO_ERROR ((uint8_t)1)
+#define AUDIO_TIMEOUT ((uint8_t)2)
+
+/* Audio In default settings */
+#define DEFAULT_AUDIO_IN_FREQ BSP_AUDIO_FREQUENCY_16K
+#define DEFAULT_AUDIO_IN_BIT_RESOLUTION ((uint8_t)16)
+#define DEFAULT_AUDIO_IN_CHANNEL_NBR ((uint8_t)2)
+#define DEFAULT_AUDIO_IN_VOLUME ((uint16_t)64)
+
+/*------------------------------------------------------------------------------
+ OUTPUT DEVICES definition
+------------------------------------------------------------------------------*/
+/* Alias on existing output devices to adapt for 2 headphones output */
+#define OUTPUT_DEVICE_HEADPHONE1 OUTPUT_DEVICE_HEADPHONE
+#define OUTPUT_DEVICE_HEADPHONE2 OUTPUT_DEVICE_SPEAKER /* Headphone2 is connected to Speaker output of the wm8994 */
+
+/*------------------------------------------------------------------------------
+ INPUT DEVICES definition
+------------------------------------------------------------------------------*/
+/* MP34DT01TR digital microphone on PCB top side */
+#define INPUT_DEVICE_DIGITAL_MIC ((uint16_t)0)
+/* Analog microphone input from 3.5 audio jack connector */
+#define INPUT_DEVICE_ANALOG_MIC INPUT_DEVICE_INPUT_LINE_1
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_AUDIO_Exported_Macros STM32F769I_DISCOVERY_AUDIO Exported Macros
+ * @{
+ */
+#define DMA_MAX(x) (((x) <= DMA_MAX_SZE)? (x):DMA_MAX_SZE)
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_AUDIO_OUT_Exported_Functions STM32F769I_DISCOVERY_AUDIO_OUT Exported Functions
+ * @{
+ */
+uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq);
+void BSP_AUDIO_OUT_DeInit(void);
+uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size);
+void BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size);
+uint8_t BSP_AUDIO_OUT_Pause(void);
+uint8_t BSP_AUDIO_OUT_Resume(void);
+uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option);
+uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume);
+void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq);
+void BSP_AUDIO_OUT_SetAudioFrameSlot(uint32_t AudioFrameSlot);
+uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd);
+uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output);
+
+/* User Callbacks: user has to implement these functions in his code if they are needed. */
+/* This function is called when the requested data has been completely transferred.*/
+void BSP_AUDIO_OUT_TransferComplete_CallBack(void);
+
+/* This function is called when half of the requested buffer has been transferred. */
+void BSP_AUDIO_OUT_HalfTransfer_CallBack(void);
+
+/* This function is called when an Interrupt due to transfer error on or peripheral
+ error occurs. */
+void BSP_AUDIO_OUT_Error_CallBack(void);
+
+/* These function can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_AUDIO_OUT_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params);
+void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params);
+void BSP_AUDIO_OUT_MspDeInit(SAI_HandleTypeDef *hsai, void *Params);
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_AUDIO_IN_Exported_Functions STM32F769I_DISCOVERY_AUDIO_IN Exported Functions
+ * @{
+ */
+uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_InitEx(uint16_t InputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_AllocScratch (int32_t *pScratch, uint32_t size);
+uint8_t BSP_AUDIO_IN_GetChannelNumber(void);
+void BSP_AUDIO_IN_DeInit(void);
+uint8_t BSP_AUDIO_IN_Record(uint16_t *pData, uint32_t Size);
+uint8_t BSP_AUDIO_IN_Stop(void);
+uint8_t BSP_AUDIO_IN_Pause(void);
+uint8_t BSP_AUDIO_IN_Resume(void);
+
+/* User Callbacks: user has to implement these functions in his code if they are needed. */
+/* This function should be implemented by the user application.
+ It is called into this driver when the current buffer is filled to prepare the next
+ buffer pointer and its size. */
+void BSP_AUDIO_IN_TransferComplete_CallBack(void);
+void BSP_AUDIO_IN_HalfTransfer_CallBack(void);
+
+/* This function is called when an Interrupt due to transfer error on or peripheral
+ error occurs. */
+void BSP_AUDIO_IN_Error_CallBack(void);
+
+/* These function can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_AUDIO_IN_ClockConfig(DFSDM_Filter_HandleTypeDef *hdfsdm_filter, uint32_t AudioFreq, void *Params);
+void BSP_AUDIO_IN_MspInit(void);
+void BSP_AUDIO_IN_MspDeInit(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_DISCOVERY_AUDIO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_eeprom.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_eeprom.c
new file mode 100644
index 00000000..220159e1
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_eeprom.c
@@ -0,0 +1,476 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_discovery_eeprom.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage an I2C M24LR64
+ * EEPROM memory.
+ @verbatim
+ To be able to use this driver, the switch EE_M24LR64 must be defined
+ in your toolchain compiler preprocessor
+
+ ===================================================================
+ Notes:
+ - The I2C EEPROM memory (M24LR64) is available on separate daughter
+ board ANT7-M24LR-A, which is not provided with the STM32F769I_DISCOVERY
+ board.
+ To use this driver you have to connect the ANT7-M24LR-A to CN2
+ connector of STM32F769I_DISCOVERY board.
+ ===================================================================
+
+ It implements a high level communication layer for read and write
+ from/to this memory. The needed STM32F7xx hardware resources (I2C and
+ GPIO) are defined in stm32f769i_discovery.h file, and the initialization is
+ performed in EEPROM_IO_Init() function declared in stm32f769i_discovery.c
+ file.
+ You can easily tailor this driver to any other development board,
+ by just adapting the defines for hardware resources and
+ EEPROM_IO_Init() function.
+
+ @note In this driver, basic read and write functions (BSP_EEPROM_ReadBuffer()
+ and BSP_EEPROM_WritePage()) use DMA mode to perform the data
+ transfer to/from EEPROM memory.
+
+ @note Regarding BSP_EEPROM_WritePage(), it is an optimized function to perform
+ small write (less than 1 page) BUT the number of bytes (combined to write start address) must not
+ cross the EEPROM page boundary. This function can only writes into
+ the boundaries of an EEPROM page.
+ This function doesn't check on boundaries condition (in this driver
+ the function BSP_EEPROM_WriteBuffer() which calls BSP_EEPROM_WritePage() is
+ responsible of checking on Page boundaries).
+
+
+ +-----------------------------------------------------------------+
+ | Pin assignment for M24LR64 EEPROM |
+ +---------------------------------------+-----------+-------------+
+ | STM32F7xx I2C Pins | EEPROM | Pin |
+ +---------------------------------------+-----------+-------------+
+ | . | E0(GND) | 1 (0V) |
+ | . | AC0 | 2 |
+ | . | AC1 | 3 |
+ | . | VSS | 4 (0V) |
+ | SDA | SDA | 5 |
+ | SCL | SCL | 6 |
+ | . | E1(GND) | 7 (0V) |
+ | . | VDD | 8 (3.3V) |
+ +---------------------------------------+-----------+-------------+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Dependencies
+- stm32f769i_discovery.c
+EndDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f769i_discovery_eeprom.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY_EEPROM STM32F769I_DISCOVERY EEPROM
+ * @brief This file includes the I2C EEPROM driver of STM32F769I-DISCOVERY board.
+ * @{
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_EEPROM_Private_Types EEPROM Private Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_EEPROM_Private_Defines EEPROM Private Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_EEPROM_Private_Macros EEPROM Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_EEPROM_Private_Variables EEPROM Private Variables
+ * @{
+ */
+__IO uint16_t EEPROMAddress = 0;
+__IO uint16_t EEPROMDataRead;
+__IO uint8_t EEPROMDataWrite;
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_EEPROM_Private_Function_Prototypes EEPROM Private Function Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_EEPROM_Private_Functions EEPROM Private Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes peripherals used by the I2C EEPROM driver.
+ * @note There are 2 different versions of M24LR64 (A01 & A02).
+ * Then try to connect on 1st one (EEPROM_I2C_ADDRESS_A01)
+ * and if problem, check the 2nd one (EEPROM_I2C_ADDRESS_A02)
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0)
+ */
+uint32_t BSP_EEPROM_Init(void)
+{
+ /* I2C Initialization */
+ EEPROM_IO_Init();
+
+ /* Select the EEPROM address for A01 and check if OK */
+ EEPROMAddress = EEPROM_I2C_ADDRESS_A01;
+ if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
+ {
+ /* Select the EEPROM address for A02 and check if OK */
+ EEPROMAddress = EEPROM_I2C_ADDRESS_A02;
+ if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
+ {
+ return EEPROM_FAIL;
+ }
+ }
+ return EEPROM_OK;
+}
+
+/**
+ * @brief DeInitializes the EEPROM.
+ * @retval EEPROM state
+ */
+uint8_t BSP_EEPROM_DeInit(void)
+{
+ /* I2C won't be disabled because common to other functionalities */
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Reads a block of data from the EEPROM.
+ * @param pBuffer: pointer to the buffer that receives the data read from
+ * the EEPROM.
+ * @param ReadAddr: EEPROM's internal address to start reading from.
+ * @param NumByteToRead: pointer to the variable holding number of bytes to
+ * be read from the EEPROM.
+ *
+ * @note The variable pointed by NumByteToRead is reset to 0 when all the
+ * data are read from the EEPROM. Application should monitor this
+ * variable in order know when the transfer is complete.
+ *
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
+{
+ uint32_t buffersize = *NumByteToRead;
+
+ /* Set the pointer to the Number of data to be read. This pointer will be used
+ by the DMA Transfer Completer interrupt Handler in order to reset the
+ variable to 0. User should check on this variable in order to know if the
+ DMA transfer has been complete or not. */
+ EEPROMDataRead = *NumByteToRead;
+
+ if(EEPROM_IO_ReadData(EEPROMAddress, ReadAddr, pBuffer, buffersize) != HAL_OK)
+ {
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ return EEPROM_FAIL;
+ }
+
+ /* If all operations OK, return EEPROM_OK (0) */
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Writes more than one byte to the EEPROM with a single WRITE cycle.
+ *
+ * @note The number of bytes (combined to write start address) must not
+ * cross the EEPROM page boundary. This function can only write into
+ * the boundaries of an EEPROM page.
+ * This function doesn't check on boundaries condition (in this driver
+ * the function BSP_EEPROM_WriteBuffer() which calls BSP_EEPROM_WritePage() is
+ * responsible of checking on Page boundaries).
+ *
+ * @param pBuffer: pointer to the buffer containing the data to be written to
+ * the EEPROM.
+ * @param WriteAddr: EEPROM's internal address to write to.
+ * @param NumByteToWrite: pointer to the variable holding number of bytes to
+ * be written into the EEPROM.
+ *
+ * @note The variable pointed by NumByteToWrite is reset to 0 when all the
+ * data are written to the EEPROM. Application should monitor this
+ * variable in order know when the transfer is complete.
+ *
+ * @note This function just configure the communication and enable the DMA
+ * channel to transfer data. Meanwhile, the user application may perform
+ * other tasks in parallel.
+ *
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite)
+{
+ uint32_t buffersize = *NumByteToWrite;
+ uint32_t status = EEPROM_OK;
+
+ /* Set the pointer to the Number of data to be written. This pointer will be used
+ by the DMA Transfer Completer interrupt Handler in order to reset the
+ variable to 0. User should check on this variable in order to know if the
+ DMA transfer has been complete or not. */
+ EEPROMDataWrite = *NumByteToWrite;
+
+ if(EEPROM_IO_WriteData(EEPROMAddress, WriteAddr, pBuffer, buffersize) != HAL_OK)
+ {
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ status = EEPROM_FAIL;
+ }
+
+ if(BSP_EEPROM_WaitEepromStandbyState() != EEPROM_OK)
+ {
+ return EEPROM_FAIL;
+ }
+
+ /* If all operations OK, return EEPROM_OK (0) */
+ return status;
+}
+
+/**
+ * @brief Writes buffer of data to the I2C EEPROM.
+ * @param pBuffer: pointer to the buffer containing the data to be written
+ * to the EEPROM.
+ * @param WriteAddr: EEPROM's internal address to write to.
+ * @param NumByteToWrite: number of bytes to write to the EEPROM.
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_WriteBuffer(uint8_t *pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
+{
+ uint16_t numofpage = 0, numofsingle = 0, count = 0;
+ uint16_t addr = 0;
+ uint8_t dataindex = 0;
+ uint32_t status = EEPROM_OK;
+
+ addr = WriteAddr % EEPROM_PAGESIZE;
+ count = EEPROM_PAGESIZE - addr;
+ numofpage = NumByteToWrite / EEPROM_PAGESIZE;
+ numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
+
+ /* If WriteAddr is EEPROM_PAGESIZE aligned */
+ if(addr == 0)
+ {
+ /* If NumByteToWrite < EEPROM_PAGESIZE */
+ if(numofpage == 0)
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ /* Start writing data */
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ /* If NumByteToWrite > EEPROM_PAGESIZE */
+ else
+ {
+ while(numofpage--)
+ {
+ /* Store the number of data to be written */
+ dataindex = EEPROM_PAGESIZE;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+
+ WriteAddr += EEPROM_PAGESIZE;
+ pBuffer += EEPROM_PAGESIZE;
+ }
+
+ if(numofsingle!=0)
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ }
+ }
+ /* If WriteAddr is not EEPROM_PAGESIZE aligned */
+ else
+ {
+ /* If NumByteToWrite < EEPROM_PAGESIZE */
+ if(numofpage== 0)
+ {
+ /* If the number of data to be written is more than the remaining space
+ in the current page: */
+ if(NumByteToWrite > count)
+ {
+ /* Store the number of data to be written */
+ dataindex = count;
+ /* Write the data contained in same page */
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+
+ /* Store the number of data to be written */
+ dataindex = (NumByteToWrite - count);
+ /* Write the remaining data in the following page */
+ status = BSP_EEPROM_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ else
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ }
+ /* If NumByteToWrite > EEPROM_PAGESIZE */
+ else
+ {
+ NumByteToWrite -= count;
+ numofpage = NumByteToWrite / EEPROM_PAGESIZE;
+ numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
+
+ if(count != 0)
+ {
+ /* Store the number of data to be written */
+ dataindex = count;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ WriteAddr += count;
+ pBuffer += count;
+ }
+
+ while(numofpage--)
+ {
+ /* Store the number of data to be written */
+ dataindex = EEPROM_PAGESIZE;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ WriteAddr += EEPROM_PAGESIZE;
+ pBuffer += EEPROM_PAGESIZE;
+ }
+ if(numofsingle != 0)
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ }
+ }
+
+ /* If all operations OK, return EEPROM_OK (0) */
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Wait for EEPROM Standby state.
+ *
+ * @note This function allows to wait and check that EEPROM has finished the
+ * last operation. It is mostly used after Write operation: after receiving
+ * the buffer to be written, the EEPROM may need additional time to actually
+ * perform the write operation. During this time, it doesn't answer to
+ * I2C packets addressed to it. Once the write operation is complete
+ * the EEPROM responds to its address.
+ *
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_WaitEepromStandbyState(void)
+{
+ /* Check if the maximum allowed number of trials has bee reached */
+ if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
+ {
+ /* If the maximum number of trials has been reached, exit the function */
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ return EEPROM_TIMEOUT;
+ }
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Basic management of the timeout situation.
+ * @retval None
+ */
+__weak void BSP_EEPROM_TIMEOUT_UserCallback(void)
+{
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_eeprom.h b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_eeprom.h
new file mode 100644
index 00000000..b3451aef
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_eeprom.h
@@ -0,0 +1,138 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_discovery_eeprom.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for
+ * the stm32f769i_discovery_eeprom.c firmware driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_DISCOVERY_EEPROM_H
+#define __STM32F769I_DISCOVERY_EEPROM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f769i_discovery.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY_EEPROM
+ * @brief This file includes the I2C EEPROM driver of STM32F769I-DISCOVERY board.
+ * @{
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_EEPROM_Exported_Types EEPROM Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_EEPROM_Exported_Constants EEPROM Exported Constants
+ * @{
+ */
+/* EEPROM hardware address and page size */
+#define EEPROM_PAGESIZE ((uint8_t)4)
+#define EEPROM_MAX_SIZE ((uint16_t)0x2000) /* 64Kbit */
+
+
+/* Maximum number of trials for EEPROM_WaitEepromStandbyState() function */
+#define EEPROM_MAX_TRIALS ((uint32_t)3000)
+
+#define EEPROM_OK ((uint32_t)0)
+#define EEPROM_FAIL ((uint32_t)1)
+#define EEPROM_TIMEOUT ((uint32_t)2)
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_EEPROM_Exported_Macros EEPROM Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_EEPROM_Exported_Functions EEPROM Exported Functions
+ * @{
+ */
+uint32_t BSP_EEPROM_Init(void);
+uint8_t BSP_EEPROM_DeInit(void);
+uint32_t BSP_EEPROM_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead);
+uint32_t BSP_EEPROM_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite);
+uint32_t BSP_EEPROM_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite);
+uint32_t BSP_EEPROM_WaitEepromStandbyState(void);
+
+/* USER Callbacks: This function is declared as __weak in EEPROM driver and
+ should be implemented into user application.
+ BSP_EEPROM_TIMEOUT_UserCallback() function is called whenever a timeout condition
+ occurs during communication (waiting on an event that doesn't occur, bus
+ errors, busy devices ...). */
+void BSP_EEPROM_TIMEOUT_UserCallback(void);
+
+/* Link function for I2C EEPROM peripheral */
+void EEPROM_IO_Init(void);
+HAL_StatusTypeDef EEPROM_IO_WriteData(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef EEPROM_IO_ReadData(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef EEPROM_IO_IsDeviceReady(uint16_t DevAddress, uint32_t Trials);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_DISCOVERY_EEPROM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_lcd.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_lcd.c
new file mode 100644
index 00000000..9006efbf
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_lcd.c
@@ -0,0 +1,1955 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_discovery_lcd.c
+ * @author MCD Application Team
+ * @brief This file includes the driver for Liquid Crystal Display (LCD) module
+ * mounted on STM32F769I-DISCOVERY board.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_DISCOVERY_LCD_H
+#define __STM32F769I_DISCOVERY_LCD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include LCD component Driver */
+
+/* Include OTM8009A LCD Driver IC driver code */
+#include "../Components/otm8009a/otm8009a.h"
+/* Include ADV7533 HDMI Driver IC driver code */
+#include "../Components/adv7533/adv7533.h"
+
+/* Include SDRAM Driver */
+#include "stm32f769i_discovery_sdram.h"
+#include "stm32f769i_discovery.h"
+
+#include "../../../Utilities/Fonts/fonts.h"
+
+#include /* use of memset() */
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY_LCD
+ * @{
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_LCD_Exported_Constants STM32F769I DISCOVERY LCD Exported Constants
+ * @{
+ */
+#define BSP_LCD_DMA2D_IRQHandler DMA2D_IRQHandler
+#define BSP_LCD_DSI_IRQHandler DSI_IRQHandler
+#define BSP_LCD_LTDC_IRQHandler LTDC_IRQHandler
+#define BSP_LCD_LTDC_ER_IRQHandler LTDC_ER_IRQHandler
+
+
+#define LCD_LayerCfgTypeDef LTDC_LayerCfgTypeDef
+/**
+ * @brief LCD FB_StartAddress
+ */
+#define LCD_FB_START_ADDRESS ((uint32_t)0xC0000000)
+
+/** @brief Maximum number of LTDC layers
+ */
+#define LTDC_MAX_LAYER_NUMBER ((uint32_t) 2)
+
+/** @brief LTDC Background layer index
+ */
+#define LTDC_ACTIVE_LAYER_BACKGROUND ((uint32_t) 0)
+
+/** @brief LTDC Foreground layer index
+ */
+#define LTDC_ACTIVE_LAYER_FOREGROUND ((uint32_t) 1)
+
+/** @brief Number of LTDC layers
+ */
+#define LTDC_NB_OF_LAYERS ((uint32_t) 2)
+
+/** @brief LTDC Default used layer index
+ */
+#define LTDC_DEFAULT_ACTIVE_LAYER LTDC_ACTIVE_LAYER_FOREGROUND
+
+/**
+ * @brief LCD status structure definition
+ */
+#define LCD_OK 0x00
+#define LCD_ERROR 0x01
+#define LCD_TIMEOUT 0x02
+
+/**
+ * @brief LCD Display OTM8009A DSI Virtual Channel ID
+ */
+#define LCD_OTM8009A_ID ((uint32_t) 0)
+
+/**
+ * @brief HDMI ADV7533 DSI Virtual Channel ID
+ */
+#define HDMI_ADV7533_ID ((uint32_t) 0)
+
+/**
+ * @brief HDMI Foramt
+ */
+#define HDMI_FORMAT_720_480 ((uint8_t) 0x00) /*720_480 format choice of HDMI display */
+#define HDMI_FORMAT_720_576 ((uint8_t) 0x01) /*720_576 format choice of HDMI display*/
+
+/**
+ * @brief LCD color definitions values
+ * in ARGB8888 format.
+ */
+
+/** @brief Blue value in ARGB8888 format
+ */
+#define LCD_COLOR_BLUE ((uint32_t) 0xFF0000FF)
+
+/** @brief Green value in ARGB8888 format
+ */
+#define LCD_COLOR_GREEN ((uint32_t) 0xFF00FF00)
+
+/** @brief Red value in ARGB8888 format
+ */
+#define LCD_COLOR_RED ((uint32_t) 0xFFFF0000)
+
+/** @brief Cyan value in ARGB8888 format
+ */
+#define LCD_COLOR_CYAN ((uint32_t) 0xFF00FFFF)
+
+/** @brief Magenta value in ARGB8888 format
+ */
+#define LCD_COLOR_MAGENTA ((uint32_t) 0xFFFF00FF)
+
+/** @brief Yellow value in ARGB8888 format
+ */
+#define LCD_COLOR_YELLOW ((uint32_t) 0xFFFFFF00)
+
+/** @brief Light Blue value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTBLUE ((uint32_t) 0xFF8080FF)
+
+/** @brief Light Green value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTGREEN ((uint32_t) 0xFF80FF80)
+
+/** @brief Light Red value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTRED ((uint32_t) 0xFFFF8080)
+
+/** @brief Light Cyan value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTCYAN ((uint32_t) 0xFF80FFFF)
+
+/** @brief Light Magenta value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTMAGENTA ((uint32_t) 0xFFFF80FF)
+
+/** @brief Light Yellow value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTYELLOW ((uint32_t) 0xFFFFFF80)
+
+/** @brief Dark Blue value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKBLUE ((uint32_t) 0xFF000080)
+
+/** @brief Light Dark Green value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKGREEN ((uint32_t) 0xFF008000)
+
+/** @brief Light Dark Red value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKRED ((uint32_t) 0xFF800000)
+
+/** @brief Dark Cyan value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKCYAN ((uint32_t) 0xFF008080)
+
+/** @brief Dark Magenta value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKMAGENTA ((uint32_t) 0xFF800080)
+
+/** @brief Dark Yellow value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKYELLOW ((uint32_t) 0xFF808000)
+
+/** @brief White value in ARGB8888 format
+ */
+#define LCD_COLOR_WHITE ((uint32_t) 0xFFFFFFFF)
+
+/** @brief Light Gray value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTGRAY ((uint32_t) 0xFFD3D3D3)
+
+/** @brief Gray value in ARGB8888 format
+ */
+#define LCD_COLOR_GRAY ((uint32_t) 0xFF808080)
+
+/** @brief Dark Gray value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKGRAY ((uint32_t) 0xFF404040)
+
+/** @brief Black value in ARGB8888 format
+ */
+#define LCD_COLOR_BLACK ((uint32_t) 0xFF000000)
+
+/** @brief Brown value in ARGB8888 format
+ */
+#define LCD_COLOR_BROWN ((uint32_t) 0xFFA52A2A)
+
+/** @brief Orange value in ARGB8888 format
+ */
+#define LCD_COLOR_ORANGE ((uint32_t) 0xFFFFA500)
+
+/** @brief Transparent value in ARGB8888 format
+ */
+#define LCD_COLOR_TRANSPARENT ((uint32_t) 0xFF000000)
+
+/**
+ * @brief LCD default font
+ */
+#define LCD_DEFAULT_FONT Font24
+
+/**
+ * @brief Possible values of
+ * pixel data format (ie color coding) transmitted on DSI Data lane in DSI packets
+ */
+
+#define LCD_DSI_PIXEL_DATA_FMT_RBG888 DSI_RGB888 /*!< DSI packet pixel format chosen is RGB888 : 24 bpp */
+#define LCD_DSI_PIXEL_DATA_FMT_RBG565 DSI_RGB565 /*!< DSI packet pixel format chosen is RGB565 : 16 bpp */
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_LCD_Exported_Types STM32F769I DISCOVERY LCD Exported Types
+ * @{
+ */
+
+/**
+* @brief LCD Drawing main properties
+*/
+typedef struct
+{
+ uint32_t TextColor; /*!< Specifies the color of text */
+ uint32_t BackColor; /*!< Specifies the background color below the text */
+ sFONT *pFont; /*!< Specifies the font used for the text */
+
+} LCD_DrawPropTypeDef;
+
+/**
+ * @brief LCD Drawing point (pixel) geometric definition
+ */
+typedef struct
+{
+ int16_t X; /*!< geometric X position of drawing */
+ int16_t Y; /*!< geometric Y position of drawing */
+
+} Point;
+
+/**
+ * @brief Pointer on LCD Drawing point (pixel) geometric definition
+ */
+typedef Point * pPoint;
+
+/**
+ * @brief LCD drawing Line alignment mode definitions
+ */
+typedef enum
+{
+ CENTER_MODE = 0x01, /*!< Center mode */
+ RIGHT_MODE = 0x02, /*!< Right mode */
+ LEFT_MODE = 0x03 /*!< Left mode */
+
+} Text_AlignModeTypdef;
+
+
+/**
+ * @brief LCD_OrientationTypeDef
+ * Possible values of Display Orientation
+ */
+typedef enum
+{
+ LCD_ORIENTATION_PORTRAIT = 0x00, /*!< Portrait orientation choice of LCD screen */
+ LCD_ORIENTATION_LANDSCAPE = 0x01, /*!< Landscape orientation choice of LCD screen */
+ LCD_ORIENTATION_INVALID = 0x02 /*!< Invalid orientation choice of LCD screen */
+} LCD_OrientationTypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_LCD_Exported_Macro STM32F769I DISCOVERY LCD Exported Macro
+ * @{
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY_LCD_Exported_Functions
+ * @{
+ */
+uint8_t BSP_LCD_Init(void);
+uint8_t BSP_LCD_InitEx(LCD_OrientationTypeDef orientation);
+uint8_t BSP_LCD_HDMIInitEx(uint8_t format);
+
+void BSP_LCD_MspDeInit(void);
+void BSP_LCD_MspInit(void);
+void BSP_LCD_Reset(void);
+
+uint32_t BSP_LCD_GetXSize(void);
+uint32_t BSP_LCD_GetYSize(void);
+void BSP_LCD_SetXSize(uint32_t imageWidthPixels);
+void BSP_LCD_SetYSize(uint32_t imageHeightPixels);
+
+void BSP_LCD_LayerDefaultInit(uint16_t LayerIndex, uint32_t FB_Address);
+void BSP_LCD_SetTransparency(uint32_t LayerIndex, uint8_t Transparency);
+void BSP_LCD_SetLayerAddress(uint32_t LayerIndex, uint32_t Address);
+void BSP_LCD_SetColorKeying(uint32_t LayerIndex, uint32_t RGBValue);
+void BSP_LCD_ResetColorKeying(uint32_t LayerIndex);
+void BSP_LCD_SetLayerWindow(uint16_t LayerIndex, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+
+void BSP_LCD_SelectLayer(uint32_t LayerIndex);
+void BSP_LCD_SetLayerVisible(uint32_t LayerIndex, FunctionalState State);
+
+void BSP_LCD_SetTextColor(uint32_t Color);
+uint32_t BSP_LCD_GetTextColor(void);
+void BSP_LCD_SetBackColor(uint32_t Color);
+uint32_t BSP_LCD_GetBackColor(void);
+void BSP_LCD_SetFont(sFONT *fonts);
+sFONT *BSP_LCD_GetFont(void);
+
+uint32_t BSP_LCD_ReadPixel(uint16_t Xpos, uint16_t Ypos);
+void BSP_LCD_DrawPixel(uint16_t Xpos, uint16_t Ypos, uint32_t pixel);
+void BSP_LCD_Clear(uint32_t Color);
+void BSP_LCD_ClearStringLine(uint32_t Line);
+void BSP_LCD_DisplayStringAtLine(uint16_t Line, uint8_t *ptr);
+void BSP_LCD_DisplayStringAt(uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Text_AlignModeTypdef Mode);
+void BSP_LCD_DisplayChar(uint16_t Xpos, uint16_t Ypos, uint8_t Ascii);
+
+void BSP_LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+void BSP_LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+void BSP_LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+void BSP_LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+void BSP_LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+void BSP_LCD_DrawPolygon(pPoint Points, uint16_t PointCount);
+void BSP_LCD_DrawEllipse(int Xpos, int Ypos, int XRadius, int YRadius);
+void BSP_LCD_DrawBitmap(uint32_t Xpos, uint32_t Ypos, uint8_t *pbmp);
+
+void BSP_LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+void BSP_LCD_FillCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+void BSP_LCD_FillPolygon(pPoint Points, uint16_t PointCount);
+void BSP_LCD_FillEllipse(int Xpos, int Ypos, int XRadius, int YRadius);
+
+void BSP_LCD_DisplayOn(void);
+void BSP_LCD_DisplayOff(void);
+void BSP_LCD_SetBrightness(uint8_t BrightnessValue);
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_LCD_Exported_Variables STM32F769I DISCOVERY LCD Exported Variables
+ * @{
+ */
+
+/* @brief DMA2D handle variable */
+extern DMA2D_HandleTypeDef hdma2d_discovery;
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_DISCOVERY_LCD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_qspi.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_qspi.c
new file mode 100644
index 00000000..7baf3560
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_qspi.c
@@ -0,0 +1,1182 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_discovery_qspi.c
+ * @author MCD Application Team
+ * @brief This file includes a standard driver for the MX25L512 QSPI
+ * memory mounted on STM32F769I-Discovery board.
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) This driver is used to drive the MX25L512 QSPI external
+ memory mounted on STM32F769I-Discovery board.
+
+ (#) This driver need a specific component driver (MX25L51245G) to be included with.
+
+ (#) Initialization steps:
+ (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ QSPI interface with the external memory.
+
+ (#) QSPI memory operations
+ (++) QSPI memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_QSPI_Read()/BSP_QSPI_Write().
+ (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory.
+ (see the QSPI memory data sheet)
+ (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by
+ specifying the block address. You can perform an erase operation of the whole
+ chip by calling the function BSP_QSPI_Erase_Chip().
+ (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory.
+ (see the QSPI memory data sheet)
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY
+ * @{
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_DISCOVERY_QSPI_H
+#define __STM32F769I_DISCOVERY_QSPI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+#include "../Components/mx25l512/mx25l512.h"
+
+/** @addtogroup STM32F769I_DISCOVERY_QSPI
+ * @{
+ */
+
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup STM32F769I_DISCOVERY_QSPI_Exported_Constants STM32F769I_DISCOVERY_QSPI Exported Constants
+ * @{
+ */
+/* QSPI Error codes */
+#define QSPI_OK ((uint8_t)0x00)
+#define QSPI_ERROR ((uint8_t)0x01)
+#define QSPI_BUSY ((uint8_t)0x02)
+#define QSPI_NOT_SUPPORTED ((uint8_t)0x04)
+#define QSPI_SUSPENDED ((uint8_t)0x08)
+
+
+/* Definition for QSPI clock resources */
+#define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE()
+#define QSPI_CLK_DISABLE() __HAL_RCC_QSPI_CLK_DISABLE()
+#define QSPI_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define QSPI_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define QSPI_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define QSPI_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define QSPI_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
+#define QSPI_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
+
+#define QSPI_FORCE_RESET() __HAL_RCC_QSPI_FORCE_RESET()
+#define QSPI_RELEASE_RESET() __HAL_RCC_QSPI_RELEASE_RESET()
+
+/* Definition for QSPI Pins */
+/* QSPI_CS */
+#define QSPI_CS_PIN GPIO_PIN_6
+#define QSPI_CS_GPIO_PORT GPIOB
+#define QSPI_CS_PIN_AF GPIO_AF10_QUADSPI
+/* QSPI_CLK */
+#define QSPI_CLK_PIN GPIO_PIN_2
+#define QSPI_CLK_GPIO_PORT GPIOB
+#define QSPI_CLK_PIN_AF GPIO_AF9_QUADSPI
+/* QSPI_D0 */
+#define QSPI_D0_PIN GPIO_PIN_9
+#define QSPI_D0_GPIO_PORT GPIOC
+#define QSPI_D0_PIN_AF GPIO_AF9_QUADSPI
+/* QSPI_D1 */
+#define QSPI_D1_PIN GPIO_PIN_10
+#define QSPI_D1_GPIO_PORT GPIOC
+#define QSPI_D1_PIN_AF GPIO_AF9_QUADSPI
+/* QSPI_D2 */
+#define QSPI_D2_PIN GPIO_PIN_2
+#define QSPI_D2_GPIO_PORT GPIOE
+#define QSPI_D2_PIN_AF GPIO_AF9_QUADSPI
+/* QSPI_D3 */
+#define QSPI_D3_PIN GPIO_PIN_13
+#define QSPI_D3_GPIO_PORT GPIOD
+#define QSPI_D3_PIN_AF GPIO_AF9_QUADSPI
+
+/**
+ * @}
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup STM32F769I_DISCOVERY_QSPI_Exported_Types STM32F769I_DISCOVERY_QSPI Exported Types
+ * @{
+ */
+/* QSPI Info */
+typedef struct {
+ uint32_t FlashSize; /*!< Size of the flash */
+ uint32_t EraseSectorSize; /*!< Size of sectors for the erase operation */
+ uint32_t EraseSectorsNumber; /*!< Number of sectors for the erase operation */
+ uint32_t ProgPageSize; /*!< Size of pages for the program operation */
+ uint32_t ProgPagesNumber; /*!< Number of pages for the program operation */
+} QSPI_Info;
+
+/**
+ * @}
+ */
+
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup STM32F769I_DISCOVERY_QSPI_Exported_Functions
+ * @{
+ */
+uint8_t BSP_QSPI_Init (void);
+uint8_t BSP_QSPI_DeInit (void);
+uint8_t BSP_QSPI_Read (uint8_t* pData, uint32_t ReadAddr, uint32_t Size);
+uint8_t BSP_QSPI_Write (uint8_t* pData, uint32_t WriteAddr, uint32_t Size);
+uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress);
+uint8_t BSP_QSPI_Erase_Chip (void);
+uint8_t BSP_QSPI_GetStatus (void);
+uint8_t BSP_QSPI_GetInfo (QSPI_Info* pInfo);
+uint8_t BSP_QSPI_EnableMemoryMappedMode(void);
+
+/* These functions can be modified in case the current settings
+ need to be changed for specific application needs */
+void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params);
+void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_DISCOVERY_QSPI_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_sd.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_sd.c
new file mode 100644
index 00000000..7d2b005e
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_sd.c
@@ -0,0 +1,611 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_discovery_sd.c
+ * @author MCD Application Team
+ * @brief This file includes the uSD card driver mounted on STM32F769I-Discovery
+ * board.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_DISCOVERY_SD_H
+#define __STM32F769I_DISCOVERY_SD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f769i_discovery.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY_SD STM32F769I_DISCOVERY SD
+ * @{
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_SD_Exported_Types SD Exported Types
+ * @{
+ */
+
+/**
+ * @brief SD Card information structure
+ */
+#define BSP_SD_CardInfo HAL_SD_CardInfoTypeDef
+/**
+ * @}
+ */
+
+/**
+ * @brief SD status structure definition
+ */
+#define MSD_OK ((uint8_t)0x00)
+#define MSD_ERROR ((uint8_t)0x01)
+#define MSD_ERROR_SD_NOT_PRESENT ((uint8_t)0x02)
+
+/**
+ * @brief SD transfer state definition
+ */
+#define SD_TRANSFER_OK ((uint8_t)0x00)
+#define SD_TRANSFER_BUSY ((uint8_t)0x01)
+
+/** @defgroup STM32F769I_DISCOVERY_SD_Exported_Constants SD Exported Constants
+ * @{
+ */
+#define SD_PRESENT ((uint8_t)0x01)
+#define SD_NOT_PRESENT ((uint8_t)0x00)
+
+#define SD_DATATIMEOUT ((uint32_t)100000000)
+
+/* DMA definitions for SD DMA transfer */
+#define __DMAx_TxRx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
+#define SD_DMAx_Tx_CHANNEL DMA_CHANNEL_11
+#define SD_DMAx_Rx_CHANNEL DMA_CHANNEL_11
+#define SD_DMAx_Tx_STREAM DMA2_Stream5
+#define SD_DMAx_Rx_STREAM DMA2_Stream0
+#define SD_DMAx_Tx_IRQn DMA2_Stream5_IRQn
+#define SD_DMAx_Rx_IRQn DMA2_Stream0_IRQn
+#define BSP_SDMMC_IRQHandler SDMMC2_IRQHandler
+#define BSP_SDMMC_DMA_Tx_IRQHandler DMA2_Stream5_IRQHandler
+#define BSP_SDMMC_DMA_Rx_IRQHandler DMA2_Stream0_IRQHandler
+#define SD_DetectIRQHandler() HAL_GPIO_EXTI_IRQHandler(SD_DETECT_PIN)
+
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_SD_Exported_Macro STM32F769I Discovery SD Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_SD_Exported_Functions STM32F769I Discovery SD Exported Functions
+ * @{
+ */
+uint8_t BSP_SD_Init(void);
+uint8_t BSP_SD_DeInit(void);
+uint8_t BSP_SD_ITConfig(void);
+uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout);
+uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout);
+uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks);
+uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks);
+uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr);
+uint8_t BSP_SD_GetCardState(void);
+void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypeDef *CardInfo);
+uint8_t BSP_SD_IsDetected(void);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params);
+void BSP_SD_Detect_MspInit(SD_HandleTypeDef *hsd, void *Params);
+void BSP_SD_MspDeInit(SD_HandleTypeDef *hsd, void *Params);
+void BSP_SD_AbortCallback(void);
+void BSP_SD_WriteCpltCallback(void);
+void BSP_SD_ReadCpltCallback(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_DISCOVERY_SD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_sdram.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_sdram.c
new file mode 100644
index 00000000..1b7f5e5e
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_sdram.c
@@ -0,0 +1,503 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_discovery_sdram.c
+ * @author MCD Application Team
+ * @brief This file includes the SDRAM driver for the MT48LC4M32B2B5-6A memory
+ * device mounted on STM32F769I-DISCOVERY boards.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ - This driver is used to drive the MT48LC4M32B2B5-6A SDRAM external memory mounted
+ on STM32F769I-DISCOVERY board.
+ - This driver does not need a specific component driver for the SDRAM device
+ to be included with.
+
+ Driver description:
+ ------------------
+ + Initialization steps:
+ o Initialize the SDRAM external memory using the BSP_SDRAM_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ FMC controller configuration to interface with the external SDRAM memory.
+ o It contains the SDRAM initialization sequence to program the SDRAM external
+ device using the function BSP_SDRAM_Initialization_sequence(). Note that this
+ sequence is standard for all SDRAM devices, but can include some differences
+ from a device to another. If it is the case, the right sequence should be
+ implemented separately.
+
+ + SDRAM read/write operations
+ o SDRAM external memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_SDRAM_ReadData()/BSP_SDRAM_WriteData(), or by DMA transfer using the functions
+ BSP_SDRAM_ReadData_DMA()/BSP_SDRAM_WriteData_DMA().
+ o The AHB access is performed with 32-bit width transaction, the DMA transfer
+ configuration is fixed at single (no burst) word transfer (see the
+ SDRAM_MspInit() static function).
+ o User can implement his own functions for read/write access with his desired
+ configurations.
+ o If interrupt mode is used for DMA transfer, the function BSP_SDRAM_DMA_IRQHandler()
+ is called in IRQ handler file, to serve the generated interrupt once the DMA
+ transfer is complete.
+ o You can send a command to the SDRAM device in runtime using the function
+ BSP_SDRAM_Sendcmd(), and giving the desired command as parameter chosen between
+ the predefined commands of the "FMC_SDRAM_CommandTypeDef" structure.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* File Info : -----------------------------------------------------------------
+ User NOTES
+1. How To use this driver:
+--------------------------
+ - This driver is used to drive the touch screen module of the STM32F769I-DISCOVERY
+ discoveryuation board on the K.O.D Optica Technology 480x800 TFT-LCD mounted on
+ MB1166 daughter board. The touch screen driver IC inside the K.O.D module KM-040TMP-02
+ is a FT6206 by Focal Tech.
+
+2. Driver description:
+---------------------
+ + Initialization steps:
+ o Initialize the TS module using the BSP_TS_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ communication layer configuration to start the TS use. The LCD size properties
+ (x and y) are passed as parameters.
+ o If TS interrupt mode is desired, you must configure the TS interrupt mode
+ by calling the function BSP_TS_ITConfig(). The TS interrupt mode is generated
+ as an external interrupt whenever a touch is detected.
+ The interrupt mode internally uses the IO functionalities driver driven by
+ the IO expander, to configure the IT line.
+
+ + Touch screen use
+ o The touch screen state is captured whenever the function BSP_TS_GetState() is
+ used. This function returns information about the last LCD touch occurred
+ in the TS_StateTypeDef structure.
+ o The IT is handled using the corresponding external interrupt IRQ handler,
+ the user IT callback treatment is implemented on the same external interrupt
+ callback.
+
+------------------------------------------------------------------------------*/
+
+/* Dependencies
+- stm32f769i_eval_lcd.c
+- ft6x06.c
+EndDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f769i_discovery.h"
+#include "stm32f769i_discovery_ts.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_TS STM32F769I_DISCOVERY TS
+ * @{
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_TS_Private_Types_Definitions TS Private Types Definitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_TS_Private_Defines TS Private Types Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_TS_Private_Macros TS Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_TS_Imported_Variables TS Imported Variables
+ * @{
+ */
+ /**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_TS_Private_Variables TS Private Variables
+ * @{
+ */
+static TS_DrvTypeDef *ts_driver;
+static uint8_t ts_orientation;
+uint8_t I2C_Address = 0;
+
+/* Table for touchscreen event information display on LCD : table indexed on enum @ref TS_TouchEventTypeDef information */
+char * ts_event_string_tab[TOUCH_EVENT_NB_MAX] = { "None",
+ "Press down",
+ "Lift up",
+ "Contact"
+ };
+
+/* Table for touchscreen gesture Id information display on LCD : table indexed on enum @ref TS_GestureIdTypeDef information */
+char * ts_gesture_id_string_tab[GEST_ID_NB_MAX] = { "None",
+ "Move Up",
+ "Move Right",
+ "Move Down",
+ "Move Left",
+ "Zoom In",
+ "Zoom Out"
+ };
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_TS_Private_Function_Prototypes TS Private Function Prototypes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_TS_Public_Functions TS Public Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes and configures the touch screen functionalities and
+ * configures all necessary hardware resources (GPIOs, I2C, clocks..).
+ * @param ts_SizeX : Maximum X size of the TS area on LCD
+ * @param ts_SizeY : Maximum Y size of the TS area on LCD
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_Init(uint16_t ts_SizeX, uint16_t ts_SizeY)
+{
+ uint8_t ts_status = TS_OK;
+ uint8_t ts_id1, ts_id2 = 0;
+ /* Note : I2C_Address is un-initialized here, but is not used at all in init function */
+ /* but the prototype of Init() is like that in template and should be respected */
+
+ /* Initialize the communication channel to sensor (I2C) if necessary */
+ /* that is initialization is done only once after a power up */
+ ft6x06_ts_drv.Init(I2C_Address);
+
+ ts_id1 = ft6x06_ts_drv.ReadID(TS_I2C_ADDRESS);
+ if(ts_id1 != FT6206_ID_VALUE)
+ {
+ ts_id2 = ft6x06_ts_drv.ReadID(TS_I2C_ADDRESS_A02);
+ I2C_Address = TS_I2C_ADDRESS_A02;
+ }
+ else
+ {
+ I2C_Address = TS_I2C_ADDRESS;
+ }
+
+ /* Scan FT6xx6 TouchScreen IC controller ID register by I2C Read */
+ /* Verify this is a FT6206 or FT6336G, otherwise this is an error case */
+ if((ts_id1 == FT6206_ID_VALUE) || (ts_id2 == FT6206_ID_VALUE))
+ {
+ /* Found FT6206 : Initialize the TS driver structure */
+ ts_driver = &ft6x06_ts_drv;
+
+ /* Get LCD chosen orientation */
+ if(ts_SizeX < ts_SizeY)
+ {
+ ts_orientation = TS_SWAP_NONE;
+ }
+ else
+ {
+ ts_orientation = TS_SWAP_XY | TS_SWAP_Y;
+ }
+
+ if(ts_status == TS_OK)
+ {
+ /* Software reset the TouchScreen */
+ ts_driver->Reset(I2C_Address);
+
+ /* Calibrate, Configure and Start the TouchScreen driver */
+ ts_driver->Start(I2C_Address);
+
+ } /* of if(ts_status == TS_OK) */
+ }
+ else
+ {
+ ts_status = TS_DEVICE_NOT_FOUND;
+ }
+
+ return (ts_status);
+}
+
+/**
+ * @brief Configures and enables the touch screen interrupts.
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_ITConfig(void)
+{
+ uint8_t ts_status = TS_OK;
+ GPIO_InitTypeDef gpio_init_structure;
+
+ /* Msp Init of GPIO used for TS_INT pin coming from TouchScreen driver IC FT6x06 */
+ /* When touchscreen is operated in interrupt mode */
+ BSP_TS_INT_MspInit();
+
+ /* Configure Interrupt mode for TS_INT pin falling edge : when a new touch is available */
+ /* TS_INT pin is active on low level on new touch available */
+ gpio_init_structure.Pin = TS_INT_PIN;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_FAST;
+ gpio_init_structure.Mode = GPIO_MODE_IT_FALLING;
+ HAL_GPIO_Init(TS_INT_GPIO_PORT, &gpio_init_structure);
+
+ /* Enable and set the TS_INT EXTI Interrupt to an intermediate priority */
+ HAL_NVIC_SetPriority((IRQn_Type)(TS_INT_EXTI_IRQn), 0x0F, 0x00);
+ HAL_NVIC_EnableIRQ((IRQn_Type)(TS_INT_EXTI_IRQn));
+
+ /* Enable the TS in interrupt mode */
+ /* In that case the INT output of FT6206 when new touch is available */
+ /* is active on low level and directed on EXTI */
+ ts_driver->EnableIT(I2C_Address);
+
+ return (ts_status);
+}
+
+/**
+ * @brief Returns status and positions of the touch screen.
+ * @param TS_State: Pointer to touch screen current state structure
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_GetState(TS_StateTypeDef *TS_State)
+{
+ static uint32_t _x[TS_MAX_NB_TOUCH] = {0, 0};
+ static uint32_t _y[TS_MAX_NB_TOUCH] = {0, 0};
+ uint8_t ts_status = TS_OK;
+ uint16_t tmp;
+ uint16_t Raw_x[TS_MAX_NB_TOUCH];
+ uint16_t Raw_y[TS_MAX_NB_TOUCH];
+ uint16_t xDiff;
+ uint16_t yDiff;
+ uint32_t index;
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+ uint32_t weight = 0;
+ uint32_t area = 0;
+ uint32_t event = 0;
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+ /* Check and update the number of touches active detected */
+ TS_State->touchDetected = ts_driver->DetectTouch(I2C_Address);
+ if(TS_State->touchDetected)
+ {
+ for(index=0; index < TS_State->touchDetected; index++)
+ {
+ /* Get each touch coordinates */
+ ts_driver->GetXY(I2C_Address, &(Raw_x[index]), &(Raw_y[index]));
+
+ if(ts_orientation & TS_SWAP_XY)
+ {
+ tmp = Raw_x[index];
+ Raw_x[index] = Raw_y[index];
+ Raw_y[index] = tmp;
+ }
+
+ if(ts_orientation & TS_SWAP_X)
+ {
+ Raw_x[index] = FT_6206_MAX_WIDTH - 1 - Raw_x[index];
+ }
+
+ if(ts_orientation & TS_SWAP_Y)
+ {
+ Raw_y[index] = FT_6206_MAX_HEIGHT - 1 - Raw_y[index];
+ }
+
+ xDiff = Raw_x[index] > _x[index]? (Raw_x[index] - _x[index]): (_x[index] - Raw_x[index]);
+ yDiff = Raw_y[index] > _y[index]? (Raw_y[index] - _y[index]): (_y[index] - Raw_y[index]);
+
+ if ((xDiff + yDiff) > 5)
+ {
+ _x[index] = Raw_x[index];
+ _y[index] = Raw_y[index];
+ }
+
+
+ TS_State->touchX[index] = _x[index];
+ TS_State->touchY[index] = _y[index];
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+
+ /* Get touch info related to the current touch */
+ ft6x06_TS_GetTouchInfo(I2C_Address, index, &weight, &area, &event);
+
+ /* Update TS_State structure */
+ TS_State->touchWeight[index] = weight;
+ TS_State->touchArea[index] = area;
+
+ /* Remap touch event */
+ switch(event)
+ {
+ case FT6206_TOUCH_EVT_FLAG_PRESS_DOWN :
+ TS_State->touchEventId[index] = TOUCH_EVENT_PRESS_DOWN;
+ break;
+ case FT6206_TOUCH_EVT_FLAG_LIFT_UP :
+ TS_State->touchEventId[index] = TOUCH_EVENT_LIFT_UP;
+ break;
+ case FT6206_TOUCH_EVT_FLAG_CONTACT :
+ TS_State->touchEventId[index] = TOUCH_EVENT_CONTACT;
+ break;
+ case FT6206_TOUCH_EVT_FLAG_NO_EVENT :
+ TS_State->touchEventId[index] = TOUCH_EVENT_NO_EVT;
+ break;
+ default :
+ ts_status = TS_ERROR;
+ break;
+ } /* of switch(event) */
+
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+ } /* of for(index=0; index < TS_State->touchDetected; index++) */
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+ /* Get gesture Id */
+ ts_status = BSP_TS_Get_GestureId(TS_State);
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+ } /* end of if(TS_State->touchDetected != 0) */
+
+ return (ts_status);
+}
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+/**
+ * @brief Update gesture Id following a touch detected.
+ * @param TS_State: Pointer to touch screen current state structure
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_Get_GestureId(TS_StateTypeDef *TS_State)
+{
+ uint32_t gestureId = 0;
+ uint8_t ts_status = TS_OK;
+
+ /* Get gesture Id */
+ ft6x06_TS_GetGestureID(I2C_Address, &gestureId);
+
+ /* Remap gesture Id to a TS_GestureIdTypeDef value */
+ switch(gestureId)
+ {
+ case FT6206_GEST_ID_NO_GESTURE :
+ TS_State->gestureId = GEST_ID_NO_GESTURE;
+ break;
+ case FT6206_GEST_ID_MOVE_UP :
+ TS_State->gestureId = GEST_ID_MOVE_UP;
+ break;
+ case FT6206_GEST_ID_MOVE_RIGHT :
+ TS_State->gestureId = GEST_ID_MOVE_RIGHT;
+ break;
+ case FT6206_GEST_ID_MOVE_DOWN :
+ TS_State->gestureId = GEST_ID_MOVE_DOWN;
+ break;
+ case FT6206_GEST_ID_MOVE_LEFT :
+ TS_State->gestureId = GEST_ID_MOVE_LEFT;
+ break;
+ case FT6206_GEST_ID_ZOOM_IN :
+ TS_State->gestureId = GEST_ID_ZOOM_IN;
+ break;
+ case FT6206_GEST_ID_ZOOM_OUT :
+ TS_State->gestureId = GEST_ID_ZOOM_OUT;
+ break;
+ default :
+ ts_status = TS_ERROR;
+ break;
+ } /* of switch(gestureId) */
+
+ return(ts_status);
+}
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+
+/** @defgroup STM32F769I_DISCOVERY_TS_Private_Functions TS Private Functions
+ * @{
+ */
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+/**
+ * @brief Function used to reset all touch data before a new acquisition
+ * of touch information.
+ * @param TS_State: Pointer to touch screen current state structure
+ * @retval TS_OK if OK, TE_ERROR if problem found.
+ */
+uint8_t BSP_TS_ResetTouchData(TS_StateTypeDef *TS_State)
+{
+ uint8_t ts_status = TS_ERROR;
+ uint32_t index;
+
+ if (TS_State != (TS_StateTypeDef *)NULL)
+ {
+ TS_State->gestureId = GEST_ID_NO_GESTURE;
+ TS_State->touchDetected = 0;
+
+ for(index = 0; index < TS_MAX_NB_TOUCH; index++)
+ {
+ TS_State->touchX[index] = 0;
+ TS_State->touchY[index] = 0;
+ TS_State->touchArea[index] = 0;
+ TS_State->touchEventId[index] = TOUCH_EVENT_NO_EVT;
+ TS_State->touchWeight[index] = 0;
+ }
+
+ ts_status = TS_OK;
+
+ } /* of if (TS_State != (TS_StateTypeDef *)NULL) */
+
+ return (ts_status);
+}
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+/**
+ * @brief Initializes the TS_INT pin MSP.
+ * @retval None
+ */
+__weak void BSP_TS_INT_MspInit(void)
+{
+ GPIO_InitTypeDef gpio_init_structure;
+
+ TS_INT_GPIO_CLK_ENABLE();
+
+ /* GPIO configuration in input for TouchScreen interrupt signal on TS_INT pin */
+ gpio_init_structure.Pin = TS_INT_PIN;
+
+ gpio_init_structure.Mode = GPIO_MODE_INPUT;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_HIGH;
+ HAL_GPIO_Init(TS_INT_GPIO_PORT, &gpio_init_structure);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_ts.h b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_ts.h
new file mode 100644
index 00000000..48343099
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I-Discovery/stm32f769i_discovery_ts.h
@@ -0,0 +1,211 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_discovery_ts.h
+ * @author MCD Application Team
+ * @brief This file contains the common defines and functions prototypes for
+ * the stm32f769i_discovery_ts.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_DISCOVERY_TS_H
+#define __STM32F769I_DISCOVERY_TS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f769i_discovery.h"
+#include "stm32f769i_discovery_lcd.h"
+
+/* Include TouchScreen component driver */
+#include "../Components/ft6x06/ft6x06.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_TS STM32F769I_DISCOVERY TS
+ * @{
+ */
+
+ /** @defgroup STM32F769I_DISCOVERY_TS_Exported_Constants TS Exported Constants
+ * @{
+ */
+/** @brief With FT6206 : maximum 2 touches detected simultaneously
+ */
+#define TS_MAX_NB_TOUCH ((uint32_t) FT6206_MAX_DETECTABLE_TOUCH)
+
+#define TS_NO_IRQ_PENDING ((uint8_t) 0)
+#define TS_IRQ_PENDING ((uint8_t) 1)
+
+#define TS_SWAP_NONE ((uint8_t) 0x01)
+#define TS_SWAP_X ((uint8_t) 0x02)
+#define TS_SWAP_Y ((uint8_t) 0x04)
+#define TS_SWAP_XY ((uint8_t) 0x08)
+
+ /**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_TS_Exported_Types TS Exported Types
+ * @{
+ */
+/**
+* @brief TS_StateTypeDef
+* Define TS State structure
+*/
+typedef struct
+{
+ uint8_t touchDetected; /*!< Total number of active touches detected at last scan */
+ uint16_t touchX[TS_MAX_NB_TOUCH]; /*!< Touch X[0], X[1] coordinates on 12 bits */
+ uint16_t touchY[TS_MAX_NB_TOUCH]; /*!< Touch Y[0], Y[1] coordinates on 12 bits */
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+ uint8_t touchWeight[TS_MAX_NB_TOUCH]; /*!< Touch_Weight[0], Touch_Weight[1] : weight property of touches */
+ uint8_t touchEventId[TS_MAX_NB_TOUCH]; /*!< Touch_EventId[0], Touch_EventId[1] : take value of type @ref TS_TouchEventTypeDef */
+ uint8_t touchArea[TS_MAX_NB_TOUCH]; /*!< Touch_Area[0], Touch_Area[1] : touch area of each touch */
+ uint32_t gestureId; /*!< type of gesture detected : take value of type @ref TS_GestureIdTypeDef */
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+} TS_StateTypeDef;
+
+/**
+ * @brief TS_StatusTypeDef
+ * Define BSP_TS_xxx() functions possible return value,
+ * when status is returned by those functions.
+ */
+typedef enum
+{
+ TS_OK = 0x00, /*!< Touch Ok */
+ TS_ERROR = 0x01, /*!< Touch Error */
+ TS_TIMEOUT = 0x02, /*!< Touch Timeout */
+ TS_DEVICE_NOT_FOUND = 0x03 /*!< Touchscreen device not found */
+} TS_StatusTypeDef;
+
+/**
+ * @brief TS_GestureIdTypeDef
+ * Define Possible managed gesture identification values returned by touch screen
+ * driver.
+ */
+typedef enum
+{
+ GEST_ID_NO_GESTURE = 0x00, /*!< Gesture not defined / recognized */
+ GEST_ID_MOVE_UP = 0x01, /*!< Gesture Move Up */
+ GEST_ID_MOVE_RIGHT = 0x02, /*!< Gesture Move Right */
+ GEST_ID_MOVE_DOWN = 0x03, /*!< Gesture Move Down */
+ GEST_ID_MOVE_LEFT = 0x04, /*!< Gesture Move Left */
+ GEST_ID_ZOOM_IN = 0x05, /*!< Gesture Zoom In */
+ GEST_ID_ZOOM_OUT = 0x06, /*!< Gesture Zoom Out */
+ GEST_ID_NB_MAX = 0x07 /*!< max number of gesture id */
+} TS_GestureIdTypeDef;
+
+/**
+ * @brief TS_TouchEventTypeDef
+ * Define Possible touch events kind as returned values
+ * by touch screen IC Driver.
+ */
+typedef enum
+{
+ TOUCH_EVENT_NO_EVT = 0x00, /*!< Touch Event : undetermined */
+ TOUCH_EVENT_PRESS_DOWN = 0x01, /*!< Touch Event Press Down */
+ TOUCH_EVENT_LIFT_UP = 0x02, /*!< Touch Event Lift Up */
+ TOUCH_EVENT_CONTACT = 0x03, /*!< Touch Event Contact */
+ TOUCH_EVENT_NB_MAX = 0x04 /*!< max number of touch events kind */
+} TS_TouchEventTypeDef;
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F769I_DISCOVERY_TS_Imported_Variables
+ * @{
+ */
+/**
+ * @brief Table for touchscreen event information display on LCD :
+ * table indexed on enum @ref TS_TouchEventTypeDef information
+ */
+extern char * ts_event_string_tab[TOUCH_EVENT_NB_MAX];
+
+/**
+ * @brief Table for touchscreen gesture Id information display on LCD : table indexed
+ * on enum @ref TS_GestureIdTypeDef information
+ */
+extern char * ts_gesture_id_string_tab[GEST_ID_NB_MAX];
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_DISCOVERY_TS_Exported_Functions TS Exported Functions
+ * @{
+ */
+uint8_t BSP_TS_Init(uint16_t ts_SizeX, uint16_t ts_SizeY);
+uint8_t BSP_TS_GetState(TS_StateTypeDef *TS_State);
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+uint8_t BSP_TS_Get_GestureId(TS_StateTypeDef *TS_State);
+uint8_t BSP_TS_ResetTouchData(TS_StateTypeDef *TS_State);
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+uint8_t BSP_TS_ITConfig(void);
+
+/* These __weak function can be surcharged by application code in case the current settings
+ need to be changed for specific (example GPIO allocation) */
+void BSP_TS_INT_MspInit(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_DISCOVERY_TS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/Release_Notes.html b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/Release_Notes.html
new file mode 100644
index 00000000..86c852a8
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/Release_Notes.html
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+ Release Notes for STM32F769I-EVAL BSP Drivers
+
+
+
+
+
+
+This software component is licensed by ST under BSD 3-Clause license, the “License”; You may not use this component except in compliance with the License. You may obtain a copy of the License at:
+
The BSP (Board Specific Package) drivers are parts of the STM32Cube package based on the HAL drivers and provide a set of high level APIs relative to the hardware components and features in the evaluation boards, discovery kits and nucleo boards coming with the STM32Cube package for a given STM32 serie.
+
The BSP drivers allow a quick access to the boards’ services using high level APIs and without any specific configuration as the link with the HAL and the external components is done in intrinsic within the drivers.
+
From project settings points of view, user has only to add the necessary driver’s files in the workspace and call the needed functions from examples. However some low level configuration functions are weak and can be overridden by the applications if user wants to change some BSP drivers default behavior.
+
+
+
Update History
+
+
+
+
Main Changes
+
+
stm32f769i_eval_camera.c/.h:
+
+
Support ov5640 camera sensor
+
+
stm32f769i_eval.c/.h:
+
+
Add OV5640 I2C address
+
Update CAMERA IO Read/Write to support ov5640 camera sensor
+
+
+
+
+
+
+
+
Main Changes
+
+
stm32f769i_eval_lcd.c:
+
+
Fix compilation errors with SW4STM32 toolchain.
+
+
stm32f769i_eval.c:
+
+
Upgrade version to v2.0.2
+
+
+
+
+
+
+
+
Main Changes
+
+
Add general description of BSP drivers
+
Add Dependencies section
+
Support of PDSC
+
+
+
+
+
+
+
Main Changes
+
+
stm32f769i_eval_sd.c/.h:
+
+
Update BSP SD APIs following new HAL SD drivers implementation
+
Fix BlockSize to 512 bytes
+
+
stm32f769i_eval_ts.c/.h:
+
+
Support of FT6336G Touch Screen
+
+
stm32f769i_eval_lcd.c/.h:
+
+
Update BSP_LCD_ReadPixel to read correctely ARGB8888 and RGB888 pixels
+
+
stm32f769i_eval_qspi.c/.h:
+
+
QSPI write operation improvement
+
Update CS High Time
+
+
+
Backward compatibility
+
+
These BSP drivers break the compatibility with previous versions.
+
+
Dependencies
+
+
If FatFs is required, “FatFS R0.11 ST modified 20161223” must be used with this version of BSP drivers.
+
+
+
+
+
+
+
Main Changes
+
+
stm32f769i_eval_lcd.c/.h:
+
+
Support of HDMI video features
+
Update DSI initialization
+
Update LTDC clock value
+
Update LCD_DSI_PIXEL_DATA_FMT_RBG888 and LCD_DSI_PIXEL_DATA_FMT_RBG565 values
+
+
stm32f769i_eval_audio.c/.h:
+
+
Support of HDMI audio features
+
+
+
+
+
+
+
+
Main Changes
+
+
Update typos in drivers comments.
+
+
+
+
+
+
+
Main Changes
+
+
First official release of the STM32F769I-EVAL and STM32F779I-EVAL BSP drivers
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_EVAL_H
+#define __STM32F769I_EVAL_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL_LOW_LEVEL
+ * @{
+ */
+
+/** @defgroup STM32F769I_EVAL_LOW_LEVEL_Exported_Types LOW LEVEL Exported Types
+ * @{
+ */
+typedef enum
+{
+LED1 = 0,
+LED_GREEN = LED1,
+LED2 = 1,
+LED_ORANGE = LED2,
+LED3 = 2,
+LED_RED = LED3,
+LED4 = 3,
+LED_BLUE = LED4
+}Led_TypeDef;
+
+typedef enum
+{
+ BUTTON_WAKEUP = 0,
+ BUTTON_TAMPER = 1,
+ BUTTON_KEY = 2
+}Button_TypeDef;
+
+typedef enum
+{
+ BUTTON_MODE_GPIO = 0,
+ BUTTON_MODE_EXTI = 1
+}ButtonMode_TypeDef;
+
+#if defined(USE_IOEXPANDER)
+typedef enum
+{
+ JOY_MODE_GPIO = 0,
+ JOY_MODE_EXTI = 1
+}JOYMode_TypeDef;
+
+typedef enum
+{
+ JOY_NONE = 0,
+ JOY_SEL = 1,
+ JOY_DOWN = 2,
+ JOY_LEFT = 3,
+ JOY_RIGHT = 4,
+ JOY_UP = 5
+}JOYState_TypeDef;
+#endif /* USE_IOEXPANDER */
+
+typedef enum
+{
+ COM1 = 0,
+ COM2 = 1
+}COM_TypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_LOW_LEVEL_Exported_Constants LOW LEVEL Exported Constants
+ * @{
+ */
+
+/**
+ * @brief Define for STM32F769I_EVAL board
+ */
+#if !defined (USE_STM32F769I_EVAL)
+ #define USE_STM32F769I_EVAL
+#endif
+
+/** @addtogroup STM32F769I_EVAL_LOW_LEVEL_LED EVAL LOW LEVEL LED
+ * @{
+ */
+#define LEDn ((uint32_t)4)
+
+#define LED1_GPIO_PORT GPIOI
+#define LED1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define LED1_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define LED1_PIN GPIO_PIN_15
+
+#define LED2_GPIO_PORT GPIOJ
+#define LED2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE()
+#define LED2_GPIO_CLK_DISABLE() __HAL_RCC_GPIOJ_CLK_DISABLE()
+#define LED2_PIN GPIO_PIN_0
+
+#define LED3_GPIO_PORT GPIOJ
+#define LED3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE()
+#define LED3_GPIO_CLK_DISABLE() __HAL_RCC_GPIOJ_CLK_DISABLE()
+#define LED3_PIN GPIO_PIN_1
+
+#define LED4_GPIO_PORT GPIOJ
+#define LED4_GPIO_CLK_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE()
+#define LED4_GPIO_CLK_DISABLE() __HAL_RCC_GPIOJ_CLK_DISABLE()
+#define LED4_PIN GPIO_PIN_3
+
+#define LEDx_GPIO_CLK_ENABLE(__INDEX__) do{if((__INDEX__) == 0) LED1_GPIO_CLK_ENABLE(); else \
+ if((__INDEX__) == 1) LED2_GPIO_CLK_ENABLE(); else \
+ if((__INDEX__) == 2) LED3_GPIO_CLK_ENABLE(); else \
+ if((__INDEX__) == 3) LED4_GPIO_CLK_ENABLE(); \
+ }while(0)
+
+#define LEDx_GPIO_CLK_DISABLE(__INDEX__) do{if((__INDEX__) == 0) LED1_GPIO_CLK_DISABLE(); else \
+ if((__INDEX__) == 1) LED2_GPIO_CLK_DISABLE(); else \
+ if((__INDEX__) == 2) LED3_GPIO_CLK_DISABLE(); else \
+ if((__INDEX__) == 3) LED4_GPIO_CLK_DISABLE(); \
+ }while(0)
+
+/**
+ * @}
+ */
+
+/**
+ * @brief MFX_IRQOUt pin
+ */
+#define MFX_IRQOUT_PIN GPIO_PIN_8
+#define MFX_IRQOUT_GPIO_PORT GPIOI
+#define MFX_IRQOUT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define MFX_IRQOUT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define MFX_IRQOUT_EXTI_IRQn EXTI9_5_IRQn
+
+/** @addtogroup STM32F769I_EVAL_LOW_LEVEL_BUTTON LOW LEVEL BUTTON
+ * @{
+ */
+/* Joystick pins are connected to IO Expander (accessible through I2C1 interface) */
+#define BUTTONn ((uint8_t)3)
+
+/**
+ * @brief Wakeup push-button
+ */
+#define WAKEUP_BUTTON_PIN GPIO_PIN_13
+#define WAKEUP_BUTTON_GPIO_PORT GPIOC
+#define WAKEUP_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define WAKEUP_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
+#define WAKEUP_BUTTON_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @brief Tamper push-button
+ */
+#define TAMPER_BUTTON_PIN GPIO_PIN_13
+#define TAMPER_BUTTON_GPIO_PORT GPIOC
+#define TAMPER_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define TAMPER_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
+#define TAMPER_BUTTON_EXTI_IRQn EXTI15_10_IRQn
+
+/**
+ * @brief Key push-button
+ */
+#define KEY_BUTTON_PIN GPIO_PIN_13
+#define KEY_BUTTON_GPIO_PORT GPIOC
+#define KEY_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define KEY_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
+#define KEY_BUTTON_EXTI_IRQn EXTI15_10_IRQn
+
+#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == 0) WAKEUP_BUTTON_GPIO_CLK_ENABLE(); else\
+ if((__INDEX__) == 1) TAMPER_BUTTON_GPIO_CLK_ENABLE(); else\
+ KEY_BUTTON_GPIO_CLK_ENABLE(); } while(0)
+
+#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? WAKEUP_BUTTON_GPIO_CLK_DISABLE() :\
+ ((__INDEX__) == 1) ? TAMPER_BUTTON_GPIO_CLK_DISABLE() : KEY_BUTTON_GPIO_CLK_DISABLE())
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F769I_EVAL_LOW_LEVEL_COM LOW LEVEL COM
+ * @{
+ */
+#define COMn ((uint8_t)1)
+
+/**
+ * @brief Definition for COM port1, connected to USART1
+ */
+#define EVAL_COM1 USART1
+#define EVAL_COM1_CLK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE()
+#define EVAL_COM1_CLK_DISABLE() __HAL_RCC_USART1_CLK_DISABLE()
+
+#define EVAL_COM1_TX_PIN GPIO_PIN_9
+#define EVAL_COM1_TX_GPIO_PORT GPIOA
+#define EVAL_COM1_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define EVAL_COM1_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define EVAL_COM1_TX_AF GPIO_AF7_USART1
+
+#define EVAL_COM1_RX_PIN GPIO_PIN_10
+#define EVAL_COM1_RX_GPIO_PORT GPIOA
+#define EVAL_COM1_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define EVAL_COM1_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define EVAL_COM1_RX_AF GPIO_AF7_USART1
+
+#define EVAL_COM1_IRQn USART1_IRQn
+
+#define EVAL_COMx_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) EVAL_COM1_CLK_ENABLE(); } while(0)
+#define EVAL_COMx_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? EVAL_COM1_CLK_DISABLE() : 0)
+
+#define EVAL_COMx_TX_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) EVAL_COM1_TX_GPIO_CLK_ENABLE(); } while(0)
+#define EVAL_COMx_TX_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? EVAL_COM1_TX_GPIO_CLK_DISABLE() : 0)
+
+#define EVAL_COMx_RX_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == COM1) EVAL_COM1_RX_GPIO_CLK_ENABLE(); } while(0)
+#define EVAL_COMx_RX_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? EVAL_COM1_RX_GPIO_CLK_DISABLE() : 0)
+
+/**
+ * @brief Definition for Potentiometer, connected to ADC3
+ */
+#define ADCx ADC3
+#define ADCx_CLK_ENABLE() __HAL_RCC_ADC3_CLK_ENABLE()
+#define ADCx_CHANNEL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
+
+#define ADCx_FORCE_RESET() __HAL_RCC_ADC_FORCE_RESET()
+#define ADCx_RELEASE_RESET() __HAL_RCC_ADC_RELEASE_RESET()
+
+/* Definition for ADCx Channel Pin */
+#define ADCx_CHANNEL_PIN GPIO_PIN_10
+#define ADCx_CHANNEL_GPIO_PORT GPIOF
+
+/* Definition for ADCx's Channel */
+#define ADCx_CHANNEL ADC_CHANNEL_8
+#define SAMPLINGTIME ADC_SAMPLETIME_3CYCLES
+#define ADCx_POLL_TIMEOUT 10
+
+/**
+ * @brief Joystick Pins definition
+ */
+#if defined(USE_IOEXPANDER)
+#define JOY_SEL_PIN IO_PIN_0
+#define JOY_DOWN_PIN IO_PIN_1
+#define JOY_LEFT_PIN IO_PIN_2
+#define JOY_RIGHT_PIN IO_PIN_3
+#define JOY_UP_PIN IO_PIN_4
+#define JOY_NONE_PIN JOY_ALL_PINS
+#define JOY_ALL_PINS (IO_PIN_0 | IO_PIN_1 | IO_PIN_2 | IO_PIN_3 | IO_PIN_4)
+#endif /* USE_IOEXPANDER */
+/**
+ * @brief Eval Pins definition connected to MFX
+ */
+
+#if defined(USE_IOEXPANDER)
+#define XSDN_PIN IO_PIN_16
+#define MII_INT_PIN IO_PIN_13
+#define RSTI_PIN IO_PIN_11
+#define CAM_PLUG_PIN IO_PIN_12
+#define TS_INT_PIN IO_PIN_14
+#define AUDIO_INT_PIN IO_PIN_5
+#define OTG_FS1_OVER_CURRENT_PIN IO_PIN_6
+#define OTG_FS1_POWER_SWITCH_PIN IO_PIN_7
+#define OTG_FS2_OVER_CURRENT_PIN IO_PIN_8
+#define OTG_FS2_POWER_SWITCH_PIN IO_PIN_9
+#define SD1_DETECT_PIN IO_PIN_15
+#define SD2_DETECT_PIN IO_PIN_10
+#define SD_DETECT_PIN SD1_DETECT_PIN
+#endif /* USE_IOEXPANDER */
+
+
+/* Exported constant IO ------------------------------------------------------*/
+
+/* The MFX_I2C_ADDR input pin selects the MFX I2C device address
+ MFX_I2C_ADDR input pin MFX I2C device address
+ 0 b: 1000 010x (0x84)
+ 1 b: 1000 011x (0x86)
+ This input is sampled during the MFX firmware startup. */
+#define IO_I2C_ADDRESS ((uint16_t)0x84) /*mfx MFX_I2C_ADDR 0*/
+#define IO_I2C_ADDRESS_2 ((uint16_t)0x86) /*mfx MFX_I2C_ADDR 1*/
+/**
+ * @brief TouchScreen FT6206 Slave I2C address 1
+ */
+#define TS_I2C_ADDRESS ((uint16_t)0x54)
+
+/**
+ * @brief TouchScreen FT6336G Slave I2C address 2
+ */
+#define TS_I2C_ADDRESS_A02 ((uint16_t)0x70)
+
+/**
+ * @brief LCD DSI Slave I2C address 1
+ */
+#define LCD_DSI_ADDRESS TS_I2C_ADDRESS
+
+/**
+ * @brief LCD DSI Slave I2C address 2
+ */
+#define LCD_DSI_ADDRESS_A02 TS_I2C_ADDRESS_A02
+
+#define CAMERA_I2C_ADDRESS ((uint16_t)0x5A)
+#define CAMERA_I2C_ADDRESS_2 ((uint16_t)0x78)
+#define AUDIO_I2C_ADDRESS ((uint16_t)0x34)
+#define EEPROM_I2C_ADDRESS_A01 ((uint16_t)0xA0)
+#define EEPROM_I2C_ADDRESS_A02 ((uint16_t)0xA6)
+/* I2C clock speed configuration (in Hz)
+ WARNING:
+ Make sure that this define is not already declared in other files (ie.
+ stm32f769i_eval.h file). It can be used in parallel by other modules. */
+#ifndef I2C_SPEED
+ #define I2C_SPEED ((uint32_t)100000)
+#endif /* I2C_SPEED */
+
+/* User can use this section to tailor I2Cx/I2Cx instance used and associated
+ resources */
+/* Definition for I2Cx clock resources */
+#define EVAL_I2Cx I2C1
+#define EVAL_I2Cx_CLK_ENABLE() __HAL_RCC_I2C1_CLK_ENABLE()
+#define EVAL_DMAx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
+#define EVAL_I2Cx_SCL_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+
+#define EVAL_I2Cx_FORCE_RESET() __HAL_RCC_I2C1_FORCE_RESET()
+#define EVAL_I2Cx_RELEASE_RESET() __HAL_RCC_I2C1_RELEASE_RESET()
+
+/* Definition for I2Cx Pins */
+#define EVAL_I2Cx_SCL_PIN GPIO_PIN_8
+#define EVAL_I2Cx_SCL_SDA_GPIO_PORT GPIOB
+#define EVAL_I2Cx_SCL_SDA_AF GPIO_AF4_I2C1
+#define EVAL_I2Cx_SDA_PIN GPIO_PIN_9
+
+/* I2C interrupt requests */
+#define EVAL_I2Cx_EV_IRQn I2C1_EV_IRQn
+#define EVAL_I2Cx_ER_IRQn I2C1_ER_IRQn
+
+/* I2C TIMING Register define when I2C clock source is SYSCLK */
+/* I2C TIMING is calculated from APB1 source clock = 50 MHz */
+/* Due to the big MOFSET capacity for adapting the camera level the rising time is very large (>1us) */
+/* 0x40912732 takes in account the big rising and aims a clock of 100khz */
+#ifndef EVAL_I2Cx_TIMING
+#define EVAL_I2Cx_TIMING ((uint32_t)0x40912732)
+#endif /* EVAL_I2Cx_TIMING */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_LOW_LEVEL_Exported_Macros LOW LEVEL Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_LOW_LEVEL_Exported_Functions LOW LEVEL Exported Functions
+ * @{
+ */
+uint32_t BSP_GetVersion(void);
+void BSP_LED_Init(Led_TypeDef Led);
+void BSP_LED_DeInit(Led_TypeDef Led);
+void BSP_LED_On(Led_TypeDef Led);
+void BSP_LED_Off(Led_TypeDef Led);
+void BSP_LED_Toggle(Led_TypeDef Led);
+void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode);
+void BSP_PB_DeInit(Button_TypeDef Button);
+uint32_t BSP_PB_GetState(Button_TypeDef Button);
+void BSP_COM_Init(COM_TypeDef COM, UART_HandleTypeDef *husart);
+void BSP_COM_DeInit(COM_TypeDef COM, UART_HandleTypeDef *huart);
+void BSP_POTENTIOMETER_Init(void);
+uint32_t BSP_POTENTIOMETER_GetLevel(void);
+#if defined(USE_IOEXPANDER)
+uint8_t BSP_JOY_Init(JOYMode_TypeDef JoyMode);
+void BSP_JOY_DeInit(void);
+JOYState_TypeDef BSP_JOY_GetState(void);
+#endif /* USE_IOEXPANDER */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_EVAL_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_audio.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_audio.c
new file mode 100644
index 00000000..e922093d
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_audio.c
@@ -0,0 +1,1642 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_eval_audio.c
+ * @author MCD Application Team
+ * @brief This file provides the Audio driver for the STM32F769I-EVAL
+ * evaluation board.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ + This driver supports STM32F7xx devices on STM32F769I-EVAL (MB1219) Evaluation boards.
+ + Call the function BSP_AUDIO_OUT_Init(
+ OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER,
+ OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
+ Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
+ AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...)
+ this parameter is relative to the audio file/stream type.
+ )
+ This function configures all the hardware required for the audio application (codec, I2C, SAI,
+ GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
+ If the returned value is different from AUDIO_OK or the function is stuck then the communication with
+ the codec or the MFX has failed (try to un-plug the power or reset device in this case).
+ - OUTPUT_DEVICE_SPEAKER : only speaker will be set as output for the audio stream.
+ - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
+ - OUTPUT_DEVICE_BOTH : both Speaker and Headphone are used as outputs for the audio stream
+ at the same time.
+ Note. On STM32F769I-EVAL SAI_DMA is configured in CIRCULAR mode. Due to this the application
+ does NOT need to call BSP_AUDIO_OUT_ChangeBuffer() to assure streaming.
+ + Call the function BSP_EVAL_AUDIO_OUT_Play(
+ pBuffer: pointer to the audio data file address
+ Size : size of the buffer to be sent in Bytes
+ )
+ to start playing (for the first time) from the audio file/stream.
+ + Call the function BSP_AUDIO_OUT_Pause() to pause playing
+ + Call the function BSP_AUDIO_OUT_Resume() to resume playing.
+ Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
+ for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
+ Note. This function should be called only when the audio file is played or paused (not stopped).
+ + For each mode, you may need to implement the relative callback functions into your code.
+ The Callback functions are named AUDIO_OUT_XXX_CallBack() and only their prototypes are declared in
+ the stm32f769i_eval_audio.h file. (refer to the example for more details on the callbacks implementations)
+ + To Stop playing, to modify the volume level, the frequency, the audio frame slot,
+ the device output mode the mute or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(),
+ AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetAudioFrameSlot(), BSP_AUDIO_OUT_SetOutputMode(),
+ BSP_AUDIO_OUT_SetMute() and BSP_AUDIO_OUT_Stop().
+ + The driver API and the callback functions are at the end of the stm32f769i_eval_audio.h file.
+
+ Driver architecture:
+ --------------------
+ + This driver provides the High Audio Layer: consists of the function API exported in the stm32f769i_eval_audio.h file
+ (BSP_AUDIO_OUT_Init(), BSP_AUDIO_OUT_Play() ...)
+ + This driver provide also the Media Access Layer (MAL): which consists of functions allowing to access the media containing/
+ providing the audio file/stream. These functions are also included as local functions into
+ the stm32f769i_eval_audio_codec.c file (DFSDMx_Init(), DFSDMx_DeInit(), SAIx_Init() and SAIx_DeInit())
+
+ Known Limitations:
+ ------------------
+ 1- If the TDM Format used to play in parallel 2 audio Stream (the first Stream is configured in codec SLOT0 and second
+ Stream in SLOT1) the Pause/Resume, volume and mute feature will control the both streams.
+ 2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size,
+ File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
+ 3- Supports only Stereo audio streaming.
+ 4- Supports only 16-bits audio data size.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_EVAL_AUDIO_H
+#define __STM32F769I_EVAL_AUDIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include audio component Driver */
+#include "../Components/wm8994/wm8994.h"
+
+#if defined(USE_LCD_HDMI)
+/* Include ADV7533 HDMI Driver IC driver code */
+#include "../Components/adv7533/adv7533.h"
+#endif /* USE_LCD_HDMI */
+
+#include "stm32f769i_eval.h"
+#include
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL_AUDIO
+ * @{
+ */
+
+/** @defgroup STM32F769I_EVAL_AUDIO_Exported_Types STM32F769I_EVAL_AUDIO Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_AUDIO_Exported_Constants STM32F769I_EVAL_AUDIO Exported Constants
+ * @{
+ */
+
+/** @defgroup BSP_Audio_Out_Option BSP Audio Out Option
+ * @{
+ */
+#define BSP_AUDIO_OUT_CIRCULARMODE ((uint32_t)0x00000001) /* BUFFER CIRCULAR MODE */
+#define BSP_AUDIO_OUT_NORMALMODE ((uint32_t)0x00000002) /* BUFFER NORMAL MODE */
+#define BSP_AUDIO_OUT_STEREOMODE ((uint32_t)0x00000004) /* STEREO MODE */
+#define BSP_AUDIO_OUT_MONOMODE ((uint32_t)0x00000008) /* MONO MODE */
+/**
+ * @}
+ */
+/** @defgroup BSP_Audio_Sample_Rate BSP Audio Sample Rate
+ * @{
+ */
+#define BSP_AUDIO_FREQUENCY_96K SAI_AUDIO_FREQUENCY_96K
+#define BSP_AUDIO_FREQUENCY_48K SAI_AUDIO_FREQUENCY_48K
+#define BSP_AUDIO_FREQUENCY_44K SAI_AUDIO_FREQUENCY_44K
+#define BSP_AUDIO_FREQUENCY_32K SAI_AUDIO_FREQUENCY_32K
+#define BSP_AUDIO_FREQUENCY_22K SAI_AUDIO_FREQUENCY_22K
+#define BSP_AUDIO_FREQUENCY_16K SAI_AUDIO_FREQUENCY_16K
+#define BSP_AUDIO_FREQUENCY_11K SAI_AUDIO_FREQUENCY_11K
+#define BSP_AUDIO_FREQUENCY_8K SAI_AUDIO_FREQUENCY_8K
+/**
+ * @}
+ */
+
+/*------------------------------------------------------------------------------
+ USER SAI defines parameters
+ -----------------------------------------------------------------------------*/
+/** CODEC_AudioFrame_SLOT_TDMMode In W8994 codec the Audio frame contains 4 slots : TDM Mode
+ * TDM format :
+ * +------------------|------------------|--------------------|-------------------+
+ * | CODEC_SLOT0 Left | CODEC_SLOT1 Left | CODEC_SLOT0 Right | CODEC_SLOT1 Right |
+ * +------------------------------------------------------------------------------+
+ */
+/* To have 2 separate audio stream in Both headphone and speaker the 4 slot must be activated */
+#define CODEC_AUDIOFRAME_SLOT_0123 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_2 | SAI_SLOTACTIVE_3
+/* To have an audio stream in headphone only SAI Slot 0 and Slot 2 must be activated */
+#define CODEC_AUDIOFRAME_SLOT_02 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_2
+/* To have an audio stream in speaker only SAI Slot 1 and Slot 3 must be activated */
+#define CODEC_AUDIOFRAME_SLOT_13 SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_3
+
+/* SAI peripheral configuration defines */
+#define AUDIO_SAIx SAI2_Block_B
+#define AUDIO_SAIx_CLK_ENABLE() __HAL_RCC_SAI2_CLK_ENABLE()
+#define AUDIO_SAIx_CLK_DISABLE() __HAL_RCC_SAI2_CLK_DISABLE()
+#define AUDIO_SAIx_SCK_AF GPIO_AF8_SAI2
+#define AUDIO_SAIx_FS_SD_MCLK_AF GPIO_AF10_SAI2
+
+#define AUDIO_SAIx_MCLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
+#define AUDIO_SAIx_MCLK_GPIO_PORT GPIOE
+#define AUDIO_SAIx_MCLK_PIN GPIO_PIN_6
+#define AUDIO_SAIx_SCK_SD_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define AUDIO_SAIx_SCK_SD_GPIO_PORT GPIOA
+#define AUDIO_SAIx_SCK_PIN GPIO_PIN_2
+#define AUDIO_SAIx_SD_PIN GPIO_PIN_0
+#define AUDIO_SAIx_FS_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
+#define AUDIO_SAIx_FS_GPIO_PORT GPIOG
+#define AUDIO_SAIx_FS_PIN GPIO_PIN_9
+
+
+/* SAI DMA Stream definitions */
+#define AUDIO_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
+#define AUDIO_SAIx_DMAx_STREAM DMA2_Stream6
+#define AUDIO_SAIx_DMAx_CHANNEL DMA_CHANNEL_3
+#define AUDIO_SAIx_DMAx_IRQ DMA2_Stream6_IRQn
+#define AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
+#define AUDIO_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
+#define DMA_MAX_SZE 0xFFFF
+
+#define AUDIO_SAIx_DMAx_IRQHandler DMA2_Stream6_IRQHandler
+
+/* Select the interrupt preemption priority for the DMA interrupt */
+#define AUDIO_OUT_IRQ_PREPRIO ((uint32_t)0x0E)
+
+/*------------------------------------------------------------------------------
+ AUDIO IN CONFIGURATION
+------------------------------------------------------------------------------*/
+/* DFSDM Configuration defines */
+#define AUDIO_DFSDMx_LEFT_CHANNEL DFSDM_CHANNEL_1
+#define AUDIO_DFSDMx_RIGHT_CHANNEL DFSDM_CHANNEL_0
+#define AUDIO_DFSDMx_LEFT_FILTER DFSDM1_Filter0
+#define AUDIO_DFSDMx_RIGHT_FILTER DFSDM1_Filter1
+#define AUDIO_DFSDMx_CLK_ENABLE() __HAL_RCC_DFSDM_CLK_ENABLE()
+#define AUDIO_DFSDMx_CKOUT_PIN GPIO_PIN_3
+#define AUDIO_DFSDMx_DMIC_DATIN_PIN GPIO_PIN_6
+#define AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT GPIOD
+#define AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
+#define AUDIO_DFSDMx_DMIC_DATIN_AF GPIO_AF10_DFSDM1
+#define AUDIO_DFSDMx_CKOUT_AF GPIO_AF3_DFSDM1
+
+/* DFSDM DMA Right and Left channels definitions */
+#define AUDIO_DFSDMx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
+#define AUDIO_DFSDMx_DMAx_LEFT_CHANNEL DMA_CHANNEL_8
+#define AUDIO_DFSDMx_DMAx_RIGHT_CHANNEL DMA_CHANNEL_8
+#define AUDIO_DFSDMx_DMAx_LEFT_IRQ DMA2_Stream0_IRQn
+#define AUDIO_DFSDMx_DMAx_RIGHT_IRQ DMA2_Stream5_IRQn
+#define AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_WORD
+#define AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_WORD
+
+#define AUDIO_DFSDM_DMAx_LEFT_IRQHandler DMA2_Stream0_IRQHandler
+#define AUDIO_DFSDM_DMAx_RIGHT_IRQHandler DMA2_Stream5_IRQHandler
+
+/* Select the interrupt preemption priority and subpriority for the IT/DMA interrupt */
+#define AUDIO_IN_IRQ_PREPRIO ((uint32_t)0x0F)
+
+
+/*------------------------------------------------------------------------------
+ CONFIGURATION: Audio Driver Configuration parameters
+------------------------------------------------------------------------------*/
+
+#define AUDIODATA_SIZE 2 /* 16-bits audio data size */
+
+/* Audio status definition */
+#define AUDIO_OK ((uint8_t)0)
+#define AUDIO_ERROR ((uint8_t)1)
+#define AUDIO_TIMEOUT ((uint8_t)2)
+
+/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */
+#define DEFAULT_AUDIO_IN_FREQ I2S_AUDIOFREQ_16K
+#define DEFAULT_AUDIO_IN_BIT_RESOLUTION ((uint8_t)16)
+#define DEFAULT_AUDIO_IN_CHANNEL_NBR ((uint8_t)2) /* Mono = 1, Stereo = 2 */
+#define DEFAULT_AUDIO_IN_VOLUME ((uint16_t)64)
+
+/*------------------------------------------------------------------------------
+ OPTIONAL Configuration defines parameters
+------------------------------------------------------------------------------*/
+
+/* Delay for the Codec to be correctly reset */
+#define CODEC_RESET_DELAY ((uint8_t)5)
+
+
+/*------------------------------------------------------------------------------
+ OUTPUT DEVICES definition
+------------------------------------------------------------------------------*/
+/* Alias on existing output devices to adapt for 2 headphones output */
+#define OUTPUT_DEVICE_HEADPHONE1 OUTPUT_DEVICE_HEADPHONE
+#define OUTPUT_DEVICE_HEADPHONE2 OUTPUT_DEVICE_SPEAKER /* Headphone2 is connected to Speaker output of the wm8994 */
+#define OUTPUT_DEVICE_HDMI OUTPUT_DEVICE_ADV7533_HDMI
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_AUDIO_Exported_Variables STM32F769I_EVAL_AUDIO Exported Variables
+ * @{
+ */
+ /**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_AUDIO_Exported_Macros STM32F769I_EVAL_AUDIO Exported Macros
+ * @{
+ */
+#define DMA_MAX(x) (((x) <= DMA_MAX_SZE)? (x):DMA_MAX_SZE)
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_AUDIO_OUT_Exported_Functions STM32F769I_EVAL_AUDIO_OUT Exported Functions
+ * @{
+ */
+uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq);
+void BSP_AUDIO_OUT_DeInit(void);
+uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size);
+void BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size);
+uint8_t BSP_AUDIO_OUT_Pause(void);
+uint8_t BSP_AUDIO_OUT_Resume(void);
+uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option);
+uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume);
+void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq);
+void BSP_AUDIO_OUT_SetAudioFrameSlot(uint32_t AudioFrameSlot);
+uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd);
+uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output);
+
+/* User Callbacks: user has to implement these functions in his code if they are needed. */
+/* This function is called when the requested data has been completely transferred.*/
+void BSP_AUDIO_OUT_TransferComplete_CallBack(void);
+
+/* This function is called when half of the requested buffer has been transferred. */
+void BSP_AUDIO_OUT_HalfTransfer_CallBack(void);
+
+/* This function is called when an Interrupt due to transfer error on or peripheral
+ error occurs. */
+void BSP_AUDIO_OUT_Error_CallBack(void);
+
+/* These function can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_AUDIO_OUT_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params);
+void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params);
+void BSP_AUDIO_OUT_MspDeInit(SAI_HandleTypeDef *hsai, void *Params);
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_AUDIO_IN_Exported_Functions STM32F769I_EVAL_AUDIO_IN Exported Functions
+ * @{
+ */
+uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_AllocScratch (int32_t *pScratch, uint32_t size);
+void BSP_AUDIO_IN_DeInit(void);
+uint8_t BSP_AUDIO_IN_Record(uint16_t *pData, uint32_t Size);
+uint8_t BSP_AUDIO_IN_Stop(void);
+uint8_t BSP_AUDIO_IN_Pause(void);
+uint8_t BSP_AUDIO_IN_Resume(void);
+
+/* User Callbacks: user has to implement these functions in his code if they are needed. */
+/* This function should be implemented by the user application.
+ It is called into this driver when the current buffer is filled to prepare the next
+ buffer pointer and its size. */
+void BSP_AUDIO_IN_TransferComplete_CallBack(void);
+void BSP_AUDIO_IN_HalfTransfer_CallBack(void);
+
+/* This function is called when an Interrupt due to transfer error on or peripheral
+ error occurs. */
+void BSP_AUDIO_IN_Error_Callback(void);
+
+/* These function can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_AUDIO_IN_ClockConfig(DFSDM_Filter_HandleTypeDef *hdfsdm_filter, uint32_t AudioFreq, void *Params);
+void BSP_AUDIO_IN_MspInit(void);
+void BSP_AUDIO_IN_MspDeInit(void);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_EVAL_AUDIO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_camera.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_camera.c
new file mode 100644
index 00000000..2b0e0bc9
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_camera.c
@@ -0,0 +1,689 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_eval_camera.c
+ * @author MCD Application Team
+ * @brief This file includes the driver for Camera modules mounted on
+ * STM32F769I-EVAL evaluation board.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_EVAL_CAMERA_H
+#define __STM32F769I_EVAL_CAMERA_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include Camera component Driver */
+#include "../Components/s5k5cag/s5k5cag.h"
+#include "../Components/ov5640/ov5640.h"
+
+/* Include IO Driver */
+#include "stm32f769i_eval_io.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL_CAMERA
+ * @{
+ */
+
+/** @defgroup STM32F769I_EVAL_CAMERA_Exported_Types CAMERA Exported Types
+ * @{
+ */
+
+/**
+ * @brief Camera State structures definition
+ */
+#define CAMERA_OK 0x00
+#define CAMERA_ERROR 0x01
+#define CAMERA_TIMEOUT 0x02
+#define CAMERA_NOT_DETECTED 0x03
+#define CAMERA_NOT_SUPPORTED 0x04
+
+
+/**
+ * @brief Camera Image rotation definition
+ * in frame buffer for LCD Display.
+ */
+#define CAMERA_NO_ROTATION 0x00
+#define CAMERA_ROTATION_90 0x01
+#define CAMERA_ROTATION_INVALID 0x02
+
+#define RESOLUTION_R160x120 CAMERA_R160x120 /* QQVGA Resolution */
+#define RESOLUTION_R320x240 CAMERA_R320x240 /* QVGA Resolution */
+#define RESOLUTION_R480x272 CAMERA_R480x272 /* 480x272 Resolution */
+#define RESOLUTION_R640x480 CAMERA_R640x480 /* VGA Resolution */
+
+#define CAMERA_VGA_RES_X 640
+#define CAMERA_VGA_RES_Y 480
+#define CAMERA_480x272_RES_X 480
+#define CAMERA_480x272_RES_Y 272
+#define CAMERA_QVGA_RES_X 320
+#define CAMERA_QVGA_RES_Y 240
+#define CAMERA_QQVGA_RES_X 160
+#define CAMERA_QQVGA_RES_Y 120
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_CAMERA_Exported_Constants CAMERA Exported Constants
+ * @{
+ */
+ #define BSP_CAMERA_IRQHandler DCMI_IRQHandler
+ #define BSP_CAMERA_DMA_IRQHandler DMA2_Stream1_IRQHandler
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_CAMERA_Exported_Functions CAMERA Exported Functions
+ * @{
+ */
+uint8_t BSP_CAMERA_Init(uint32_t Resolution);
+uint8_t BSP_CAMERA_DeInit(void);
+void BSP_CAMERA_ContinuousStart(uint8_t *buff);
+void BSP_CAMERA_SnapshotStart(uint8_t *buff);
+void BSP_CAMERA_Suspend(void);
+void BSP_CAMERA_Resume(void);
+uint8_t BSP_CAMERA_Stop(void);
+void BSP_CAMERA_HwReset(void);
+void BSP_CAMERA_PwrDown(void);
+void BSP_CAMERA_LineEventCallback(void);
+void BSP_CAMERA_VsyncEventCallback(void);
+void BSP_CAMERA_FrameEventCallback(void);
+void BSP_CAMERA_ErrorCallback(void);
+
+/* Camera features functions prototype */
+void BSP_CAMERA_ContrastBrightnessConfig(uint32_t contrast_level, uint32_t brightness_level);
+void BSP_CAMERA_BlackWhiteConfig(uint32_t Mode);
+void BSP_CAMERA_ColorEffectConfig(uint32_t Effect);
+
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_CAMERA_MspInit(DCMI_HandleTypeDef *hdcmi, void *Params);
+void BSP_CAMERA_MspDeInit(DCMI_HandleTypeDef *hdcmi, void *Params);
+uint8_t BSP_CAMERA_SetRotation(uint32_t rotation);
+uint32_t BSP_CAMERA_GetRotation(void);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_EVAL_CAMERA_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_eeprom.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_eeprom.c
new file mode 100644
index 00000000..a3f2dc61
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_eeprom.c
@@ -0,0 +1,476 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_eval_eeprom.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage an I2C M24LR64
+ * EEPROM memory.
+ @verbatim
+ To be able to use this driver, the switch EE_M24LR64 must be defined
+ in your toolchain compiler preprocessor
+
+ ===================================================================
+ Notes:
+ - The I2C EEPROM memory (M24LR64) is available on separate daughter
+ board ANT7-M24LR-A, which is not provided with the STM32F769I_EVAL
+ board.
+ To use this driver you have to connect the ANT7-M24LR-A to CN2
+ connector of STM32F769I_EVAL board.
+ ===================================================================
+
+ It implements a high level communication layer for read and write
+ from/to this memory. The needed STM32F7xx hardware resources (I2C and
+ GPIO) are defined in stm32f769i_eval.h file, and the initialization is
+ performed in EEPROM_IO_Init() function declared in stm32f769i_eval.c
+ file.
+ You can easily tailor this driver to any other development board,
+ by just adapting the defines for hardware resources and
+ EEPROM_IO_Init() function.
+
+ @note In this driver, basic read and write functions (BSP_EEPROM_ReadBuffer()
+ and BSP_EEPROM_WritePage()) use DMA mode to perform the data
+ transfer to/from EEPROM memory.
+
+ @note Regarding BSP_EEPROM_WritePage(), it is an optimized function to perform
+ small write (less than 1 page) BUT the number of bytes (combined to write start address) must not
+ cross the EEPROM page boundary. This function can only writes into
+ the boundaries of an EEPROM page.
+ This function doesn't check on boundaries condition (in this driver
+ the function BSP_EEPROM_WriteBuffer() which calls BSP_EEPROM_WritePage() is
+ responsible of checking on Page boundaries).
+
+
+ +-----------------------------------------------------------------+
+ | Pin assignment for M24LR64 EEPROM |
+ +---------------------------------------+-----------+-------------+
+ | STM32F7xx I2C Pins | EEPROM | Pin |
+ +---------------------------------------+-----------+-------------+
+ | . | E0(GND) | 1 (0V) |
+ | . | AC0 | 2 |
+ | . | AC1 | 3 |
+ | . | VSS | 4 (0V) |
+ | SDA | SDA | 5 |
+ | SCL | SCL | 6 |
+ | . | E1(GND) | 7 (0V) |
+ | . | VDD | 8 (3.3V) |
+ +---------------------------------------+-----------+-------------+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Dependencies
+- stm32f769i_eval.c
+EndDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f769i_eval_eeprom.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL
+ * @{
+ */
+
+/** @defgroup STM32F769I_EVAL_EEPROM STM32F769I_EVAL EEPROM
+ * @brief This file includes the I2C EEPROM driver of STM32F769I-EVAL evaluation board.
+ * @{
+ */
+
+/** @defgroup STM32F769I_EVAL_EEPROM_Private_Types EEPROM Private Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_EEPROM_Private_Defines EEPROM Private Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_EEPROM_Private_Macros EEPROM Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_EEPROM_Private_Variables EEPROM Private Variables
+ * @{
+ */
+__IO uint16_t EEPROMAddress = 0;
+__IO uint16_t EEPROMDataRead;
+__IO uint8_t EEPROMDataWrite;
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_EEPROM_Private_Function_Prototypes EEPROM Private Functions Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_EEPROM_Private_Functions EEPROM Private Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes peripherals used by the I2C EEPROM driver.
+ * @note There are 2 different versions of M24LR64 (A01 & A02).
+ * Then try to connect on 1st one (EEPROM_I2C_ADDRESS_A01)
+ * and if problem, check the 2nd one (EEPROM_I2C_ADDRESS_A02)
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0)
+ */
+uint32_t BSP_EEPROM_Init(void)
+{
+ /* I2C Initialization */
+ EEPROM_IO_Init();
+
+ /* Select the EEPROM address for A01 and check if OK */
+ EEPROMAddress = EEPROM_I2C_ADDRESS_A01;
+ if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
+ {
+ /* Select the EEPROM address for A02 and check if OK */
+ EEPROMAddress = EEPROM_I2C_ADDRESS_A02;
+ if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
+ {
+ return EEPROM_FAIL;
+ }
+ }
+ return EEPROM_OK;
+}
+
+/**
+ * @brief DeInitializes the EEPROM.
+ * @retval EEPROM state
+ */
+uint8_t BSP_EEPROM_DeInit(void)
+{
+ /* I2C won't be disabled because common to other functionalities */
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Reads a block of data from the EEPROM.
+ * @param pBuffer: pointer to the buffer that receives the data read from
+ * the EEPROM.
+ * @param ReadAddr: EEPROM's internal address to start reading from.
+ * @param NumByteToRead: pointer to the variable holding number of bytes to
+ * be read from the EEPROM.
+ *
+ * @note The variable pointed by NumByteToRead is reset to 0 when all the
+ * data are read from the EEPROM. Application should monitor this
+ * variable in order know when the transfer is complete.
+ *
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
+{
+ uint32_t buffersize = *NumByteToRead;
+
+ /* Set the pointer to the Number of data to be read. This pointer will be used
+ by the DMA Transfer Completer interrupt Handler in order to reset the
+ variable to 0. User should check on this variable in order to know if the
+ DMA transfer has been complete or not. */
+ EEPROMDataRead = *NumByteToRead;
+
+ if(EEPROM_IO_ReadData(EEPROMAddress, ReadAddr, pBuffer, buffersize) != HAL_OK)
+ {
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ return EEPROM_FAIL;
+ }
+
+ /* If all operations OK, return EEPROM_OK (0) */
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Writes more than one byte to the EEPROM with a single WRITE cycle.
+ *
+ * @note The number of bytes (combined to write start address) must not
+ * cross the EEPROM page boundary. This function can only write into
+ * the boundaries of an EEPROM page.
+ * This function doesn't check on boundaries condition (in this driver
+ * the function BSP_EEPROM_WriteBuffer() which calls BSP_EEPROM_WritePage() is
+ * responsible of checking on Page boundaries).
+ *
+ * @param pBuffer: pointer to the buffer containing the data to be written to
+ * the EEPROM.
+ * @param WriteAddr: EEPROM's internal address to write to.
+ * @param NumByteToWrite: pointer to the variable holding number of bytes to
+ * be written into the EEPROM.
+ *
+ * @note The variable pointed by NumByteToWrite is reset to 0 when all the
+ * data are written to the EEPROM. Application should monitor this
+ * variable in order know when the transfer is complete.
+ *
+ * @note This function just configure the communication and enable the DMA
+ * channel to transfer data. Meanwhile, the user application may perform
+ * other tasks in parallel.
+ *
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite)
+{
+ uint32_t buffersize = *NumByteToWrite;
+ uint32_t status = EEPROM_OK;
+
+ /* Set the pointer to the Number of data to be written. This pointer will be used
+ by the DMA Transfer Completer interrupt Handler in order to reset the
+ variable to 0. User should check on this variable in order to know if the
+ DMA transfer has been complete or not. */
+ EEPROMDataWrite = *NumByteToWrite;
+
+ if(EEPROM_IO_WriteData(EEPROMAddress, WriteAddr, pBuffer, buffersize) != HAL_OK)
+ {
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ status = EEPROM_FAIL;
+ }
+
+ if(BSP_EEPROM_WaitEepromStandbyState() != EEPROM_OK)
+ {
+ return EEPROM_FAIL;
+ }
+
+ /* If all operations OK, return EEPROM_OK (0) */
+ return status;
+}
+
+/**
+ * @brief Writes buffer of data to the I2C EEPROM.
+ * @param pBuffer: pointer to the buffer containing the data to be written
+ * to the EEPROM.
+ * @param WriteAddr: EEPROM's internal address to write to.
+ * @param NumByteToWrite: number of bytes to write to the EEPROM.
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_WriteBuffer(uint8_t *pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
+{
+ uint16_t numofpage = 0, numofsingle = 0, count = 0;
+ uint16_t addr = 0;
+ uint8_t dataindex = 0;
+ uint32_t status = EEPROM_OK;
+
+ addr = WriteAddr % EEPROM_PAGESIZE;
+ count = EEPROM_PAGESIZE - addr;
+ numofpage = NumByteToWrite / EEPROM_PAGESIZE;
+ numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
+
+ /* If WriteAddr is EEPROM_PAGESIZE aligned */
+ if(addr == 0)
+ {
+ /* If NumByteToWrite < EEPROM_PAGESIZE */
+ if(numofpage == 0)
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ /* Start writing data */
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ /* If NumByteToWrite > EEPROM_PAGESIZE */
+ else
+ {
+ while(numofpage--)
+ {
+ /* Store the number of data to be written */
+ dataindex = EEPROM_PAGESIZE;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+
+ WriteAddr += EEPROM_PAGESIZE;
+ pBuffer += EEPROM_PAGESIZE;
+ }
+
+ if(numofsingle!=0)
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ }
+ }
+ /* If WriteAddr is not EEPROM_PAGESIZE aligned */
+ else
+ {
+ /* If NumByteToWrite < EEPROM_PAGESIZE */
+ if(numofpage== 0)
+ {
+ /* If the number of data to be written is more than the remaining space
+ in the current page: */
+ if(NumByteToWrite > count)
+ {
+ /* Store the number of data to be written */
+ dataindex = count;
+ /* Write the data contained in same page */
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+
+ /* Store the number of data to be written */
+ dataindex = (NumByteToWrite - count);
+ /* Write the remaining data in the following page */
+ status = BSP_EEPROM_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ else
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ }
+ /* If NumByteToWrite > EEPROM_PAGESIZE */
+ else
+ {
+ NumByteToWrite -= count;
+ numofpage = NumByteToWrite / EEPROM_PAGESIZE;
+ numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
+
+ if(count != 0)
+ {
+ /* Store the number of data to be written */
+ dataindex = count;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ WriteAddr += count;
+ pBuffer += count;
+ }
+
+ while(numofpage--)
+ {
+ /* Store the number of data to be written */
+ dataindex = EEPROM_PAGESIZE;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ WriteAddr += EEPROM_PAGESIZE;
+ pBuffer += EEPROM_PAGESIZE;
+ }
+ if(numofsingle != 0)
+ {
+ /* Store the number of data to be written */
+ dataindex = numofsingle;
+ status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
+ if(status != EEPROM_OK)
+ {
+ return status;
+ }
+ }
+ }
+ }
+
+ /* If all operations OK, return EEPROM_OK (0) */
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Wait for EEPROM Standby state.
+ *
+ * @note This function allows to wait and check that EEPROM has finished the
+ * last operation. It is mostly used after Write operation: after receiving
+ * the buffer to be written, the EEPROM may need additional time to actually
+ * perform the write operation. During this time, it doesn't answer to
+ * I2C packets addressed to it. Once the write operation is complete
+ * the EEPROM responds to its address.
+ *
+ * @retval EEPROM_OK (0) if operation is correctly performed, else return value
+ * different from EEPROM_OK (0) or the timeout user callback.
+ */
+uint32_t BSP_EEPROM_WaitEepromStandbyState(void)
+{
+ /* Check if the maximum allowed number of trials has bee reached */
+ if(EEPROM_IO_IsDeviceReady(EEPROMAddress, EEPROM_MAX_TRIALS) != HAL_OK)
+ {
+ /* If the maximum number of trials has been reached, exit the function */
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ return EEPROM_TIMEOUT;
+ }
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Basic management of the timeout situation.
+ * @retval None
+ */
+__weak void BSP_EEPROM_TIMEOUT_UserCallback(void)
+{
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_eeprom.h b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_eeprom.h
new file mode 100644
index 00000000..138d694a
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_eeprom.h
@@ -0,0 +1,138 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_eval_eeprom.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for
+ * the stm32f769i_eval_eeprom.c firmware driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F756G_EVAL_EEPROM_H
+#define __STM32F756G_EVAL_EEPROM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f769i_eval.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL_EEPROM
+ * @brief This file includes the I2C EEPROM driver of STM32F769I-EVAL evaluation board.
+ * @{
+ */
+
+/** @defgroup STM32F769I_EVAL_EEPROM_Exported_Types EEPROM_ Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_EEPROM_Exported_Constants EEPROM Exported Constants
+ * @{
+ */
+/* EEPROM hardware address and page size */
+#define EEPROM_PAGESIZE ((uint8_t)4)
+#define EEPROM_MAX_SIZE ((uint16_t)0x2000) /* 64Kbit */
+
+
+/* Maximum number of trials for EEPROM_WaitEepromStandbyState() function */
+#define EEPROM_MAX_TRIALS ((uint32_t)3000)
+
+#define EEPROM_OK ((uint32_t)0)
+#define EEPROM_FAIL ((uint32_t)1)
+#define EEPROM_TIMEOUT ((uint32_t)2)
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_EEPROM_Exported_Macros EEPROM Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_EEPROM_Exported_Functions EEPROM Exported Functions
+ * @{
+ */
+uint32_t BSP_EEPROM_Init(void);
+uint8_t BSP_EEPROM_DeInit(void);
+uint32_t BSP_EEPROM_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead);
+uint32_t BSP_EEPROM_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite);
+uint32_t BSP_EEPROM_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite);
+uint32_t BSP_EEPROM_WaitEepromStandbyState(void);
+
+/* USER Callbacks: This function is declared as __weak in EEPROM driver and
+ should be implemented into user application.
+ BSP_EEPROM_TIMEOUT_UserCallback() function is called whenever a timeout condition
+ occurs during communication (waiting on an event that doesn't occur, bus
+ errors, busy devices ...). */
+void BSP_EEPROM_TIMEOUT_UserCallback(void);
+
+/* Link function for I2C EEPROM peripheral */
+void EEPROM_IO_Init(void);
+HAL_StatusTypeDef EEPROM_IO_WriteData(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef EEPROM_IO_ReadData(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pBuffer, uint32_t BufferSize);
+HAL_StatusTypeDef EEPROM_IO_IsDeviceReady(uint16_t DevAddress, uint32_t Trials);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_EVAL_EEPROM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_io.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_io.c
new file mode 100644
index 00000000..d21ace5b
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_io.c
@@ -0,0 +1,335 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_eval_io.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the IO pins
+ * on STM32F769I-EVAL evaluation board.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ - This driver is used to drive the IO module of the STM32F769I-EVAL evaluation
+ board.
+ - The MFXSTM32L152 IO expander device component driver must be included with this
+ driver in order to run the IO functionalities commanded by the IO expander (MFX)
+ device mounted on the evaluation board.
+
+ Driver description:
+ -------------------
+ + Initialization steps:
+ o Initialize the IO module using the BSP_IO_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ communication layer configuration to start the IO functionalities use.
+
+ + IO functionalities use
+ o The IO pin mode is configured when calling the function BSP_IO_ConfigPin(), you
+ must specify the desired IO mode by choosing the "IO_ModeTypedef" parameter
+ predefined value.
+ o If an IO pin is used in interrupt mode, the function BSP_IO_ITGetStatus() is
+ needed to get the interrupt status. To clear the IT pending bits, you should
+ call the function BSP_IO_ITClear() with specifying the IO pending bit to clear.
+ o The IT is handled using the corresponding external interrupt IRQ handler,
+ the user IT callback treatment is implemented on the same external interrupt
+ callback.
+ o The IRQ_OUT pin (common for all functionalities: JOY, SD, LEDs, etc) can be
+ configured using the function BSP_IO_ConfigIrqOutPin()
+ o To get/set an IO pin combination state you can use the functions
+ BSP_IO_ReadPin()/BSP_IO_WritePin() or the function BSP_IO_TogglePin() to toggle the pin
+ state.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Dependencies
+- stm32f769i_eval.h
+- mfxstm32l152.c
+EndDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f769i_eval_io.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL
+ * @{
+ */
+
+/** @defgroup STM32F769I_EVAL_IO STM32F769I_EVAL IO
+ * @{
+ */
+
+/** @defgroup STM32F769I_EVAL_IO_Private_Types_Definitions IO Private Types Definitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_IO_Private_Defines IO Private Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_IO_Private_Macros IO Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_IO_Private_Variables IO Private Variables
+ * @{
+ */
+static IO_DrvTypeDef *IoDrv = NULL;
+static uint8_t mfxstm32l152Identifier;
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_IO_Private_Functions_Prototypes IO Private Functions Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_IO_Private_Functions IO Private Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes and configures the IO functionalities and configures all
+ * necessary hardware resources (MFX, ...).
+ * @note BSP_IO_Init() is using HAL_Delay() function to ensure that MFXSTM32L152
+ * IO Expander is correctly reset. HAL_Delay() function provides accurate
+ * delay (in milliseconds) based on variable incremented in SysTick ISR.
+ * This implies that if BSP_IO_Init() is called from a peripheral ISR process,
+ * then the SysTick interrupt must have higher priority (numerically lower)
+ * than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
+ * @retval IO_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_IO_Init(void)
+{
+ uint8_t ret = IO_OK;
+
+ if (IoDrv == NULL) /* Checks if MFX initialization never done */
+ {
+ /* Read ID and verify the MFX is ready */
+ mfxstm32l152Identifier = mfxstm32l152_io_drv.ReadID(IO_I2C_ADDRESS);
+ if((mfxstm32l152Identifier == MFXSTM32L152_ID_1) || (mfxstm32l152Identifier == MFXSTM32L152_ID_2))
+ {
+ /* Initialize the IO driver structure */
+ IoDrv = &mfxstm32l152_io_drv;
+
+ /* Initialize MFX */
+ IoDrv->Init(IO_I2C_ADDRESS);
+ IoDrv->Start(IO_I2C_ADDRESS, IO_PIN_ALL);
+ }
+ else
+ {
+ ret = IO_ERROR;
+ }
+ }
+ else
+ {
+ /* MFX initialization already done : do nothing */
+ }
+
+ return ret;
+}
+
+/**
+ * @brief DeInit allows Mfx Initialization to be executed again
+ * @note BSP_IO_Init() has no effect if the IoDrv is already initialized
+ * BSP_IO_DeInit() allows to erase the pointer such to allow init to be effective
+ * @retval IO_OK
+ */
+uint8_t BSP_IO_DeInit(void)
+{
+ IoDrv = NULL;
+ return IO_OK;
+}
+
+/**
+ * @brief Gets the selected pins IT status.
+ * @param IoPin: Selected pins to check the status.
+ * This parameter can be any combination of the IO pins.
+ * @retval IO_OK if read status OK. Other value if error.
+ */
+uint32_t BSP_IO_ITGetStatus(uint32_t IoPin)
+{
+ /* Return the IO Pin IT status */
+ return (IoDrv->ITStatus(IO_I2C_ADDRESS, IoPin));
+}
+
+/**
+ * @brief Clears all the IO IT pending bits.
+ * @retval None
+ */
+void BSP_IO_ITClear(void)
+{
+ /* Clear all IO IT pending bits */
+ IoDrv->ClearIT(IO_I2C_ADDRESS, MFXSTM32L152_GPIO_PINS_ALL);
+}
+
+/**
+ * @brief Clear only one or a selection of IO IT pending bits.
+ * @param IO_Pins_To_Clear : MFX IRQ status IO pin to clear (or combination of several IOs)
+ */
+void BSP_IO_ITClearPin(uint32_t IO_Pins_To_Clear)
+{
+ /* Clear only the selected list of IO IT pending bits */
+ IoDrv->ClearIT(IO_I2C_ADDRESS, IO_Pins_To_Clear);
+}
+
+/**
+ * @brief Configures the IO pin(s) according to IO mode structure value.
+ * @param IoPin: IO pin(s) to be configured.
+ * This parameter can be one of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+ * @param IoMode: IO pin mode to configure
+ * This parameter can be one of the following values:
+ * @arg IO_MODE_INPUT
+ * @arg IO_MODE_OUTPUT
+ * @arg IO_MODE_IT_RISING_EDGE
+ * @arg IO_MODE_IT_FALLING_EDGE
+ * @arg IO_MODE_IT_LOW_LEVEL
+ * @arg IO_MODE_IT_HIGH_LEVEL
+ * @arg IO_MODE_ANALOG
+ * @arg IO_MODE_OFF
+ * @arg IO_MODE_INPUT_PU,
+ * @arg IO_MODE_INPUT_PD,
+ * @arg IO_MODE_OUTPUT_OD,
+ * @arg IO_MODE_OUTPUT_OD_PU,
+ * @arg IO_MODE_OUTPUT_OD_PD,
+ * @arg IO_MODE_OUTPUT_PP,
+ * @arg IO_MODE_OUTPUT_PP_PU,
+ * @arg IO_MODE_OUTPUT_PP_PD,
+ * @arg IO_MODE_IT_RISING_EDGE_PU
+ * @arg IO_MODE_IT_FALLING_EDGE_PU
+ * @arg IO_MODE_IT_LOW_LEVEL_PU
+ * @arg IO_MODE_IT_HIGH_LEVEL_PU
+ * @arg IO_MODE_IT_RISING_EDGE_PD
+ * @arg IO_MODE_IT_FALLING_EDGE_PD
+ * @arg IO_MODE_IT_LOW_LEVEL_PD
+ * @arg IO_MODE_IT_HIGH_LEVEL_PD
+ * @retval IO_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_IO_ConfigPin(uint32_t IoPin, IO_ModeTypedef IoMode)
+{
+ /* Configure the selected IO pin(s) mode */
+ IoDrv->Config(IO_I2C_ADDRESS, IoPin, IoMode);
+
+ return IO_OK;
+}
+
+/**
+ * @brief Sets the IRQ_OUT pin polarity and type
+ * @param IoIrqOutPinPolarity: High/Low
+ * @param IoIrqOutPinType: OpenDrain/PushPull
+ * @retval OK
+ */
+uint8_t BSP_IO_ConfigIrqOutPin(uint8_t IoIrqOutPinPolarity, uint8_t IoIrqOutPinType)
+{
+ if((mfxstm32l152Identifier == MFXSTM32L152_ID_1) || (mfxstm32l152Identifier == MFXSTM32L152_ID_2))
+ {
+ /* Initialize the IO driver structure */
+ mfxstm32l152_SetIrqOutPinPolarity(IO_I2C_ADDRESS, IoIrqOutPinPolarity);
+ mfxstm32l152_SetIrqOutPinType(IO_I2C_ADDRESS, IoIrqOutPinType);
+ }
+
+ return IO_OK;
+}
+
+/**
+ * @brief Sets the selected pins state.
+ * @param IoPin: Selected pins to write.
+ * This parameter can be any combination of the IO pins.
+ * @param PinState: New pins state to write
+ * @retval None
+ */
+void BSP_IO_WritePin(uint32_t IoPin, BSP_IO_PinStateTypeDef PinState)
+{
+ /* Set the Pin state */
+ IoDrv->WritePin(IO_I2C_ADDRESS, IoPin, PinState);
+}
+
+/**
+ * @brief Gets the selected pins current state.
+ * @param IoPin: Selected pins to read.
+ * This parameter can be any combination of the IO pins.
+ * @retval The current pins state
+ */
+uint32_t BSP_IO_ReadPin(uint32_t IoPin)
+{
+ return(IoDrv->ReadPin(IO_I2C_ADDRESS, IoPin));
+}
+
+/**
+ * @brief Toggles the selected pins state.
+ * @param IoPin: Selected pins to toggle.
+ * This parameter can be any combination of the IO pins.
+ * @note This function is only used to toggle one pin in the same time
+ * @retval None
+ */
+void BSP_IO_TogglePin(uint32_t IoPin)
+{
+ /* Toggle the current pin state */
+ if(IoDrv->ReadPin(IO_I2C_ADDRESS, IoPin) != 0) /* Set */
+ {
+ IoDrv->WritePin(IO_I2C_ADDRESS, IoPin, 0); /* Reset */
+ }
+ else
+ {
+ IoDrv->WritePin(IO_I2C_ADDRESS, IoPin, 1); /* Set */
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_io.h b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_io.h
new file mode 100644
index 00000000..90c06234
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_io.h
@@ -0,0 +1,157 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_eval_io.h
+ * @author MCD Application Team
+ * @brief This file contains the common defines and functions prototypes for
+ * the stm32f769i_eval_io.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_EVAL_LCD_H
+#define __STM32F769I_EVAL_LCD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include LCD component Driver */
+
+/* Include OTM8009A LCD Driver IC driver code */
+#include "../Components/otm8009a/otm8009a.h"
+
+#if defined(USE_LCD_HDMI)
+/* Include ADV7533 HDMI Driver IC driver code */
+#include "../Components/adv7533/adv7533.h"
+#endif /* USE_LCD_HDMI */
+
+/* Include SDRAM Driver */
+#include "stm32f769i_eval_sdram.h"
+#include "stm32f769i_eval.h"
+
+#include "../../../Utilities/Fonts/fonts.h"
+
+#include /* use of memset() */
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL_LCD
+ * @{
+ */
+
+/** @defgroup STM32F769I_EVAL_LCD_Exported_Constants STM32F769I EVAL LCD Exported Constants
+ * @{
+ */
+#define BSP_LCD_DMA2D_IRQHandler DMA2D_IRQHandler
+#define BSP_LCD_DSI_IRQHandler DSI_IRQHandler
+#define BSP_LCD_LTDC_IRQHandler LTDC_IRQHandler
+#define BSP_LCD_LTDC_ER_IRQHandler LTDC_ER_IRQHandler
+
+
+#define LCD_LayerCfgTypeDef LTDC_LayerCfgTypeDef
+/**
+ * @brief LCD FB_StartAddress
+ */
+#define LCD_FB_START_ADDRESS ((uint32_t)0xC0000000)
+
+/** @brief Maximum number of LTDC layers
+ */
+#define LTDC_MAX_LAYER_NUMBER ((uint32_t) 2)
+
+/** @brief LTDC Background layer index
+ */
+#define LTDC_ACTIVE_LAYER_BACKGROUND ((uint32_t) 0)
+
+/** @brief LTDC Foreground layer index
+ */
+#define LTDC_ACTIVE_LAYER_FOREGROUND ((uint32_t) 1)
+
+/** @brief Number of LTDC layers
+ */
+#define LTDC_NB_OF_LAYERS ((uint32_t) 2)
+
+/** @brief LTDC Default used layer index
+ */
+#define LTDC_DEFAULT_ACTIVE_LAYER LTDC_ACTIVE_LAYER_FOREGROUND
+
+/**
+ * @brief LCD status structure definition
+ */
+#define LCD_OK 0x00
+#define LCD_ERROR 0x01
+#define LCD_TIMEOUT 0x02
+
+/**
+ * @brief LCD Display OTM8009A DSI Virtual Channel ID
+ */
+#define LCD_OTM8009A_ID ((uint32_t) 0)
+
+#if defined(USE_LCD_HDMI)
+/**
+ * @brief HDMI ADV7533 DSI Virtual Channel ID
+ */
+#define HDMI_ADV7533_ID ((uint32_t) 0)
+
+/**
+ * @brief HDMI Foramt
+ */
+#define HDMI_FORMAT_720_480 ((uint8_t) 0x00) /*720_480 format choice of HDMI display */
+#define HDMI_FORMAT_720_576 ((uint8_t) 0x01) /*720_576 format choice of HDMI display*/
+
+#endif /* USE_LCD_HDMI */
+
+/**
+ * @brief LCD color definitions values
+ * in ARGB8888 format.
+ */
+
+/** @brief Blue value in ARGB8888 format
+ */
+#define LCD_COLOR_BLUE ((uint32_t) 0xFF0000FF)
+
+/** @brief Green value in ARGB8888 format
+ */
+#define LCD_COLOR_GREEN ((uint32_t) 0xFF00FF00)
+
+/** @brief Red value in ARGB8888 format
+ */
+#define LCD_COLOR_RED ((uint32_t) 0xFFFF0000)
+
+/** @brief Cyan value in ARGB8888 format
+ */
+#define LCD_COLOR_CYAN ((uint32_t) 0xFF00FFFF)
+
+/** @brief Magenta value in ARGB8888 format
+ */
+#define LCD_COLOR_MAGENTA ((uint32_t) 0xFFFF00FF)
+
+/** @brief Yellow value in ARGB8888 format
+ */
+#define LCD_COLOR_YELLOW ((uint32_t) 0xFFFFFF00)
+
+/** @brief Light Blue value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTBLUE ((uint32_t) 0xFF8080FF)
+
+/** @brief Light Green value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTGREEN ((uint32_t) 0xFF80FF80)
+
+/** @brief Light Red value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTRED ((uint32_t) 0xFFFF8080)
+
+/** @brief Light Cyan value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTCYAN ((uint32_t) 0xFF80FFFF)
+
+/** @brief Light Magenta value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTMAGENTA ((uint32_t) 0xFFFF80FF)
+
+/** @brief Light Yellow value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTYELLOW ((uint32_t) 0xFFFFFF80)
+
+/** @brief Dark Blue value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKBLUE ((uint32_t) 0xFF000080)
+
+/** @brief Light Dark Green value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKGREEN ((uint32_t) 0xFF008000)
+
+/** @brief Light Dark Red value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKRED ((uint32_t) 0xFF800000)
+
+/** @brief Dark Cyan value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKCYAN ((uint32_t) 0xFF008080)
+
+/** @brief Dark Magenta value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKMAGENTA ((uint32_t) 0xFF800080)
+
+/** @brief Dark Yellow value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKYELLOW ((uint32_t) 0xFF808000)
+
+/** @brief White value in ARGB8888 format
+ */
+#define LCD_COLOR_WHITE ((uint32_t) 0xFFFFFFFF)
+
+/** @brief Light Gray value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTGRAY ((uint32_t) 0xFFD3D3D3)
+
+/** @brief Gray value in ARGB8888 format
+ */
+#define LCD_COLOR_GRAY ((uint32_t) 0xFF808080)
+
+/** @brief Dark Gray value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKGRAY ((uint32_t) 0xFF404040)
+
+/** @brief Black value in ARGB8888 format
+ */
+#define LCD_COLOR_BLACK ((uint32_t) 0xFF000000)
+
+/** @brief Brown value in ARGB8888 format
+ */
+#define LCD_COLOR_BROWN ((uint32_t) 0xFFA52A2A)
+
+/** @brief Orange value in ARGB8888 format
+ */
+#define LCD_COLOR_ORANGE ((uint32_t) 0xFFFFA500)
+
+/** @brief Transparent value in ARGB8888 format
+ */
+#define LCD_COLOR_TRANSPARENT ((uint32_t) 0xFF000000)
+
+/**
+ * @brief LCD default font
+ */
+#define LCD_DEFAULT_FONT Font24
+
+/**
+ * @brief Possible values of
+ * pixel data format (ie color coding) transmitted on DSI Data lane in DSI packets
+ */
+
+#define LCD_DSI_PIXEL_DATA_FMT_RBG888 DSI_RGB888 /*!< DSI packet pixel format chosen is RGB888 : 24 bpp */
+#define LCD_DSI_PIXEL_DATA_FMT_RBG565 DSI_RGB565 /*!< DSI packet pixel format chosen is RGB565 : 16 bpp */
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_LCD_Exported_Types STM32F769I EVAL LCD Exported Types
+ * @{
+ */
+
+/**
+* @brief LCD Drawing main properties
+*/
+typedef struct
+{
+ uint32_t TextColor; /*!< Specifies the color of text */
+ uint32_t BackColor; /*!< Specifies the background color below the text */
+ sFONT *pFont; /*!< Specifies the font used for the text */
+
+} LCD_DrawPropTypeDef;
+
+/**
+ * @brief LCD Drawing point (pixel) geometric definition
+ */
+typedef struct
+{
+ int16_t X; /*!< geometric X position of drawing */
+ int16_t Y; /*!< geometric Y position of drawing */
+
+} Point;
+
+/**
+ * @brief Pointer on LCD Drawing point (pixel) geometric definition
+ */
+typedef Point * pPoint;
+
+/**
+ * @brief LCD drawing Line alignment mode definitions
+ */
+typedef enum
+{
+ CENTER_MODE = 0x01, /*!< Center mode */
+ RIGHT_MODE = 0x02, /*!< Right mode */
+ LEFT_MODE = 0x03 /*!< Left mode */
+
+} Text_AlignModeTypdef;
+
+
+/**
+ * @brief LCD_OrientationTypeDef
+ * Possible values of Display Orientation
+ */
+typedef enum
+{
+ LCD_ORIENTATION_PORTRAIT = 0x00, /*!< Portrait orientation choice of LCD screen */
+ LCD_ORIENTATION_LANDSCAPE = 0x01, /*!< Landscape orientation choice of LCD screen */
+ LCD_ORIENTATION_INVALID = 0x02 /*!< Invalid orientation choice of LCD screen */
+} LCD_OrientationTypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_LCD_Exported_Macro STM32F769I EVAL LCD Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+/** @addtogroup STM32F769I_EVAL_LCD_Exported_Functions
+ * @{
+ */
+uint8_t BSP_LCD_Init(void);
+uint8_t BSP_LCD_InitEx(LCD_OrientationTypeDef orientation);
+
+#if defined(USE_LCD_HDMI)
+uint8_t BSP_LCD_HDMIInitEx(uint8_t format);
+#endif /* USE_LCD_HDMI */
+
+void BSP_LCD_MspDeInit(void);
+void BSP_LCD_MspInit(void);
+void BSP_LCD_Reset(void);
+
+uint32_t BSP_LCD_GetXSize(void);
+uint32_t BSP_LCD_GetYSize(void);
+void BSP_LCD_SetXSize(uint32_t imageWidthPixels);
+void BSP_LCD_SetYSize(uint32_t imageHeightPixels);
+
+void BSP_LCD_LayerDefaultInit(uint16_t LayerIndex, uint32_t FB_Address);
+void BSP_LCD_SetTransparency(uint32_t LayerIndex, uint8_t Transparency);
+void BSP_LCD_SetLayerAddress(uint32_t LayerIndex, uint32_t Address);
+void BSP_LCD_SetColorKeying(uint32_t LayerIndex, uint32_t RGBValue);
+void BSP_LCD_ResetColorKeying(uint32_t LayerIndex);
+void BSP_LCD_SetLayerWindow(uint16_t LayerIndex, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+
+void BSP_LCD_SelectLayer(uint32_t LayerIndex);
+void BSP_LCD_SetLayerVisible(uint32_t LayerIndex, FunctionalState State);
+
+void BSP_LCD_SetTextColor(uint32_t Color);
+uint32_t BSP_LCD_GetTextColor(void);
+void BSP_LCD_SetBackColor(uint32_t Color);
+uint32_t BSP_LCD_GetBackColor(void);
+void BSP_LCD_SetFont(sFONT *fonts);
+sFONT *BSP_LCD_GetFont(void);
+
+uint32_t BSP_LCD_ReadPixel(uint16_t Xpos, uint16_t Ypos);
+void BSP_LCD_DrawPixel(uint16_t Xpos, uint16_t Ypos, uint32_t pixel);
+void BSP_LCD_Clear(uint32_t Color);
+void BSP_LCD_ClearStringLine(uint32_t Line);
+void BSP_LCD_DisplayStringAtLine(uint16_t Line, uint8_t *ptr);
+void BSP_LCD_DisplayStringAt(uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Text_AlignModeTypdef Mode);
+void BSP_LCD_DisplayChar(uint16_t Xpos, uint16_t Ypos, uint8_t Ascii);
+
+void BSP_LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+void BSP_LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+void BSP_LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+void BSP_LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+void BSP_LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+void BSP_LCD_DrawPolygon(pPoint Points, uint16_t PointCount);
+void BSP_LCD_DrawEllipse(int Xpos, int Ypos, int XRadius, int YRadius);
+void BSP_LCD_DrawBitmap(uint32_t Xpos, uint32_t Ypos, uint8_t *pbmp);
+
+void BSP_LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+void BSP_LCD_FillCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+void BSP_LCD_FillPolygon(pPoint Points, uint16_t PointCount);
+void BSP_LCD_FillEllipse(int Xpos, int Ypos, int XRadius, int YRadius);
+
+void BSP_LCD_DisplayOff(void);
+void BSP_LCD_DisplayOn(void);
+void BSP_LCD_SetBrightness(uint8_t BrightnessValue);
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_LCD_Exported_Variables STM32F769I EVAL LCD Exported Variables
+ * @{
+ */
+
+/* @brief DMA2D handle variable */
+extern DMA2D_HandleTypeDef hdma2d_eval;
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_EVAL_LCD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_nor.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_nor.c
new file mode 100644
index 00000000..560b8790
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_nor.c
@@ -0,0 +1,461 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_eval_nor.c
+ * @author MCD Application Team
+ * @brief This file includes a standard driver for the PC28F128M29EWLA NOR flash memory
+ * device mounted on STM32F769I-EVAL evaluation boards.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ - This driver is used to drive the PC28F128M29EWLA NOR flash external memory mounted
+ on STM32F769I-EVAL evaluation board.
+ - This driver does not need a specific component driver for the NOR device
+ to be included with.
+
+ Driver description:
+ ------------------
+ + Initialization steps:
+ o Initialize the NOR external memory using the BSP_NOR_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ FMC controller configuration to interface with the external NOR memory.
+
+ + NOR flash operations
+ o NOR external memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_NOR_ReadData()/BSP_NOR_WriteData(). The BSP_NOR_WriteData() performs write operation
+ of an amount of data by unit (halfword). You can also perform a program data
+ operation of an amount of data using the function BSP_NOR_ProgramData().
+ o The function BSP_NOR_Read_ID() returns the chip IDs stored in the structure
+ "NOR_IDTypeDef". (see the NOR IDs in the memory data sheet)
+ o Perform erase block operation using the function BSP_NOR_Erase_Block() and by
+ specifying the block address. You can perform an erase operation of the whole
+ chip by calling the function BSP_NOR_Erase_Chip().
+ o After other operations, the function BSP_NOR_ReturnToReadMode() allows the NOR
+ flash to return to read mode to perform read operations on it.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_EVAL_NOR_H
+#define __STM32F769I_EVAL_NOR_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL_NOR
+ * @{
+ */
+
+/** @defgroup STM32F769I_EVAL_NOR_Exported_Types NOR Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/**
+ * @brief NOR status structure definition
+ */
+#define NOR_STATUS_OK ((uint8_t)0x00)
+#define NOR_STATUS_ERROR ((uint8_t)0x01)
+
+/** @defgroup STM32F769I_EVAL_NOR_Exported_Constants NOR Exported Constants
+ * @{
+ */
+#define NOR_DEVICE_ADDR ((uint32_t)0x60000000)
+
+/* #define NOR_MEMORY_WIDTH FMC_NORSRAM_MEM_BUS_WIDTH_8 */
+#define NOR_MEMORY_WIDTH FMC_NORSRAM_MEM_BUS_WIDTH_16
+
+#define NOR_BURSTACCESS FMC_BURST_ACCESS_MODE_DISABLE
+/* #define NOR_BURSTACCESS FMC_BURST_ACCESS_MODE_ENABLE*/
+
+#define NOR_WRITEBURST FMC_WRITE_BURST_DISABLE
+/* #define NOR_WRITEBURST FMC_WRITE_BURST_ENABLE */
+
+#define CONTINUOUSCLOCK_FEATURE FMC_CONTINUOUS_CLOCK_SYNC_ONLY
+/* #define CONTINUOUSCLOCK_FEATURE FMC_CONTINUOUS_CLOCK_SYNC_ASYNC */
+
+/* NOR operations Timeout definitions */
+#define BLOCKERASE_TIMEOUT ((uint32_t)0x00A00000) /* NOR block erase timeout */
+#define CHIPERASE_TIMEOUT ((uint32_t)0x30000000) /* NOR chip erase timeout */
+#define PROGRAM_TIMEOUT ((uint32_t)0x00004400) /* NOR program timeout */
+
+/* NOR Ready/Busy signal GPIO definitions */
+#define NOR_READY_BUSY_PIN GPIO_PIN_6
+#define NOR_READY_BUSY_GPIO GPIOC
+#define NOR_READY_STATE GPIO_PIN_SET
+#define NOR_BUSY_STATE GPIO_PIN_RESET
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_NOR_Exported_Macro NOR Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_NOR_Exported_Functions NOR Exported Functions
+ * @{
+ */
+uint8_t BSP_NOR_Init(void);
+uint8_t BSP_NOR_DeInit(void);
+uint8_t BSP_NOR_ReadData(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+uint8_t BSP_NOR_WriteData(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+uint8_t BSP_NOR_ProgramData(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+uint8_t BSP_NOR_Erase_Block(uint32_t BlockAddress);
+uint8_t BSP_NOR_Erase_Chip(void);
+uint8_t BSP_NOR_Read_ID(NOR_IDTypeDef *pNOR_ID);
+void BSP_NOR_ReturnToReadMode(void);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_NOR_MspInit(NOR_HandleTypeDef *hnor, void *Params);
+void BSP_NOR_MspDeInit(NOR_HandleTypeDef *hnor, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_EVAL_NOR_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_qspi.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_qspi.c
new file mode 100644
index 00000000..ed1f59f5
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_qspi.c
@@ -0,0 +1,851 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_eval_qspi.c
+ * @author MCD Application Team
+ * @brief This file includes a standard driver for the N25Q512A QSPI
+ * memory mounted on STM32F769I-EVAL board.
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) This driver is used to drive the N25Q512A QSPI external
+ memory mounted on STM32F769I-EVAL evaluation board.
+
+ (#) This driver need a specific component driver (N25Q512A) to be included with.
+
+ (#) Initialization steps:
+ (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ QSPI interface with the external memory.
+
+ (#) QSPI memory operations
+ (++) QSPI memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_QSPI_Read()/BSP_QSPI_Write().
+ (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory.
+ (see the QSPI memory data sheet)
+ (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by
+ specifying the block address. You can perform an erase operation of the whole
+ chip by calling the function BSP_QSPI_Erase_Chip().
+ (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory.
+ (see the QSPI memory data sheet)
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL
+ * @{
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_EVAL_QSPI_H
+#define __STM32F769I_EVAL_QSPI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+#include "../Components/n25q512a/n25q512a.h"
+
+/** @addtogroup STM32F769I_EVAL_QSPI
+ * @{
+ */
+
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup STM32F769I_EVAL_QSPI_Exported_Constants Exported Constants
+ * @{
+ */
+/* QSPI Error codes */
+#define QSPI_OK ((uint8_t)0x00)
+#define QSPI_ERROR ((uint8_t)0x01)
+#define QSPI_BUSY ((uint8_t)0x02)
+#define QSPI_NOT_SUPPORTED ((uint8_t)0x04)
+#define QSPI_SUSPENDED ((uint8_t)0x08)
+
+
+/* Definition for QSPI clock resources */
+#define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE()
+#define QSPI_CLK_DISABLE() __HAL_RCC_QSPI_CLK_DISABLE()
+#define QSPI_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define QSPI_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define QSPI_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
+#define QSPI_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
+#define QSPI_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
+#define QSPI_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
+
+#define QSPI_FORCE_RESET() __HAL_RCC_QSPI_FORCE_RESET()
+#define QSPI_RELEASE_RESET() __HAL_RCC_QSPI_RELEASE_RESET()
+
+/* Definition for QSPI Pins */
+#define QSPI_CS_PIN GPIO_PIN_6
+#define QSPI_CS_GPIO_PORT GPIOB
+#define QSPI_CLK_PIN GPIO_PIN_2
+#define QSPI_CLK_GPIO_PORT GPIOB
+#define QSPI_D0_PIN GPIO_PIN_8
+#define QSPI_D0_GPIO_PORT GPIOF
+#define QSPI_D1_PIN GPIO_PIN_9
+#define QSPI_D1_GPIO_PORT GPIOF
+#define QSPI_D2_PIN GPIO_PIN_7
+#define QSPI_D2_GPIO_PORT GPIOF
+#define QSPI_D3_PIN GPIO_PIN_6
+#define QSPI_D3_GPIO_PORT GPIOF
+
+/* N25Q512A13GSF40E Micron memory */
+/* Size of the flash */
+#define QSPI_FLASH_SIZE 25 /* Address bus width to access whole memory space */
+#define QSPI_PAGE_SIZE 256
+
+/**
+ * @}
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup STM32F769I_EVAL_QSPI_Exported_Types Exported Types
+ * @{
+ */
+/* QSPI Info */
+typedef struct {
+ uint32_t FlashSize; /*!< Size of the flash */
+ uint32_t EraseSectorSize; /*!< Size of sectors for the erase operation */
+ uint32_t EraseSectorsNumber; /*!< Number of sectors for the erase operation */
+ uint32_t ProgPageSize; /*!< Size of pages for the program operation */
+ uint32_t ProgPagesNumber; /*!< Number of pages for the program operation */
+} QSPI_Info;
+
+/**
+ * @}
+ */
+
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup STM32F769I_EVAL_QSPI_Exported_Functions
+ * @{
+ */
+uint8_t BSP_QSPI_Init (void);
+uint8_t BSP_QSPI_DeInit (void);
+uint8_t BSP_QSPI_Read (uint8_t* pData, uint32_t ReadAddr, uint32_t Size);
+uint8_t BSP_QSPI_Write (uint8_t* pData, uint32_t WriteAddr, uint32_t Size);
+uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress);
+uint8_t BSP_QSPI_Erase_Chip (void);
+uint8_t BSP_QSPI_GetStatus (void);
+uint8_t BSP_QSPI_GetInfo (QSPI_Info* pInfo);
+uint8_t BSP_QSPI_EnableMemoryMappedMode(void);
+
+/* These functions can be modified in case the current settings
+ need to be changed for specific application needs */
+void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params);
+void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_EVAL_QSPI_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_sd.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_sd.c
new file mode 100644
index 00000000..96772b99
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_sd.c
@@ -0,0 +1,1027 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_eval_sd.c
+ * @author MCD Application Team
+ * @brief This file includes the uSD card driver mounted on STM32F769I-EVAL
+ * evaluation boards.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ - This driver is used to drive the micro SD external cards mounted on STM32F769I-EVAL
+ evaluation board.
+ - This driver does not need a specific component driver for the micro SD device
+ to be included with.
+
+ Driver description:
+ ------------------
+ + Initialization steps:
+ o Initialize the micro SD card using the BSP_SD_InitEx() function. This
+ function includes the MSP layer hardware resources initialization and the
+ SDIO interface configuration to interface with the external micro SD. It
+ also includes the micro SD initialization sequence for SDCard1 or SDCard2.
+ When BSP_SD_Init() is called, SDCard1 is by default initialized.
+ o To check the SD card presence you can use the function BSP_SD_IsDetectedEx() which
+ returns the detection status for SDCard1 or SDCard2.
+ the function BSP_SD_IsDetected() returns the detection status for SDCard1.
+ o If SD presence detection interrupt mode is desired, you must configure the
+ SD detection interrupt mode by calling the functions BSP_SD_ITConfig() for
+ SDCard1 or BSP_SD_ITConfigEx() for SDCard2 . The interrupt is generated as
+ an external interrupt whenever the micro SD card is plugged/unplugged
+ in/from the evaluation board. The SD detection is managed by MFX, so the
+ SD detection interrupt has to be treated by MFX_IRQOUT gpio pin IRQ handler.
+ o The function BSP_SD_GetCardInfo()/BSP_SD_GetCardInfoEx() are used to get
+ the micro SD card information which is stored in the structure
+ "HAL_SD_CardInfoTypedef".
+
+ + Micro SD card operations
+ o The micro SD card can be accessed with read/write block(s) operations once
+ it is ready for access. The access, by default to SDCard1, can be performed whether
+ using the polling mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks(),
+ or by DMA transfer using the functions BSP_SD_ReadBlocks_DMA()/BSP_SD_WriteBlocks_DMA().
+ The access can be performed to SDCard1 or SDCard2 by calling BSP_SD_ReadBlocksEx(),
+ BSP_SD_WriteBlocksEx() or by calling BSP_SD_ReadBlocks_DMAEx()/BSP_SD_WriteBlocks_DMAEx().
+ o The DMA transfer complete is used with interrupt mode. Once the SD transfer
+ is complete, the SD interrupt is handled using the function BSP_SDMMC1_IRQHandler()
+ when SDCard1 is used or BSP_SDMMC2_IRQHandler() when SDCard2 is used.
+ The DMA Tx/Rx transfer complete are handled using the functions
+ BSP_SDMMC1_DMA_Tx_IRQHandler(), BSP_SDMMC1_DMA_Rx_IRQHandler(),
+ BSP_SDMMC2_DMA_Tx_IRQHandler(), BSP_SDMMC2_DMA_Rx_IRQHandler(). The corresponding
+ user callbacks are implemented by the user at application level.
+ o The SD erase block(s) is performed using the functions BSP_SD_Erase()/BSP_SD_EraseEx()
+ with specifying the number of blocks to erase.
+ o The SD runtime status is returned when calling the function BSP_SD_GetCardState()
+ BSP_SD_GetCardStateEx().
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_EVAL_SD_H
+#define __STM32F769I_EVAL_SD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+#include "stm32f769i_eval_io.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL_SD
+ * @{
+ */
+
+/** @defgroup STM32F769I_EVAL_SD_Exported_Types SD Exported Types
+ * @{
+ */
+
+/**
+ * @brief SD Card information structure
+ */
+#define BSP_SD_CardInfo HAL_SD_CardInfoTypeDef
+/**
+ * @}
+ */
+
+/**
+ * @brief SD status structure definition
+ */
+#define MSD_OK ((uint8_t)0x00)
+#define MSD_ERROR ((uint8_t)0x01)
+#define MSD_ERROR_SD_NOT_PRESENT ((uint8_t)0x02)
+
+/**
+ * @brief SD transfer state definition
+ */
+#define SD_TRANSFER_OK ((uint8_t)0x00)
+#define SD_TRANSFER_BUSY ((uint8_t)0x01)
+
+/** @defgroup STM32F769I_EVAL_SD_Exported_Constants SD Exported Constants
+ * @{
+ */
+#define SD_PRESENT ((uint8_t)0x01)
+#define SD_NOT_PRESENT ((uint8_t)0x00)
+
+#define SD_CARD1 ((uint32_t)0x00)
+#define SD_CARD2 ((uint32_t)0x01)
+
+#define SD_DATATIMEOUT ((uint32_t)100000000)
+
+/* DMA definitions for SD DMA transfer */
+#define __DMAx_TxRx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
+#define SD1_DMAx_Tx_CHANNEL DMA_CHANNEL_4
+#define SD1_DMAx_Rx_CHANNEL DMA_CHANNEL_4
+#define SD1_DMAx_Tx_STREAM DMA2_Stream6
+#define SD1_DMAx_Rx_STREAM DMA2_Stream3
+#define SD1_DMAx_Tx_IRQn DMA2_Stream6_IRQn
+#define SD1_DMAx_Rx_IRQn DMA2_Stream3_IRQn
+#define BSP_SDMMC1_DMA_Tx_IRQHandler DMA2_Stream6_IRQHandler
+#define BSP_SDMMC1_DMA_Rx_IRQHandler DMA2_Stream3_IRQHandler
+#define BSP_SDMMC1_IRQHandler SDMMC1_IRQHandler
+
+#define SD2_DMAx_Tx_CHANNEL DMA_CHANNEL_11
+#define SD2_DMAx_Rx_CHANNEL DMA_CHANNEL_11
+#define SD2_DMAx_Tx_STREAM DMA2_Stream5
+#define SD2_DMAx_Rx_STREAM DMA2_Stream0
+#define SD2_DMAx_Tx_IRQn DMA2_Stream5_IRQn
+#define SD2_DMAx_Rx_IRQn DMA2_Stream0_IRQn
+#define BSP_SDMMC2_DMA_Tx_IRQHandler DMA2_Stream5_IRQHandler
+#define BSP_SDMMC2_DMA_Rx_IRQHandler DMA2_Stream0_IRQHandler
+#define BSP_SDMMC2_IRQHandler SDMMC2_IRQHandler
+
+#define SD_DetectIRQHandler() HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8)
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_SD_Exported_Macro SD Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_SD_Exported_Functions SD Exported Functions
+ * @{
+ */
+uint8_t BSP_SD_Init(void);
+uint8_t BSP_SD_InitEx(uint32_t SdCard);
+uint8_t BSP_SD_DeInit(void);
+uint8_t BSP_SD_DeInitEx(uint32_t SdCard);
+uint8_t BSP_SD_ITConfig(void);
+uint8_t BSP_SD_ITConfigEx(uint32_t SdCard);
+uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout);
+uint8_t BSP_SD_ReadBlocksEx(uint32_t SdCard, uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout);
+uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout);
+uint8_t BSP_SD_WriteBlocksEx(uint32_t SdCard, uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout);
+uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks);
+uint8_t BSP_SD_ReadBlocks_DMAEx(uint32_t SdCard, uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks);
+uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks);
+uint8_t BSP_SD_WriteBlocks_DMAEx(uint32_t SdCard, uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks);
+uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr);
+uint8_t BSP_SD_EraseEx(uint32_t SdCard, uint32_t StartAddr, uint32_t EndAddr);
+uint8_t BSP_SD_GetCardState(void);
+uint8_t BSP_SD_GetCardStateEx(uint32_t SdCard);
+void BSP_SD_GetCardInfo(BSP_SD_CardInfo *CardInfo);
+void BSP_SD_GetCardInfoEx(uint32_t SdCard, BSP_SD_CardInfo *CardInfo);
+uint8_t BSP_SD_IsDetected(void);
+uint8_t BSP_SD_IsDetectedEx(uint32_t SdCard);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params);
+void BSP_SD_MspDeInit(SD_HandleTypeDef *hsd, void *Params);
+void BSP_SD_AbortCallback(uint32_t SdCard);
+void BSP_SD_WriteCpltCallback(uint32_t SdCard);
+void BSP_SD_ReadCpltCallback(uint32_t SdCard);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_EVAL_SD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_sdram.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_sdram.c
new file mode 100644
index 00000000..f76cf475
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_sdram.c
@@ -0,0 +1,503 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_eval_sdram.c
+ * @author MCD Application Team
+ * @brief This file includes the SDRAM driver for the MT48LC4M32B2B5-7 memory
+ * device mounted on STM32F769I-EVAL evaluation boards.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ - This driver is used to drive the MT48LC4M32B2B5-7 SDRAM external memory mounted
+ on STM32F769I-EVAL evaluation board.
+ - This driver does not need a specific component driver for the SDRAM device
+ to be included with.
+
+ Driver description:
+ ------------------
+ + Initialization steps:
+ o Initialize the SDRAM external memory using the BSP_SDRAM_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ FMC controller configuration to interface with the external SDRAM memory.
+ o It contains the SDRAM initialization sequence to program the SDRAM external
+ device using the function BSP_SDRAM_Initialization_sequence(). Note that this
+ sequence is standard for all SDRAM devices, but can include some differences
+ from a device to another. If it is the case, the right sequence should be
+ implemented separately.
+
+ + SDRAM read/write operations
+ o SDRAM external memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_SDRAM_ReadData()/BSP_SDRAM_WriteData(), or by DMA transfer using the functions
+ BSP_SDRAM_ReadData_DMA()/BSP_SDRAM_WriteData_DMA().
+ o The AHB access is performed with 32-bit width transaction, the DMA transfer
+ configuration is fixed at single (no burst) word transfer (see the
+ SDRAM_MspInit() static function).
+ o User can implement his own functions for read/write access with his desired
+ configurations.
+ o If interrupt mode is used for DMA transfer, the function BSP_SDRAM_DMA_IRQHandler()
+ is called in IRQ handler file, to serve the generated interrupt once the DMA
+ transfer is complete.
+ o You can send a command to the SDRAM device in runtime using the function
+ BSP_SDRAM_Sendcmd(), and giving the desired command as parameter chosen between
+ the predefined commands of the "FMC_SDRAM_CommandTypeDef" structure.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_EVAL_SDRAM_H
+#define __STM32F769I_EVAL_SDRAM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL_SDRAM
+ * @{
+ */
+
+/** @defgroup STM32F769I_EVAL_SDRAM_Exported_Types SDRAM Exported Types
+ * @{
+ */
+
+/**
+ * @brief SDRAM status structure definition
+ */
+#define SDRAM_OK ((uint8_t)0x00)
+#define SDRAM_ERROR ((uint8_t)0x01)
+
+/** @defgroup STM32F769I_EVAL_SDRAM_Exported_Constants SDRAM Exported Constants
+ * @{
+ */
+#define SDRAM_DEVICE_ADDR ((uint32_t)0xC0000000)
+#define SDRAM_DEVICE_SIZE ((uint32_t)0x2000000) /* SDRAM device size in MBytes */
+
+/* #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_8 */
+/* #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16 */
+#define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_32
+
+#define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_2
+/* #define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_3 */
+
+#define REFRESH_COUNT ((uint32_t)0x0603) /* SDRAM refresh counter (100Mhz SD clock) */
+
+#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
+
+/* DMA definitions for SDRAM DMA transfer */
+#define __DMAx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
+#define __DMAx_CLK_DISABLE __HAL_RCC_DMA2_CLK_DISABLE
+#define SDRAM_DMAx_CHANNEL DMA_CHANNEL_0
+#define SDRAM_DMAx_STREAM DMA2_Stream0
+#define SDRAM_DMAx_IRQn DMA2_Stream0_IRQn
+#define BSP_SDRAM_DMA_IRQHandler DMA2_Stream0_IRQHandler
+/**
+ * @}
+ */
+
+/**
+ * @brief FMC SDRAM Mode definition register defines
+ */
+#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
+#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
+#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
+#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
+#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
+#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
+#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
+#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
+#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
+#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
+#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_SDRAM_Exported_Macro SDRAM Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_SDRAM_Exported_Functions SDRAM Exported Functions
+ * @{
+ */
+uint8_t BSP_SDRAM_Init(void);
+uint8_t BSP_SDRAM_DeInit(void);
+void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount);
+uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram, void *Params);
+void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram, void *Params);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_EVAL_SDRAM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_sram.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_sram.c
new file mode 100644
index 00000000..ed7b6eab
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_sram.c
@@ -0,0 +1,402 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_eval_sram.c
+ * @author MCD Application Team
+ * @brief This file includes the SRAM driver for the IS61WV102416BLL-10M memory
+ * device mounted on STM32F769I-EVAL evaluation boards.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ - This driver is used to drive the IS61WV102416BLL-10M SRAM external memory mounted
+ on STM32F769I-EVAL evaluation board.
+ - This driver does not need a specific component driver for the SRAM device
+ to be included with.
+
+ Driver description:
+ ------------------
+ + Initialization steps:
+ o Initialize the SRAM external memory using the BSP_SRAM_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ FMC controller configuration to interface with the external SRAM memory.
+
+ + SRAM read/write operations
+ o SRAM external memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_SRAM_ReadData()/BSP_SRAM_WriteData(), or by DMA transfer using the functions
+ BSP_SRAM_ReadData_DMA()/BSP_SRAM_WriteData_DMA().
+ o The AHB access is performed with 16-bit width transaction, the DMA transfer
+ configuration is fixed at single (no burst) halfword transfer
+ (see the SRAM_MspInit() static function).
+ o User can implement his own functions for read/write access with his desired
+ configurations.
+ o If interrupt mode is used for DMA transfer, the function BSP_SRAM_DMA_IRQHandler()
+ is called in IRQ handler file, to serve the generated interrupt once the DMA
+ transfer is complete.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F769I_EVAL_SRAM_H
+#define __STM32F769I_EVAL_SRAM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL_SRAM
+ * @{
+ */
+
+/** @defgroup STM32F769I_EVAL_SRAM_Exported_Types SRAM Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_SRAM_Exported_Constants SRAM Exported Constants
+ * @{
+ */
+
+/**
+ * @brief SRAM status structure definition
+ */
+#define SRAM_OK ((uint8_t)0x00)
+#define SRAM_ERROR ((uint8_t)0x01)
+
+#define SRAM_DEVICE_ADDR ((uint32_t)0x68000000)
+#define SRAM_DEVICE_SIZE ((uint32_t)0x200000) /* SRAM device size in MBytes */
+
+/* #define SRAM_MEMORY_WIDTH FMC_NORSRAM_MEM_BUS_WIDTH_8*/
+#define SRAM_MEMORY_WIDTH FMC_NORSRAM_MEM_BUS_WIDTH_16
+
+#define SRAM_BURSTACCESS FMC_BURST_ACCESS_MODE_DISABLE
+/* #define SRAM_BURSTACCESS FMC_BURST_ACCESS_MODE_ENABLE*/
+
+#define SRAM_WRITEBURST FMC_WRITE_BURST_DISABLE
+/* #define SRAM_WRITEBURST FMC_WRITE_BURST_ENABLE */
+
+#define CONTINUOUSCLOCK_FEATURE FMC_CONTINUOUS_CLOCK_SYNC_ONLY
+/* #define CONTINUOUSCLOCK_FEATURE FMC_CONTINUOUS_CLOCK_SYNC_ASYNC */
+
+/* DMA definitions for SRAM DMA transfer */
+#define __SRAM_DMAx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
+#define __SRAM_DMAx_CLK_DISABLE __HAL_RCC_DMA2_CLK_DISABLE
+#define SRAM_DMAx_CHANNEL DMA_CHANNEL_0
+#define SRAM_DMAx_STREAM DMA2_Stream4
+#define SRAM_DMAx_IRQn DMA2_Stream4_IRQn
+#define BSP_SRAM_DMA_IRQHandler DMA2_Stream4_IRQHandler
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_SRAM_Exported_Macro SRAM Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_SRAM_Exported_Functions SRAM Exported Functions
+ * @{
+ */
+uint8_t BSP_SRAM_Init(void);
+uint8_t BSP_SRAM_DeInit(void);
+uint8_t BSP_SRAM_ReadData(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SRAM_ReadData_DMA(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SRAM_WriteData(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SRAM_WriteData_DMA(uint32_t uwStartAddress, uint16_t *pData, uint32_t uwDataSize);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_SRAM_MspInit(SRAM_HandleTypeDef *hsram, void *Params);
+void BSP_SRAM_MspDeInit(SRAM_HandleTypeDef *hsram, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F769I_EVAL_SRAM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_ts.c b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_ts.c
new file mode 100644
index 00000000..0e819171
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_ts.c
@@ -0,0 +1,499 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_eval_ts.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the Touch
+ * Screen on STM32F769I-EVAL evaluation board.
+ ******************************************************************************
+ * @attention
+ *
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* File Info : -----------------------------------------------------------------
+ User NOTES
+1. How To use this driver:
+--------------------------
+ - This driver is used to drive the touch screen module of the STM32F769I-EVAL
+ evaluation board on the K.O.D Optica Technology 480x800 TFT-LCD mounted on
+ MB1166 daughter board. The touch screen driver IC inside the K.O.D module KM-040TMP-02
+ is a FT6206 by Focal Tech.
+
+2. Driver description:
+---------------------
+ + Initialization steps:
+ o Initialize the TS module using the BSP_TS_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ communication layer configuration to start the TS use. The LCD size properties
+ (x and y) are passed as parameters.
+ o If TS interrupt mode is desired, you must configure the TS interrupt mode
+ by calling the function BSP_TS_ITConfig(). The TS interrupt mode is generated
+ as an external interrupt whenever a touch is detected.
+ The interrupt mode internally uses the IO functionalities driver driven by
+ the IO expander, to configure the IT line.
+
+ + Touch screen use
+ o The touch screen state is captured whenever the function BSP_TS_GetState() is
+ used. This function returns information about the last LCD touch occurred
+ in the TS_StateTypeDef structure.
+ o If TS interrupt mode is used, the function BSP_TS_ITGetStatus() is needed to get
+ the interrupt status. To clear the IT pending bits, you should call the
+ function BSP_TS_ITClear().
+ o The IT is handled using the corresponding external interrupt IRQ handler,
+ the user IT callback treatment is implemented on the same external interrupt
+ callback.
+
+------------------------------------------------------------------------------*/
+/* Dependencies
+- stm32f769i_eval_lcd.c
+- ft6x06.c
+EndDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f769i_eval.h"
+#include "stm32f769i_eval_ts.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F769I_EVAL
+ * @{
+ */
+
+/** @defgroup STM32F769I_EVAL_TS STM32F769I_EVAL TS
+ * @{
+ */
+
+/** @defgroup STM32F769I_EVAL_TS_Private_Types_Definitions TS Private Types Definitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_TS_Private_Defines TS Private Types Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_TS_Private_Macros TS Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_TS_Imported_Variables TS Imported Variables
+ * @{
+ */
+ /**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_TS_Private_Variables TS Private Variables
+ * @{
+ */
+static TS_DrvTypeDef *ts_driver;
+static uint8_t ts_orientation;
+uint8_t I2C_Address = 0;
+
+/* Table for touchscreen event information display on LCD : table indexed on enum @ref TS_TouchEventTypeDef information */
+char * ts_event_string_tab[TOUCH_EVENT_NB_MAX] = { "None",
+ "Press down",
+ "Lift up",
+ "Contact"
+ };
+
+/* Table for touchscreen gesture Id information display on LCD : table indexed on enum @ref TS_GestureIdTypeDef information */
+char * ts_gesture_id_string_tab[GEST_ID_NB_MAX] = { "None",
+ "Move Up",
+ "Move Right",
+ "Move Down",
+ "Move Left",
+ "Zoom In",
+ "Zoom Out"
+ };
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_TS_Private_Function_Prototypes TS Private Function Prototypes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F769I_EVAL_TS_Public_Functions TS Public Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes and configures the touch screen functionalities and
+ * configures all necessary hardware resources (GPIOs, I2C, clocks..).
+ * @param ts_SizeX : Maximum X size of the TS area on LCD
+ * @param ts_SizeY : Maximum Y size of the TS area on LCD
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_Init(uint16_t ts_SizeX, uint16_t ts_SizeY)
+{
+ uint8_t ts_status = TS_OK;
+ uint8_t ts_id1, ts_id2 = 0;
+ /* Note : I2C_Address is un-initialized here, but is not used at all in init function */
+ /* but the prototype of Init() is like that in template and should be respected */
+
+ /* Initialize the communication channel to sensor (I2C) if necessary */
+ /* that is initialization is done only once after a power up */
+ ft6x06_ts_drv.Init(I2C_Address);
+
+ ts_id1 = ft6x06_ts_drv.ReadID(TS_I2C_ADDRESS);
+ if(ts_id1 != FT6206_ID_VALUE)
+ {
+ ts_id2 = ft6x06_ts_drv.ReadID(TS_I2C_ADDRESS_A02);
+ I2C_Address = TS_I2C_ADDRESS_A02;
+ }
+ else
+ {
+ I2C_Address = TS_I2C_ADDRESS;
+ }
+
+ /* Scan FT6xx6 TouchScreen IC controller ID register by I2C Read */
+ /* Verify this is a FT6206 or FT6336G, otherwise this is an error case */
+ if((ts_id1 == FT6206_ID_VALUE) || (ts_id2 == FT6206_ID_VALUE))
+ {
+ /* Found FT6206 : Initialize the TS driver structure */
+ ts_driver = &ft6x06_ts_drv;
+
+ /* Get LCD chosen orientation */
+ if(ts_SizeX < ts_SizeY)
+ {
+ ts_orientation = TS_SWAP_NONE;
+ }
+ else
+ {
+ ts_orientation = TS_SWAP_XY | TS_SWAP_Y;
+ }
+
+ if(ts_status == TS_OK)
+ {
+ /* Software reset the TouchScreen */
+ ts_driver->Reset(I2C_Address);
+
+ /* Calibrate, Configure and Start the TouchScreen driver */
+ ts_driver->Start(I2C_Address);
+
+ } /* of if(ts_status == TS_OK) */
+ }
+ else
+ {
+ ts_status = TS_DEVICE_NOT_FOUND;
+ }
+
+ return (ts_status);
+}
+
+/**
+ * @brief Configures and enables the touch screen interrupts.
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_ITConfig(void)
+{
+ uint8_t ts_status = TS_ERROR;
+ uint8_t io_status = IO_ERROR;
+
+ /* Initialize the IO */
+ io_status = BSP_IO_Init();
+ if(io_status != IO_OK)
+ {
+ return (ts_status);
+ }
+
+ /* Configure TS IT line IO : is active low on FT6206 (see data sheet) */
+ /* Configure TS_INT_PIN (MFX_IO_14) low level to generate MFX_IRQ_OUT in EXTI on MCU */
+ io_status = BSP_IO_ConfigPin(TS_INT_PIN, IO_MODE_IT_LOW_LEVEL_PU);
+ if(io_status != IO_OK)
+ {
+ return (ts_status);
+ }
+
+ /* Enable the TS in interrupt mode */
+ /* In that case the INT output of FT6206 when new touch is available */
+ /* is active low and directed on MFX IO14 */
+ ts_driver->EnableIT(I2C_Address);
+
+ /* If arrived here : set good status on exit */
+ ts_status = TS_OK;
+
+ return (ts_status);
+}
+
+/**
+ * @brief Gets the touch screen interrupt status.
+ * @retval TS_IRQ_PENDING if touchscreen IRQ is pending, TS_NO_IRQ_PENDING when no IRQ TS is pending.
+ */
+uint8_t BSP_TS_ITGetStatus(void)
+{
+ uint8_t itStatus = TS_NO_IRQ_PENDING; /* By default no IRQ TS pending */
+ uint32_t mfx_irq_status = 0; /* No MFX IRQ by default */
+
+ /* Check status of MFX_IO14 in particular which is the Touch Screen INT pin active low */
+ mfx_irq_status = BSP_IO_ITGetStatus(TS_INT_PIN);
+ if(mfx_irq_status != 0) /* Note : returned mfx_irq_status = 0x4000 == (1<touchDetected = ts_driver->DetectTouch(I2C_Address);
+ if(TS_State->touchDetected)
+ {
+ for(index=0; index < TS_State->touchDetected; index++)
+ {
+ /* Get each touch coordinates */
+ ts_driver->GetXY(I2C_Address, &(Raw_x[index]), &(Raw_y[index]));
+
+ if(ts_orientation & TS_SWAP_XY)
+ {
+ tmp = Raw_x[index];
+ Raw_x[index] = Raw_y[index];
+ Raw_y[index] = tmp;
+ }
+
+ if(ts_orientation & TS_SWAP_X)
+ {
+ Raw_x[index] = FT_6206_MAX_WIDTH - 1 - Raw_x[index];
+ }
+
+ if(ts_orientation & TS_SWAP_Y)
+ {
+ Raw_y[index] = FT_6206_MAX_HEIGHT - 1 - Raw_y[index];
+ }
+
+ xDiff = Raw_x[index] > _x[index]? (Raw_x[index] - _x[index]): (_x[index] - Raw_x[index]);
+ yDiff = Raw_y[index] > _y[index]? (Raw_y[index] - _y[index]): (_y[index] - Raw_y[index]);
+
+ if ((xDiff + yDiff) > 5)
+ {
+ _x[index] = Raw_x[index];
+ _y[index] = Raw_y[index];
+ }
+
+
+ TS_State->touchX[index] = _x[index];
+ TS_State->touchY[index] = _y[index];
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+
+ /* Get touch info related to the current touch */
+ ft6x06_TS_GetTouchInfo(I2C_Address, index, &weight, &area, &event);
+
+ /* Update TS_State structure */
+ TS_State->touchWeight[index] = weight;
+ TS_State->touchArea[index] = area;
+
+ /* Remap touch event */
+ switch(event)
+ {
+ case FT6206_TOUCH_EVT_FLAG_PRESS_DOWN :
+ TS_State->touchEventId[index] = TOUCH_EVENT_PRESS_DOWN;
+ break;
+ case FT6206_TOUCH_EVT_FLAG_LIFT_UP :
+ TS_State->touchEventId[index] = TOUCH_EVENT_LIFT_UP;
+ break;
+ case FT6206_TOUCH_EVT_FLAG_CONTACT :
+ TS_State->touchEventId[index] = TOUCH_EVENT_CONTACT;
+ break;
+ case FT6206_TOUCH_EVT_FLAG_NO_EVENT :
+ TS_State->touchEventId[index] = TOUCH_EVENT_NO_EVT;
+ break;
+ default :
+ ts_status = TS_ERROR;
+ break;
+ } /* of switch(event) */
+
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+ } /* of for(index=0; index < TS_State->touchDetected; index++) */
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+ /* Get gesture Id */
+ ts_status = BSP_TS_Get_GestureId(TS_State);
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+ } /* end of if(TS_State->touchDetected != 0) */
+
+ return (ts_status);
+}
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+/**
+ * @brief Update gesture Id following a touch detected.
+ * @param TS_State: Pointer to touch screen current state structure
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_Get_GestureId(TS_StateTypeDef *TS_State)
+{
+ uint32_t gestureId = 0;
+ uint8_t ts_status = TS_OK;
+
+ /* Get gesture Id */
+ ft6x06_TS_GetGestureID(I2C_Address, &gestureId);
+
+ /* Remap gesture Id to a TS_GestureIdTypeDef value */
+ switch(gestureId)
+ {
+ case FT6206_GEST_ID_NO_GESTURE :
+ TS_State->gestureId = GEST_ID_NO_GESTURE;
+ break;
+ case FT6206_GEST_ID_MOVE_UP :
+ TS_State->gestureId = GEST_ID_MOVE_UP;
+ break;
+ case FT6206_GEST_ID_MOVE_RIGHT :
+ TS_State->gestureId = GEST_ID_MOVE_RIGHT;
+ break;
+ case FT6206_GEST_ID_MOVE_DOWN :
+ TS_State->gestureId = GEST_ID_MOVE_DOWN;
+ break;
+ case FT6206_GEST_ID_MOVE_LEFT :
+ TS_State->gestureId = GEST_ID_MOVE_LEFT;
+ break;
+ case FT6206_GEST_ID_ZOOM_IN :
+ TS_State->gestureId = GEST_ID_ZOOM_IN;
+ break;
+ case FT6206_GEST_ID_ZOOM_OUT :
+ TS_State->gestureId = GEST_ID_ZOOM_OUT;
+ break;
+ default :
+ ts_status = TS_ERROR;
+ break;
+ } /* of switch(gestureId) */
+
+ return(ts_status);
+}
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+
+/**
+ * @brief Clears all touch screen interrupts.
+ */
+void BSP_TS_ITClear(void)
+{
+ /* Clear TS_INT_PIN IRQ in MFX */
+ BSP_IO_ITClearPin(TS_INT_PIN);
+}
+
+
+/** @defgroup STM32F769I_EVAL_TS_Private_Functions TS Private Functions
+ * @{
+ */
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+/**
+ * @brief Function used to reset all touch data before a new acquisition
+ * of touch information.
+ * @param TS_State: Pointer to touch screen current state structure
+ * @retval TS_OK if OK, TE_ERROR if problem found.
+ */
+uint8_t BSP_TS_ResetTouchData(TS_StateTypeDef *TS_State)
+{
+ uint8_t ts_status = TS_ERROR;
+ uint32_t index;
+
+ if (TS_State != (TS_StateTypeDef *)NULL)
+ {
+ TS_State->gestureId = GEST_ID_NO_GESTURE;
+ TS_State->touchDetected = 0;
+
+ for(index = 0; index < TS_MAX_NB_TOUCH; index++)
+ {
+ TS_State->touchX[index] = 0;
+ TS_State->touchY[index] = 0;
+ TS_State->touchArea[index] = 0;
+ TS_State->touchEventId[index] = TOUCH_EVENT_NO_EVT;
+ TS_State->touchWeight[index] = 0;
+ }
+
+ ts_status = TS_OK;
+
+ } /* of if (TS_State != (TS_StateTypeDef *)NULL) */
+
+ return (ts_status);
+}
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_ts.h b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_ts.h
new file mode 100644
index 00000000..26541091
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F769I_EVAL/stm32f769i_eval_ts.h
@@ -0,0 +1,210 @@
+/**
+ ******************************************************************************
+ * @file stm32f769i_eval_ts.h
+ * @author MCD Application Team
+ * @brief This file contains the common defines and functions prototypes for
+ * the stm32f769i_eval_ts.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
Release
+Notes for STM32F7xx_Nucleo_144 Board Drivers
+
Copyright
+2015 STMicroelectronics
+
+
+
+
+
+
+
+
+
+
+
+
Update History
V1.0.0 / 18-November-2015
+
+
Main
+Changes
+
+
First official release
License
+
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived
+
+
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
For
+complete documentation on STM32 Microcontrollers
+visit www.st.com/STM32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/port_stm32f7/common/bsp_drivers/STM32F7xx_Nucleo_144/stm32f7xx_nucleo_144.c b/src/port_stm32f7/common/bsp_drivers/STM32F7xx_Nucleo_144/stm32f7xx_nucleo_144.c
new file mode 100644
index 00000000..405f83db
--- /dev/null
+++ b/src/port_stm32f7/common/bsp_drivers/STM32F7xx_Nucleo_144/stm32f7xx_nucleo_144.c
@@ -0,0 +1,919 @@
+/**
+ ******************************************************************************
+ * @file stm32f7xx_nucleo_144.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 18-November-2015
+ * @brief This file provides set of firmware functions to manage:
+ * - LEDs and push-button available on STM32F7XX-Nucleo-144 Kit
+ * from STMicroelectronics
+ * - LCD, joystick and microSD available on Adafruit 1.8" TFT LCD
+ * shield (reference ID 802)
+ ******************************************************************************
+ * @attention
+ *
+ *
+ */
diff --git a/src/port_stm32f7/common/stm32f7xx_hal_timebase_tim.c b/src/port_stm32f7/common/stm32f7xx_hal_timebase_tim.c
new file mode 100644
index 00000000..e9251eec
--- /dev/null
+++ b/src/port_stm32f7/common/stm32f7xx_hal_timebase_tim.c
@@ -0,0 +1,181 @@
+/**
+ ******************************************************************************
+ * @file stm32f7xx_hal_timebase_tim6.c
+ * @author MCD Application Team
+ * @brief HAL time base based on the hardware TIM6.
+ *
+ * This file overrides the native HAL time base functions (defined as weak)
+ * the TIM time base:
+ * + Initializes the TIM peripheral generate a Period elapsed Event each 1ms
+ * + HAL_IncTick is called inside HAL_TIM_PeriodElapsedCallback ie each 1ms
+ *
+ ******************************************************************************
+ * @attention
+ *
+ *