diff --git a/Drivers/BSP/STM32F429I-Discovery/.github/ISSUE_TEMPLATE.md b/Drivers/BSP/STM32F429I-Discovery/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000..8d49e8b
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,37 @@
+---
+name: 'Issue report'
+about: 'Create a report to help us improve the quality of our software'
+title: ''
+labels: ''
+assignees: ''
+---
+
+**Caution**
+
+The Issues are strictly limited for the reporting of problem encountered with the software provided in this project.
+For any other problem related to the STM32 product, the performance, the hardware characteristics and boards, the tools the environment in general, please post your report to the **ST Community** in the STM32 MCUs dedicated [page](https://community.st.com/s/group/0F90X000000AXsASAW/stm32-mcus).
+
+**Describe the set-up**
+
+ * The board (either ST RPN reference or your custom board)
+ * IDE or at least the compiler and its version
+
+**Describe the bug (skip if none)**
+
+A clear and concise description of what the bug is.
+
+**How to reproduce the bug (skip if none)**
+
+1. Indicate the global behavior of your application project
+2. List the modules that you suspect to be the cause of the problem (Drivers, BSP, MW...)
+3. Describe the use case that generates the problem
+4. How we can reproduce the problem
+
+
+**Additional context**
+
+If you have a first analysis, an enhancement, a fix or a patch, thank you to share your proposal.
+
+**Screenshots**
+
+If applicable, add screenshots to help explain your problem.
diff --git a/Drivers/BSP/STM32F429I-Discovery/.github/PULL_REQUEST_TEMPLATE.md b/Drivers/BSP/STM32F429I-Discovery/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..a2581a4
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,5 @@
+## IMPORTANT INFORMATION
+
+### Contributor License Agreement (CLA)
+* The Pull Request feature will be considered by STMicroelectronics after the signature of a **Contributor License Agreement (CLA)** by the submitter.
+* If you did not sign such agreement, please follow the steps mentioned in the [CONTRIBUTING.md](https://github.com/STMicroelectronics/stm32f429i-discovery/blob/main/CONTRIBUTING.md) file.
diff --git a/Drivers/BSP/STM32F429I-Discovery/CODE_OF_CONDUCT.md b/Drivers/BSP/STM32F429I-Discovery/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..8f8955a
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/CODE_OF_CONDUCT.md
@@ -0,0 +1,73 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, sex characteristics, gender identity and expression,
+level of experience, education, socio-economic status, nationality, personal
+appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team via this [link](https://www.st.com/content/st_com/en/contact-us.html).
+All complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4,
+available [here](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html).
+
+For answers to common questions about this code of conduct, see the [FAQ section](https://www.contributor-covenant.org/faq).
diff --git a/Drivers/BSP/STM32F429I-Discovery/CONTRIBUTING.md b/Drivers/BSP/STM32F429I-Discovery/CONTRIBUTING.md
new file mode 100644
index 0000000..8b65c58
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/CONTRIBUTING.md
@@ -0,0 +1,38 @@
+## Contributing guide
+
+This document serves as a checklist before contributing to this repository.
+It includes links to read up on if topics are unclear to you.
+
+This guide mainly focuses on steps to be followed to submit an issue or a pull-request.
+
+### 1. Before opening an issue
+
+To report a bug or a request please file an issue in the right repository
+(example for [stm32f429i-discovery](https://github.com/STMicroelectronics/stm32f429i-discovery/issues/new/choose)).
+
+Please check the following boxes before posting an issue:
+- [ ] `Make sure you are using the latest commit (major releases are tagged, but corrections are available as new commits).`
+- [ ] `Make sure your issue is a question/feedback/suggestions RELATED TO the software provided in this repository.` Otherwise, it should be submitted to the **ST Community** on the appropriate topic [page](https://community.st.com/s/topiccatalog).
+- [ ] `Make sure your issue is not already reported/fixed on GitHub or discussed on a previous issue.` Please refer to this [dashboard](https://github.com/orgs/STMicroelectronics/projects/2) for the list of issues and pull-requests. Do not forget to browse into the **closed** issues.
+
+### 2. Posting the issue
+
+When you have checked the previous boxes, create a new report from the **Issues** tab of the repository. A template is available to help you report the issue you are facing or the enhancement you would like to propose.
+
+### 3. Pull Requests
+
+STMicrolectronics is happy to receive contributions from the community, based on an initial Contributor License Agreement (CLA) procedure.
+
+* If you are an individual writing original source code and you are sure **you own the intellectual property**, then you need to sign an Individual [CLA](https://cla.st.com).
+* If you work for a company that wants also to allow you to contribute with your work, your company needs to provide a Corporate [CLA](https://cla.st.com) mentioning your GitHub account name.
+* If you are not sure that a CLA (Individual or Corporate) has been signed for your GitHub account you can check the [CLA](https://cla.st.com) dedicated page.
+
+Please note that:
+* The Corporate CLA will always take precedence over the Individual CLA.
+* One CLA submission is sufficient, for any project proposed by STMicroelectronics.
+
+### 4. How to proceed
+
+* We recommend to engage first a communication thru an issue, in order to present your proposal, just to confirm that it corresponds to STMicroelectronics' domain or scope.
+* Then fork the project to your GitHub account to further develop your contribution. Please use the latest commit version.
+* Please, submit one pull-request per new feature or proposal. This will ease the analysis and the final merge if accepted.
diff --git a/Drivers/BSP/STM32F429I-Discovery/LICENSE.md b/Drivers/BSP/STM32F429I-Discovery/LICENSE.md
new file mode 100644
index 0000000..479c4f6
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/LICENSE.md
@@ -0,0 +1,27 @@
+Copyright 2017 STMicroelectronics.
+All rights reserved.
+
+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 the copyright holder 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.
diff --git a/Drivers/BSP/STM32F429I-Discovery/README.md b/Drivers/BSP/STM32F429I-Discovery/README.md
new file mode 100644
index 0000000..bc32734
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/README.md
@@ -0,0 +1,39 @@
+# BSP STM32F429I-DISCOVERY Component
+
+
+
+## Overview
+
+**STM32Cube** is an STMicroelectronics original initiative to ease developers' life by reducing efforts, time and cost.
+
+**STM32Cube** covers the overall STM32 products portfolio. It includes a comprehensive embedded software platform delivered for each STM32 series.
+ * The CMSIS modules (core and device) corresponding to the ARM(tm) core implemented in this STM32 product.
+ * The STM32 HAL-LL drivers, an abstraction layer offering a set of APIs ensuring maximized portability across the STM32 portfolio.
+ * The BSP drivers of each evaluation, demonstration or nucleo board provided for this STM32 series.
+ * A consistent set of middleware libraries such as RTOS, USB, FatFS, graphics, touch sensing library...
+ * A full set of software projects (basic examples, applications, and demonstrations) for each board provided for this STM32 series.
+
+Two models of publication are proposed for the STM32Cube embedded software:
+ * The monolithic **MCU Package**: all STM32Cube software modules of one STM32 series are present (Drivers, Middleware, Projects, Utilities) in the repository (usual name **STM32Cubexx**, xx corresponding to the STM32 series).
+ * The **MCU component**: each STM32Cube software module being part of the STM32Cube MCU Package, is delivered as an individual repository, allowing the user to select and get only the required software functions.
+
+## Description
+
+This **stm32f429i-discovery** MCU component repository is one element of the **STM32CubeF4** MCU embedded software package, providing the **STM32F429I-DISCOVERY** BSP BOARD component part.
+
+## Release note
+
+Details about the content of this release are available in the release note [here](https://htmlpreview.github.io/?https://github.com/STMicroelectronics/stm32f429i-discovery/blob/main/Release_Notes.html).
+
+## Compatibility information
+
+Below is the list of the BSP *component* drivers to be used with this BSP *board* driver. It is **crucial** that you use a consistent set of CMSIS - HAL - BSP versions, as mentioned in [this](https://htmlpreview.github.io/?https://github.com/STMicroelectronics/STM32CubeF4/blob/master/Release_Notes.html) release note.
+
+* [stm32-bsp-common](https://github.com/STMicroelectronics/stm32-bsp-common)
+* [stm32-ili9341](https://github.com/STMicroelectronics/stm32-ili9341)
+* [stm32-l3gd20](https://github.com/STMicroelectronics/stm32-l3gd20)
+* [stm32-stmpe811](https://github.com/STMicroelectronics/stm32-stmpe811)
+
+## Troubleshooting
+
+Please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) guide.
diff --git a/Drivers/BSP/STM32F429I-Discovery/Release_Notes.html b/Drivers/BSP/STM32F429I-Discovery/Release_Notes.html
new file mode 100644
index 0000000..0502726
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/Release_Notes.html
@@ -0,0 +1,250 @@
+
+
+
+
+
+
+ Release Notes for STM32F429 Discovery Board Drivers
+
+
+
+
+
+
+
+
+
+Release Notes for
+STM32F429 Discovery Board Drivers
+Copyright © 2017 STMicroelectronics
+
+
+
+
Purpose
+
This directory contains the board drivers to demonstrate the capabilities of the STM32F429 Discovery Board Drivers.
+
+
+
Update History
+
+
V2.1.8 / 22-September-2023
+
+
Main Changes
+
+Update Release_Notes.html to support new format
+Update touch calibration to fix inverted touch panel on STM32F429I-DISCOVERY
+
+
+
+
+
V2.1.7 / 11-Fabruary-2022
+
+
Main Changes
+
+Update to support the I3G4250D gyroscope component
+All source files: update disclaimer to add reference to the new license agreement
+
+
+
+
+
V2.1.6 / 06-October-2017
+
+
Main Changes
+
+Remove Date & Version
+stm32f429i_discovery_lcd.c/.h
+
+Update BSP_LCD_DrawBitmap() API to fix functional misbehaviour with SW4STM32 Toolchain
+
+
+
+
+
+
V2.1.5 / 27-January-2017
+
+
Main Changes
+
+Replace __PPP_CLK_ENABLE/DISABLE with __HAL_RCC_PPP_ENABLE/DISABLE
+Set NVIC priority to 0x0F
+stm32f429i_discovery_lcd.c/.h
+
+Update BSP_LCD_ReadPixel implementation for ARGB8888 and RGB888 formats
+
+
+
+
+
+
V2.1.4 / 06-May-2016
+
+
Main Changes
+
+stm32f429i_discovery_lcd.c/.h
+
+Provide BSP full coverage for the LTDC reload HW capabilities (Immediate reload , Vertical Blanking Reload , No reload)
+
+BSP_LCD_Relaod() to disable the color keying without reloading
+BSP_LCD_SetLayerVisible_NoReload() to set an LCD Layer visible without reloading
+BSP_LCD_SetTransparency_NoReload() to configure the transparency without reloading
+BSP_LCD_SetLayerAddress_NoReload() to set an LCD layer frame buffer address without reloading
+BSP_LCD_SetLayerWindow_NoReload() to set display window without reloading
+BSP_LCD_SetColorKeying_NoReload() to configure and sets the color keying without reloading
+BSP_LCD_ResetColorKeying_NoReload() to disables the color keying without reloading
+
+
+
+
+
+
+
V2.1.3 / 13-January-2016
+
+
Main Changes
+
+General updates to fix doxygen errors
+Add STM32429I_EVAL_BSP_User_Manual.chm file
+
+
+
+
+
V2.1.2 / 02-March-2015
+
+
Main Changes
+
+stm32f429i_discovery.c/.h
+
+Align to STM32F4xx HAL Driver V1.3.0 for __HAL_RCC_PPP_CLK_ENABLE() .
+
+
+
+
+
+
V2.1.1 / 10-December-2014
+
+
Main Changes
+
+stm32f429i_discovery.c/.h
+
+Change I2C_SPEED used define by BSP_I2C_SPEED
+
+stm32f429i_discovery_sdram.c
+
+BSP_SDRAM_Initialization_sequence(): Fix wrong configuration of the burst length
+
+stm32f429i_discovery_gyroscope.h, stm32f429i_discovery_io.h,stm32f429i_discovery_lcd.c/.h and stm32f429i_discovery_ts.h:
+
+Change “" by”/" in the include path to fix compilation issue under Linux
+
+Miscellaneous comments update
+
+
+
+
+
V2.1.0 / 19-June-2014
+
+
Main Changes
+
+stm32f429i_discovery.c/.h
+
+Add protection for double initialization of IO_Init within LCD_IO_Init()
+Enhance BSP_PB_Init() function by removing the call of __SYSCFG_CLK_ENABLE() already enabled in the HAL_GPIO_Init()
+
+stm32f429i_discovery_gyroscope.c/.h
+
+Update BSP_GYRO_Init() to support new L3GD20 device ID (I_AM_L3GD20_TR)
+
+stm32f429i_discovery_ts.c/.h
+
+Correct wrong TS configuration BSP_TS_ITConfig() and TS IT implementation, BSP_TS_ITClear() related to the use of IO expander STMPE1600 device not available on stm32f429i discovery board
+Comments clean up and typo corrections
+
+stm32f429i_discovery_eeprom.c/.h
+
+Update usage of BSP_EEPROM_TIMEOUT_UserCallback() function
+
+
+
+
+
+
V2.0.1 / 26-Fabruary-2014
+
+
Main Changes
+
+stm32f429i_discovery_eeprom.c/.h
+
+Update usage of BSP_EEPROM_TIMEOUT_UserCallback() function
+
+
+
+
+
+
V2.0.0 / 18-Fabruary-2014
+
+
Main Changes
+
+Major update based on STM32Cube specification: drivers architecture and APIs modified vs. V1.0.2, and thus the 2 versions are not compatible.
+This version has to be used only with STM32CubeF4 based development
+
+
+
+
+
V1.0.2 / 06-December-2013
+
+
Main Changes
+
+Update IO expander interrupt line on stm32f429i_discovery_ioe.h file.
+
+
+
+
+
V1.0.1 / 28-October-2013
+
+
Main Changes
+
+stm32f429i_discovery_l3gd20.c, stm32f429i_discovery_lcd.c
+
+Set SPI baudrate to 5.625 MHz to fit LCD and Gyroscope timing characteristics
+
+ILI9341 LCD SPI interface max baud rate is 10MHz for write and 6.66MHz for read
+Gyroscope l3gd20 SPI interface max baud rate is 10MHz for write/read
+
+
+stm32f429i_discovery_lcd.c
+
+Improve SPI low level write routines (add check on BSY flag before to deselect the LCD)
+Remove the __IO attribute from these function’s parameters: LCD_SetLayer(), LCD_SetColors(), LCD_GetColors(), LCD_SetTextColor() and LCD_SetBackColor()
+
+stm32f429i_discovery_i2c_ee.c, stm32f429i_discovery_i2c_ ioe.c
+
+Add a test in Init() function; if the I2C is already configured, then there is no need to reconfigure it again
+I2C_SPEED define moved to stm32f429i_discovery.h file
+
+stm32f429i_discovery_sdram.c
+
+Update device refresh counter value to fit with SDRAM timing characteristics
+
+Miscellaneous robustness improvement
+Miscellaneous comments update
+
+
+
+
+
V1.0.0 / 20-September-2013
+
+
Main Changes
+
+First official version of the STM32F429 Discovery Board Drivers
+
+
+
+
+
+
+
+
diff --git a/Drivers/BSP/STM32F429I-Discovery/SECURITY.md b/Drivers/BSP/STM32F429I-Discovery/SECURITY.md
new file mode 100644
index 0000000..b784d15
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/SECURITY.md
@@ -0,0 +1,31 @@
+# Report potential product security vulnerabilities
+
+ST places a high priority on security, and our Product Security Incident
+Response Team (PSIRT) is committed to rapidly addressing potential security
+vulnerabilities affecting our products. PSIRT's long history and vast experience
+in security allows ST to perform clear analyses and provide appropriate guidance
+on mitigations and solutions when applicable.
+
+If you wish to report potential security vulnerabilities regarding our products,
+**please do not report them through public GitHub issues.** Instead, we
+encourage you to report them to our ST PSIRT following the process described at:
+**https://www.st.com/content/st_com/en/security/report-vulnerabilities.html**
+
+### IMPORTANT - READ CAREFULLY:
+
+STMicroelectronics International N.V., on behalf of itself, its affiliates and
+subsidiaries, (collectively “ST”) takes all potential security vulnerability
+reports or other related communications (“Report(s)”) seriously. In order to
+review Your Report (the terms “You” and “Yours” include your employer, and all
+affiliates, subsidiaries and related persons or entities) and take actions as
+deemed appropriate, ST requires that we have the rights and Your permission to
+do so.
+
+As such, by submitting Your Report to ST, You agree that You have the right to
+do so, and You grant to ST the rights to use the Report for purposes related to
+security vulnerability analysis, testing, correction, patching, reporting and
+any other related purpose or function.
+
+By submitting Your Report, You agree that ST’s
+[Privacy Policy](https://www.st.com/content/st_com/en/common/privacy-portal.html)
+applies to all related communications.
diff --git a/Drivers/BSP/STM32F429I-Discovery/_htmresc/favicon.png b/Drivers/BSP/STM32F429I-Discovery/_htmresc/favicon.png
new file mode 100644
index 0000000..06713ee
Binary files /dev/null and b/Drivers/BSP/STM32F429I-Discovery/_htmresc/favicon.png differ
diff --git a/Drivers/BSP/STM32F429I-Discovery/_htmresc/mini-st_2020.css b/Drivers/BSP/STM32F429I-Discovery/_htmresc/mini-st_2020.css
new file mode 100644
index 0000000..986f4d4
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/_htmresc/mini-st_2020.css
@@ -0,0 +1,1711 @@
+@charset "UTF-8";
+/*
+ Flavor name: Custom (mini-custom)
+ Generated online - https://minicss.org/flavors
+ mini.css version: v3.0.1
+*/
+/*
+ Browsers resets and base typography.
+*/
+/* Core module CSS variable definitions */
+:root {
+ --fore-color: #03234b;
+ --secondary-fore-color: #03234b;
+ --back-color: #ffffff;
+ --secondary-back-color: #ffffff;
+ --blockquote-color: #e6007e;
+ --pre-color: #e6007e;
+ --border-color: #3cb4e6;
+ --secondary-border-color: #3cb4e6;
+ --heading-ratio: 1.2;
+ --universal-margin: 0.5rem;
+ --universal-padding: 0.25rem;
+ --universal-border-radius: 0.075rem;
+ --background-margin: 1.5%;
+ --a-link-color: #3cb4e6;
+ --a-visited-color: #8c0078; }
+
+html {
+ font-size: 13.5px; }
+
+a, b, del, em, i, ins, q, span, strong, u {
+ font-size: 1em; }
+
+html, * {
+ font-family: -apple-system, BlinkMacSystemFont, Helvetica, arial, sans-serif;
+ line-height: 1.25;
+ -webkit-text-size-adjust: 100%; }
+
+* {
+ font-size: 1rem; }
+
+body {
+ margin: 0;
+ color: var(--fore-color);
+ @background: var(--back-color);
+ background: var(--back-color) linear-gradient(#ffd200, #ffd200) repeat-y left top;
+ background-size: var(--background-margin);
+ }
+
+details {
+ display: block; }
+
+summary {
+ display: list-item; }
+
+abbr[title] {
+ border-bottom: none;
+ text-decoration: underline dotted; }
+
+input {
+ overflow: visible; }
+
+img {
+ max-width: 100%;
+ height: auto; }
+
+h1, h2, h3, h4, h5, h6 {
+ line-height: 1.25;
+ margin: calc(1.5 * var(--universal-margin)) var(--universal-margin);
+ font-weight: 400; }
+ h1 small, h2 small, h3 small, h4 small, h5 small, h6 small {
+ color: var(--secondary-fore-color);
+ display: block;
+ margin-top: -0.25rem; }
+
+h1 {
+ font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio)); }
+
+h2 {
+ font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) );
+ border-style: none none solid none ;
+ border-width: thin;
+ border-color: var(--border-color); }
+h3 {
+ font-size: calc(1rem * var(--heading-ratio) ); }
+
+h4 {
+ font-size: calc(1rem * var(--heading-ratio)); }
+
+h5 {
+ font-size: 1rem; }
+
+h6 {
+ font-size: calc(1rem / var(--heading-ratio)); }
+
+p {
+ margin: var(--universal-margin); }
+
+ol, ul {
+ margin: var(--universal-margin);
+ padding-left: calc(3 * var(--universal-margin)); }
+
+b, strong {
+ font-weight: 700; }
+
+hr {
+ box-sizing: content-box;
+ border: 0;
+ line-height: 1.25em;
+ margin: var(--universal-margin);
+ height: 0.0714285714rem;
+ background: linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent); }
+
+blockquote {
+ display: block;
+ position: relative;
+ font-style: italic;
+ color: var(--secondary-fore-color);
+ margin: var(--universal-margin);
+ padding: calc(3 * var(--universal-padding));
+ border: 0.0714285714rem solid var(--secondary-border-color);
+ border-left: 0.3rem solid var(--blockquote-color);
+ border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; }
+ blockquote:before {
+ position: absolute;
+ top: calc(0rem - var(--universal-padding));
+ left: 0;
+ font-family: sans-serif;
+ font-size: 2rem;
+ font-weight: 800;
+ content: "\201c";
+ color: var(--blockquote-color); }
+ blockquote[cite]:after {
+ font-style: normal;
+ font-size: 0.75em;
+ font-weight: 700;
+ content: "\a— " attr(cite);
+ white-space: pre; }
+
+code, kbd, pre, samp {
+ font-family: Menlo, Consolas, monospace;
+ font-size: 0.85em; }
+
+code {
+ background: var(--secondary-back-color);
+ border-radius: var(--universal-border-radius);
+ padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); }
+
+kbd {
+ background: var(--fore-color);
+ color: var(--back-color);
+ border-radius: var(--universal-border-radius);
+ padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); }
+
+pre {
+ overflow: auto;
+ background: var(--secondary-back-color);
+ padding: calc(1.5 * var(--universal-padding));
+ margin: var(--universal-margin);
+ border: 0.0714285714rem solid var(--secondary-border-color);
+ border-left: 0.2857142857rem solid var(--pre-color);
+ border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; }
+
+sup, sub, code, kbd {
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline; }
+
+small, sup, sub, figcaption {
+ font-size: 0.75em; }
+
+sup {
+ top: -0.5em; }
+
+sub {
+ bottom: -0.25em; }
+
+figure {
+ margin: var(--universal-margin); }
+
+figcaption {
+ color: var(--secondary-fore-color); }
+
+a {
+ text-decoration: none; }
+ a:link {
+ color: var(--a-link-color); }
+ a:visited {
+ color: var(--a-visited-color); }
+ a:hover, a:focus {
+ text-decoration: underline; }
+
+/*
+ Definitions for the grid system, cards and containers.
+*/
+.container {
+ margin: 0 auto;
+ padding: 0 calc(1.5 * var(--universal-padding)); }
+
+.row {
+ box-sizing: border-box;
+ display: flex;
+ flex: 0 1 auto;
+ flex-flow: row wrap;
+ margin: 0 0 0 var(--background-margin); }
+
+.col-sm,
+[class^='col-sm-'],
+[class^='col-sm-offset-'],
+.row[class*='cols-sm-'] > * {
+ box-sizing: border-box;
+ flex: 0 0 auto;
+ padding: 0 calc(var(--universal-padding) / 2); }
+
+.col-sm,
+.row.cols-sm > * {
+ max-width: 100%;
+ flex-grow: 1;
+ flex-basis: 0; }
+
+.col-sm-1,
+.row.cols-sm-1 > * {
+ max-width: 8.3333333333%;
+ flex-basis: 8.3333333333%; }
+
+.col-sm-offset-0 {
+ margin-left: 0; }
+
+.col-sm-2,
+.row.cols-sm-2 > * {
+ max-width: 16.6666666667%;
+ flex-basis: 16.6666666667%; }
+
+.col-sm-offset-1 {
+ margin-left: 8.3333333333%; }
+
+.col-sm-3,
+.row.cols-sm-3 > * {
+ max-width: 25%;
+ flex-basis: 25%; }
+
+.col-sm-offset-2 {
+ margin-left: 16.6666666667%; }
+
+.col-sm-4,
+.row.cols-sm-4 > * {
+ max-width: 33.3333333333%;
+ flex-basis: 33.3333333333%; }
+
+.col-sm-offset-3 {
+ margin-left: 25%; }
+
+.col-sm-5,
+.row.cols-sm-5 > * {
+ max-width: 41.6666666667%;
+ flex-basis: 41.6666666667%; }
+
+.col-sm-offset-4 {
+ margin-left: 33.3333333333%; }
+
+.col-sm-6,
+.row.cols-sm-6 > * {
+ max-width: 50%;
+ flex-basis: 50%; }
+
+.col-sm-offset-5 {
+ margin-left: 41.6666666667%; }
+
+.col-sm-7,
+.row.cols-sm-7 > * {
+ max-width: 58.3333333333%;
+ flex-basis: 58.3333333333%; }
+
+.col-sm-offset-6 {
+ margin-left: 50%; }
+
+.col-sm-8,
+.row.cols-sm-8 > * {
+ max-width: 66.6666666667%;
+ flex-basis: 66.6666666667%; }
+
+.col-sm-offset-7 {
+ margin-left: 58.3333333333%; }
+
+.col-sm-9,
+.row.cols-sm-9 > * {
+ max-width: 75%;
+ flex-basis: 75%; }
+
+.col-sm-offset-8 {
+ margin-left: 66.6666666667%; }
+
+.col-sm-10,
+.row.cols-sm-10 > * {
+ max-width: 83.3333333333%;
+ flex-basis: 83.3333333333%; }
+
+.col-sm-offset-9 {
+ margin-left: 75%; }
+
+.col-sm-11,
+.row.cols-sm-11 > * {
+ max-width: 91.6666666667%;
+ flex-basis: 91.6666666667%; }
+
+.col-sm-offset-10 {
+ margin-left: 83.3333333333%; }
+
+.col-sm-12,
+.row.cols-sm-12 > * {
+ max-width: 100%;
+ flex-basis: 100%; }
+
+.col-sm-offset-11 {
+ margin-left: 91.6666666667%; }
+
+.col-sm-normal {
+ order: initial; }
+
+.col-sm-first {
+ order: -999; }
+
+.col-sm-last {
+ order: 999; }
+
+@media screen and (min-width: 500px) {
+ .col-md,
+ [class^='col-md-'],
+ [class^='col-md-offset-'],
+ .row[class*='cols-md-'] > * {
+ box-sizing: border-box;
+ flex: 0 0 auto;
+ padding: 0 calc(var(--universal-padding) / 2); }
+
+ .col-md,
+ .row.cols-md > * {
+ max-width: 100%;
+ flex-grow: 1;
+ flex-basis: 0; }
+
+ .col-md-1,
+ .row.cols-md-1 > * {
+ max-width: 8.3333333333%;
+ flex-basis: 8.3333333333%; }
+
+ .col-md-offset-0 {
+ margin-left: 0; }
+
+ .col-md-2,
+ .row.cols-md-2 > * {
+ max-width: 16.6666666667%;
+ flex-basis: 16.6666666667%; }
+
+ .col-md-offset-1 {
+ margin-left: 8.3333333333%; }
+
+ .col-md-3,
+ .row.cols-md-3 > * {
+ max-width: 25%;
+ flex-basis: 25%; }
+
+ .col-md-offset-2 {
+ margin-left: 16.6666666667%; }
+
+ .col-md-4,
+ .row.cols-md-4 > * {
+ max-width: 33.3333333333%;
+ flex-basis: 33.3333333333%; }
+
+ .col-md-offset-3 {
+ margin-left: 25%; }
+
+ .col-md-5,
+ .row.cols-md-5 > * {
+ max-width: 41.6666666667%;
+ flex-basis: 41.6666666667%; }
+
+ .col-md-offset-4 {
+ margin-left: 33.3333333333%; }
+
+ .col-md-6,
+ .row.cols-md-6 > * {
+ max-width: 50%;
+ flex-basis: 50%; }
+
+ .col-md-offset-5 {
+ margin-left: 41.6666666667%; }
+
+ .col-md-7,
+ .row.cols-md-7 > * {
+ max-width: 58.3333333333%;
+ flex-basis: 58.3333333333%; }
+
+ .col-md-offset-6 {
+ margin-left: 50%; }
+
+ .col-md-8,
+ .row.cols-md-8 > * {
+ max-width: 66.6666666667%;
+ flex-basis: 66.6666666667%; }
+
+ .col-md-offset-7 {
+ margin-left: 58.3333333333%; }
+
+ .col-md-9,
+ .row.cols-md-9 > * {
+ max-width: 75%;
+ flex-basis: 75%; }
+
+ .col-md-offset-8 {
+ margin-left: 66.6666666667%; }
+
+ .col-md-10,
+ .row.cols-md-10 > * {
+ max-width: 83.3333333333%;
+ flex-basis: 83.3333333333%; }
+
+ .col-md-offset-9 {
+ margin-left: 75%; }
+
+ .col-md-11,
+ .row.cols-md-11 > * {
+ max-width: 91.6666666667%;
+ flex-basis: 91.6666666667%; }
+
+ .col-md-offset-10 {
+ margin-left: 83.3333333333%; }
+
+ .col-md-12,
+ .row.cols-md-12 > * {
+ max-width: 100%;
+ flex-basis: 100%; }
+
+ .col-md-offset-11 {
+ margin-left: 91.6666666667%; }
+
+ .col-md-normal {
+ order: initial; }
+
+ .col-md-first {
+ order: -999; }
+
+ .col-md-last {
+ order: 999; } }
+@media screen and (min-width: 1280px) {
+ .col-lg,
+ [class^='col-lg-'],
+ [class^='col-lg-offset-'],
+ .row[class*='cols-lg-'] > * {
+ box-sizing: border-box;
+ flex: 0 0 auto;
+ padding: 0 calc(var(--universal-padding) / 2); }
+
+ .col-lg,
+ .row.cols-lg > * {
+ max-width: 100%;
+ flex-grow: 1;
+ flex-basis: 0; }
+
+ .col-lg-1,
+ .row.cols-lg-1 > * {
+ max-width: 8.3333333333%;
+ flex-basis: 8.3333333333%; }
+
+ .col-lg-offset-0 {
+ margin-left: 0; }
+
+ .col-lg-2,
+ .row.cols-lg-2 > * {
+ max-width: 16.6666666667%;
+ flex-basis: 16.6666666667%; }
+
+ .col-lg-offset-1 {
+ margin-left: 8.3333333333%; }
+
+ .col-lg-3,
+ .row.cols-lg-3 > * {
+ max-width: 25%;
+ flex-basis: 25%; }
+
+ .col-lg-offset-2 {
+ margin-left: 16.6666666667%; }
+
+ .col-lg-4,
+ .row.cols-lg-4 > * {
+ max-width: 33.3333333333%;
+ flex-basis: 33.3333333333%; }
+
+ .col-lg-offset-3 {
+ margin-left: 25%; }
+
+ .col-lg-5,
+ .row.cols-lg-5 > * {
+ max-width: 41.6666666667%;
+ flex-basis: 41.6666666667%; }
+
+ .col-lg-offset-4 {
+ margin-left: 33.3333333333%; }
+
+ .col-lg-6,
+ .row.cols-lg-6 > * {
+ max-width: 50%;
+ flex-basis: 50%; }
+
+ .col-lg-offset-5 {
+ margin-left: 41.6666666667%; }
+
+ .col-lg-7,
+ .row.cols-lg-7 > * {
+ max-width: 58.3333333333%;
+ flex-basis: 58.3333333333%; }
+
+ .col-lg-offset-6 {
+ margin-left: 50%; }
+
+ .col-lg-8,
+ .row.cols-lg-8 > * {
+ max-width: 66.6666666667%;
+ flex-basis: 66.6666666667%; }
+
+ .col-lg-offset-7 {
+ margin-left: 58.3333333333%; }
+
+ .col-lg-9,
+ .row.cols-lg-9 > * {
+ max-width: 75%;
+ flex-basis: 75%; }
+
+ .col-lg-offset-8 {
+ margin-left: 66.6666666667%; }
+
+ .col-lg-10,
+ .row.cols-lg-10 > * {
+ max-width: 83.3333333333%;
+ flex-basis: 83.3333333333%; }
+
+ .col-lg-offset-9 {
+ margin-left: 75%; }
+
+ .col-lg-11,
+ .row.cols-lg-11 > * {
+ max-width: 91.6666666667%;
+ flex-basis: 91.6666666667%; }
+
+ .col-lg-offset-10 {
+ margin-left: 83.3333333333%; }
+
+ .col-lg-12,
+ .row.cols-lg-12 > * {
+ max-width: 100%;
+ flex-basis: 100%; }
+
+ .col-lg-offset-11 {
+ margin-left: 91.6666666667%; }
+
+ .col-lg-normal {
+ order: initial; }
+
+ .col-lg-first {
+ order: -999; }
+
+ .col-lg-last {
+ order: 999; } }
+/* Card component CSS variable definitions */
+:root {
+ --card-back-color: #3cb4e6;
+ --card-fore-color: #03234b;
+ --card-border-color: #03234b; }
+
+.card {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ align-self: center;
+ position: relative;
+ width: 100%;
+ background: var(--card-back-color);
+ color: var(--card-fore-color);
+ border: 0.0714285714rem solid var(--card-border-color);
+ border-radius: var(--universal-border-radius);
+ margin: var(--universal-margin);
+ overflow: hidden; }
+ @media screen and (min-width: 320px) {
+ .card {
+ max-width: 320px; } }
+ .card > .sectione {
+ background: var(--card-back-color);
+ color: var(--card-fore-color);
+ box-sizing: border-box;
+ margin: 0;
+ border: 0;
+ border-radius: 0;
+ border-bottom: 0.0714285714rem solid var(--card-border-color);
+ padding: var(--universal-padding);
+ width: 100%; }
+ .card > .sectione.media {
+ height: 200px;
+ padding: 0;
+ -o-object-fit: cover;
+ object-fit: cover; }
+ .card > .sectione:last-child {
+ border-bottom: 0; }
+
+/*
+ Custom elements for card elements.
+*/
+@media screen and (min-width: 240px) {
+ .card.small {
+ max-width: 240px; } }
+@media screen and (min-width: 480px) {
+ .card.large {
+ max-width: 480px; } }
+.card.fluid {
+ max-width: 100%;
+ width: auto; }
+
+.card.warning {
+ --card-back-color: #e5b8b7;
+ --card-fore-color: #3b234b;
+ --card-border-color: #8c0078; }
+
+.card.error {
+ --card-back-color: #464650;
+ --card-fore-color: #ffffff;
+ --card-border-color: #8c0078; }
+
+.card > .sectione.dark {
+ --card-back-color: #3b234b;
+ --card-fore-color: #ffffff; }
+
+.card > .sectione.double-padded {
+ padding: calc(1.5 * var(--universal-padding)); }
+
+/*
+ Definitions for forms and input elements.
+*/
+/* Input_control module CSS variable definitions */
+:root {
+ --form-back-color: #ffe97f;
+ --form-fore-color: #03234b;
+ --form-border-color: #3cb4e6;
+ --input-back-color: #ffffff;
+ --input-fore-color: #03234b;
+ --input-border-color: #3cb4e6;
+ --input-focus-color: #0288d1;
+ --input-invalid-color: #d32f2f;
+ --button-back-color: #e2e2e2;
+ --button-hover-back-color: #dcdcdc;
+ --button-fore-color: #212121;
+ --button-border-color: transparent;
+ --button-hover-border-color: transparent;
+ --button-group-border-color: rgba(124, 124, 124, 0.54); }
+
+form {
+ background: var(--form-back-color);
+ color: var(--form-fore-color);
+ border: 0.0714285714rem solid var(--form-border-color);
+ border-radius: var(--universal-border-radius);
+ margin: var(--universal-margin);
+ padding: calc(2 * var(--universal-padding)) var(--universal-padding); }
+
+fieldset {
+ border: 0.0714285714rem solid var(--form-border-color);
+ border-radius: var(--universal-border-radius);
+ margin: calc(var(--universal-margin) / 4);
+ padding: var(--universal-padding); }
+
+legend {
+ box-sizing: border-box;
+ display: table;
+ max-width: 100%;
+ white-space: normal;
+ font-weight: 500;
+ padding: calc(var(--universal-padding) / 2); }
+
+label {
+ padding: calc(var(--universal-padding) / 2) var(--universal-padding); }
+
+.input-group {
+ display: inline-block; }
+ .input-group.fluid {
+ display: flex;
+ align-items: center;
+ justify-content: center; }
+ .input-group.fluid > input {
+ max-width: 100%;
+ flex-grow: 1;
+ flex-basis: 0px; }
+ @media screen and (max-width: 499px) {
+ .input-group.fluid {
+ align-items: stretch;
+ flex-direction: column; } }
+ .input-group.vertical {
+ display: flex;
+ align-items: stretch;
+ flex-direction: column; }
+ .input-group.vertical > input {
+ max-width: 100%;
+ flex-grow: 1;
+ flex-basis: 0px; }
+
+[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button {
+ height: auto; }
+
+[type="search"] {
+ -webkit-appearance: textfield;
+ outline-offset: -2px; }
+
+[type="search"]::-webkit-search-cancel-button,
+[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none; }
+
+input:not([type]), [type="text"], [type="email"], [type="number"], [type="search"],
+[type="password"], [type="url"], [type="tel"], [type="checkbox"], [type="radio"], textarea, select {
+ box-sizing: border-box;
+ background: var(--input-back-color);
+ color: var(--input-fore-color);
+ border: 0.0714285714rem solid var(--input-border-color);
+ border-radius: var(--universal-border-radius);
+ margin: calc(var(--universal-margin) / 2);
+ padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); }
+
+input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus, textarea:hover, textarea:focus, select:hover, select:focus {
+ border-color: var(--input-focus-color);
+ box-shadow: none; }
+input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid, textarea:invalid, textarea:focus:invalid, select:invalid, select:focus:invalid {
+ border-color: var(--input-invalid-color);
+ box-shadow: none; }
+input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly], textarea[readonly], select[readonly] {
+ background: var(--secondary-back-color); }
+
+select {
+ max-width: 100%; }
+
+option {
+ overflow: hidden;
+ text-overflow: ellipsis; }
+
+[type="checkbox"], [type="radio"] {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ position: relative;
+ height: calc(1rem + var(--universal-padding) / 2);
+ width: calc(1rem + var(--universal-padding) / 2);
+ vertical-align: text-bottom;
+ padding: 0;
+ flex-basis: calc(1rem + var(--universal-padding) / 2) !important;
+ flex-grow: 0 !important; }
+ [type="checkbox"]:checked:before, [type="radio"]:checked:before {
+ position: absolute; }
+
+[type="checkbox"]:checked:before {
+ content: '\2713';
+ font-family: sans-serif;
+ font-size: calc(1rem + var(--universal-padding) / 2);
+ top: calc(0rem - var(--universal-padding));
+ left: calc(var(--universal-padding) / 4); }
+
+[type="radio"] {
+ border-radius: 100%; }
+ [type="radio"]:checked:before {
+ border-radius: 100%;
+ content: '';
+ top: calc(0.0714285714rem + var(--universal-padding) / 2);
+ left: calc(0.0714285714rem + var(--universal-padding) / 2);
+ background: var(--input-fore-color);
+ width: 0.5rem;
+ height: 0.5rem; }
+
+:placeholder-shown {
+ color: var(--input-fore-color); }
+
+::-ms-placeholder {
+ color: var(--input-fore-color);
+ opacity: 0.54; }
+
+button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner {
+ border-style: none;
+ padding: 0; }
+
+button, html [type="button"], [type="reset"], [type="submit"] {
+ -webkit-appearance: button; }
+
+button {
+ overflow: visible;
+ text-transform: none; }
+
+button, [type="button"], [type="submit"], [type="reset"],
+a.button, label.button, .button,
+a[role="button"], label[role="button"], [role="button"] {
+ display: inline-block;
+ background: var(--button-back-color);
+ color: var(--button-fore-color);
+ border: 0.0714285714rem solid var(--button-border-color);
+ border-radius: var(--universal-border-radius);
+ padding: var(--universal-padding) calc(1.5 * var(--universal-padding));
+ margin: var(--universal-margin);
+ text-decoration: none;
+ cursor: pointer;
+ transition: background 0.3s; }
+ button:hover, button:focus, [type="button"]:hover, [type="button"]:focus, [type="submit"]:hover, [type="submit"]:focus, [type="reset"]:hover, [type="reset"]:focus,
+ a.button:hover,
+ a.button:focus, label.button:hover, label.button:focus, .button:hover, .button:focus,
+ a[role="button"]:hover,
+ a[role="button"]:focus, label[role="button"]:hover, label[role="button"]:focus, [role="button"]:hover, [role="button"]:focus {
+ background: var(--button-hover-back-color);
+ border-color: var(--button-hover-border-color); }
+
+input:disabled, input[disabled], textarea:disabled, textarea[disabled], select:disabled, select[disabled], button:disabled, button[disabled], .button:disabled, .button[disabled], [role="button"]:disabled, [role="button"][disabled] {
+ cursor: not-allowed;
+ opacity: 0.75; }
+
+.button-group {
+ display: flex;
+ border: 0.0714285714rem solid var(--button-group-border-color);
+ border-radius: var(--universal-border-radius);
+ margin: var(--universal-margin); }
+ .button-group > button, .button-group [type="button"], .button-group > [type="submit"], .button-group > [type="reset"], .button-group > .button, .button-group > [role="button"] {
+ margin: 0;
+ max-width: 100%;
+ flex: 1 1 auto;
+ text-align: center;
+ border: 0;
+ border-radius: 0;
+ box-shadow: none; }
+ .button-group > :not(:first-child) {
+ border-left: 0.0714285714rem solid var(--button-group-border-color); }
+ @media screen and (max-width: 499px) {
+ .button-group {
+ flex-direction: column; }
+ .button-group > :not(:first-child) {
+ border: 0;
+ border-top: 0.0714285714rem solid var(--button-group-border-color); } }
+
+/*
+ Custom elements for forms and input elements.
+*/
+button.primary, [type="button"].primary, [type="submit"].primary, [type="reset"].primary, .button.primary, [role="button"].primary {
+ --button-back-color: #1976d2;
+ --button-fore-color: #f8f8f8; }
+ button.primary:hover, button.primary:focus, [type="button"].primary:hover, [type="button"].primary:focus, [type="submit"].primary:hover, [type="submit"].primary:focus, [type="reset"].primary:hover, [type="reset"].primary:focus, .button.primary:hover, .button.primary:focus, [role="button"].primary:hover, [role="button"].primary:focus {
+ --button-hover-back-color: #1565c0; }
+
+button.secondary, [type="button"].secondary, [type="submit"].secondary, [type="reset"].secondary, .button.secondary, [role="button"].secondary {
+ --button-back-color: #d32f2f;
+ --button-fore-color: #f8f8f8; }
+ button.secondary:hover, button.secondary:focus, [type="button"].secondary:hover, [type="button"].secondary:focus, [type="submit"].secondary:hover, [type="submit"].secondary:focus, [type="reset"].secondary:hover, [type="reset"].secondary:focus, .button.secondary:hover, .button.secondary:focus, [role="button"].secondary:hover, [role="button"].secondary:focus {
+ --button-hover-back-color: #c62828; }
+
+button.tertiary, [type="button"].tertiary, [type="submit"].tertiary, [type="reset"].tertiary, .button.tertiary, [role="button"].tertiary {
+ --button-back-color: #308732;
+ --button-fore-color: #f8f8f8; }
+ button.tertiary:hover, button.tertiary:focus, [type="button"].tertiary:hover, [type="button"].tertiary:focus, [type="submit"].tertiary:hover, [type="submit"].tertiary:focus, [type="reset"].tertiary:hover, [type="reset"].tertiary:focus, .button.tertiary:hover, .button.tertiary:focus, [role="button"].tertiary:hover, [role="button"].tertiary:focus {
+ --button-hover-back-color: #277529; }
+
+button.inverse, [type="button"].inverse, [type="submit"].inverse, [type="reset"].inverse, .button.inverse, [role="button"].inverse {
+ --button-back-color: #212121;
+ --button-fore-color: #f8f8f8; }
+ button.inverse:hover, button.inverse:focus, [type="button"].inverse:hover, [type="button"].inverse:focus, [type="submit"].inverse:hover, [type="submit"].inverse:focus, [type="reset"].inverse:hover, [type="reset"].inverse:focus, .button.inverse:hover, .button.inverse:focus, [role="button"].inverse:hover, [role="button"].inverse:focus {
+ --button-hover-back-color: #111; }
+
+button.small, [type="button"].small, [type="submit"].small, [type="reset"].small, .button.small, [role="button"].small {
+ padding: calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding));
+ margin: var(--universal-margin); }
+
+button.large, [type="button"].large, [type="submit"].large, [type="reset"].large, .button.large, [role="button"].large {
+ padding: calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding));
+ margin: var(--universal-margin); }
+
+/*
+ Definitions for navigation elements.
+*/
+/* Navigation module CSS variable definitions */
+:root {
+ --header-back-color: #03234b;
+ --header-hover-back-color: #ffd200;
+ --header-fore-color: #ffffff;
+ --header-border-color: #3cb4e6;
+ --nav-back-color: #ffffff;
+ --nav-hover-back-color: #ffe97f;
+ --nav-fore-color: #e6007e;
+ --nav-border-color: #3cb4e6;
+ --nav-link-color: #3cb4e6;
+ --footer-fore-color: #ffffff;
+ --footer-back-color: #03234b;
+ --footer-border-color: #3cb4e6;
+ --footer-link-color: #3cb4e6;
+ --drawer-back-color: #ffffff;
+ --drawer-hover-back-color: #ffe97f;
+ --drawer-border-color: #3cb4e6;
+ --drawer-close-color: #e6007e; }
+
+header {
+ height: 2.75rem;
+ background: var(--header-back-color);
+ color: var(--header-fore-color);
+ border-bottom: 0.0714285714rem solid var(--header-border-color);
+ padding: calc(var(--universal-padding) / 4) 0;
+ white-space: nowrap;
+ overflow-x: auto;
+ overflow-y: hidden; }
+ header.row {
+ box-sizing: content-box; }
+ header .logo {
+ color: var(--header-fore-color);
+ font-size: 1.75rem;
+ padding: var(--universal-padding) calc(2 * var(--universal-padding));
+ text-decoration: none; }
+ header button, header [type="button"], header .button, header [role="button"] {
+ box-sizing: border-box;
+ position: relative;
+ top: calc(0rem - var(--universal-padding) / 4);
+ height: calc(3.1875rem + var(--universal-padding) / 2);
+ background: var(--header-back-color);
+ line-height: calc(3.1875rem - var(--universal-padding) * 1.5);
+ text-align: center;
+ color: var(--header-fore-color);
+ border: 0;
+ border-radius: 0;
+ margin: 0;
+ text-transform: uppercase; }
+ header button:hover, header button:focus, header [type="button"]:hover, header [type="button"]:focus, header .button:hover, header .button:focus, header [role="button"]:hover, header [role="button"]:focus {
+ background: var(--header-hover-back-color); }
+
+nav {
+ background: var(--nav-back-color);
+ color: var(--nav-fore-color);
+ border: 0.0714285714rem solid var(--nav-border-color);
+ border-radius: var(--universal-border-radius);
+ margin: var(--universal-margin); }
+ nav * {
+ padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); }
+ nav a, nav a:visited {
+ display: block;
+ color: var(--nav-link-color);
+ border-radius: var(--universal-border-radius);
+ transition: background 0.3s; }
+ nav a:hover, nav a:focus, nav a:visited:hover, nav a:visited:focus {
+ text-decoration: none;
+ background: var(--nav-hover-back-color); }
+ nav .sublink-1 {
+ position: relative;
+ margin-left: calc(2 * var(--universal-padding)); }
+ nav .sublink-1:before {
+ position: absolute;
+ left: calc(var(--universal-padding) - 1 * var(--universal-padding));
+ top: -0.0714285714rem;
+ content: '';
+ height: 100%;
+ border: 0.0714285714rem solid var(--nav-border-color);
+ border-left: 0; }
+ nav .sublink-2 {
+ position: relative;
+ margin-left: calc(4 * var(--universal-padding)); }
+ nav .sublink-2:before {
+ position: absolute;
+ left: calc(var(--universal-padding) - 3 * var(--universal-padding));
+ top: -0.0714285714rem;
+ content: '';
+ height: 100%;
+ border: 0.0714285714rem solid var(--nav-border-color);
+ border-left: 0; }
+
+footer {
+ background: var(--footer-back-color);
+ color: var(--footer-fore-color);
+ border-top: 0.0714285714rem solid var(--footer-border-color);
+ padding: calc(2 * var(--universal-padding)) var(--universal-padding);
+ font-size: 0.875rem; }
+ footer a, footer a:visited {
+ color: var(--footer-link-color); }
+
+header.sticky {
+ position: -webkit-sticky;
+ position: sticky;
+ z-index: 1101;
+ top: 0; }
+
+footer.sticky {
+ position: -webkit-sticky;
+ position: sticky;
+ z-index: 1101;
+ bottom: 0; }
+
+.drawer-toggle:before {
+ display: inline-block;
+ position: relative;
+ vertical-align: bottom;
+ content: '\00a0\2261\00a0';
+ font-family: sans-serif;
+ font-size: 1.5em; }
+@media screen and (min-width: 500px) {
+ .drawer-toggle:not(.persistent) {
+ display: none; } }
+
+[type="checkbox"].drawer {
+ height: 1px;
+ width: 1px;
+ margin: -1px;
+ overflow: hidden;
+ position: absolute;
+ clip: rect(0 0 0 0);
+ -webkit-clip-path: inset(100%);
+ clip-path: inset(100%); }
+ [type="checkbox"].drawer + * {
+ display: block;
+ box-sizing: border-box;
+ position: fixed;
+ top: 0;
+ width: 320px;
+ height: 100vh;
+ overflow-y: auto;
+ background: var(--drawer-back-color);
+ border: 0.0714285714rem solid var(--drawer-border-color);
+ border-radius: 0;
+ margin: 0;
+ z-index: 1110;
+ right: -320px;
+ transition: right 0.3s; }
+ [type="checkbox"].drawer + * .drawer-close {
+ position: absolute;
+ top: var(--universal-margin);
+ right: var(--universal-margin);
+ z-index: 1111;
+ width: 2rem;
+ height: 2rem;
+ border-radius: var(--universal-border-radius);
+ padding: var(--universal-padding);
+ margin: 0;
+ cursor: pointer;
+ transition: background 0.3s; }
+ [type="checkbox"].drawer + * .drawer-close:before {
+ display: block;
+ content: '\00D7';
+ color: var(--drawer-close-color);
+ position: relative;
+ font-family: sans-serif;
+ font-size: 2rem;
+ line-height: 1;
+ text-align: center; }
+ [type="checkbox"].drawer + * .drawer-close:hover, [type="checkbox"].drawer + * .drawer-close:focus {
+ background: var(--drawer-hover-back-color); }
+ @media screen and (max-width: 320px) {
+ [type="checkbox"].drawer + * {
+ width: 100%; } }
+ [type="checkbox"].drawer:checked + * {
+ right: 0; }
+ @media screen and (min-width: 500px) {
+ [type="checkbox"].drawer:not(.persistent) + * {
+ position: static;
+ height: 100%;
+ z-index: 1100; }
+ [type="checkbox"].drawer:not(.persistent) + * .drawer-close {
+ display: none; } }
+
+/*
+ Definitions for the responsive table component.
+*/
+/* Table module CSS variable definitions. */
+:root {
+ --table-border-color: #03234b;
+ --table-border-separator-color: #03234b;
+ --table-head-back-color: #03234b;
+ --table-head-fore-color: #ffffff;
+ --table-body-back-color: #ffffff;
+ --table-body-fore-color: #03234b;
+ --table-body-alt-back-color: #f4f4f4; }
+
+table {
+ border-collapse: separate;
+ border-spacing: 0;
+ margin: 0;
+ display: flex;
+ flex: 0 1 auto;
+ flex-flow: row wrap;
+ padding: var(--universal-padding);
+ padding-top: 0; }
+ table caption {
+ font-size: 1rem;
+ margin: calc(2 * var(--universal-margin)) 0;
+ max-width: 100%;
+ flex: 0 0 100%; }
+ table thead, table tbody {
+ display: flex;
+ flex-flow: row wrap;
+ border: 0.0714285714rem solid var(--table-border-color); }
+ table thead {
+ z-index: 999;
+ border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0;
+ border-bottom: 0.0714285714rem solid var(--table-border-separator-color); }
+ table tbody {
+ border-top: 0;
+ margin-top: calc(0 - var(--universal-margin));
+ border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); }
+ table tr {
+ display: flex;
+ padding: 0; }
+ table th, table td {
+ padding: calc(0.5 * var(--universal-padding));
+ font-size: 0.9rem; }
+ table th {
+ text-align: left;
+ background: var(--table-head-back-color);
+ color: var(--table-head-fore-color); }
+ table td {
+ background: var(--table-body-back-color);
+ color: var(--table-body-fore-color);
+ border-top: 0.0714285714rem solid var(--table-border-color); }
+
+table:not(.horizontal) {
+ overflow: auto;
+ max-height: 100%; }
+ table:not(.horizontal) thead, table:not(.horizontal) tbody {
+ max-width: 100%;
+ flex: 0 0 100%; }
+ table:not(.horizontal) tr {
+ flex-flow: row wrap;
+ flex: 0 0 100%; }
+ table:not(.horizontal) th, table:not(.horizontal) td {
+ flex: 1 0 0%;
+ overflow: hidden;
+ text-overflow: ellipsis; }
+ table:not(.horizontal) thead {
+ position: sticky;
+ top: 0; }
+ table:not(.horizontal) tbody tr:first-child td {
+ border-top: 0; }
+
+table.horizontal {
+ border: 0; }
+ table.horizontal thead, table.horizontal tbody {
+ border: 0;
+ flex: .2 0 0;
+ flex-flow: row nowrap; }
+ table.horizontal tbody {
+ overflow: auto;
+ justify-content: space-between;
+ flex: .8 0 0;
+ margin-left: 0;
+ padding-bottom: calc(var(--universal-padding) / 4); }
+ table.horizontal tr {
+ flex-direction: column;
+ flex: 1 0 auto; }
+ table.horizontal th, table.horizontal td {
+ width: auto;
+ border: 0;
+ border-bottom: 0.0714285714rem solid var(--table-border-color); }
+ table.horizontal th:not(:first-child), table.horizontal td:not(:first-child) {
+ border-top: 0; }
+ table.horizontal th {
+ text-align: right;
+ border-left: 0.0714285714rem solid var(--table-border-color);
+ border-right: 0.0714285714rem solid var(--table-border-separator-color); }
+ table.horizontal thead tr:first-child {
+ padding-left: 0; }
+ table.horizontal th:first-child, table.horizontal td:first-child {
+ border-top: 0.0714285714rem solid var(--table-border-color); }
+ table.horizontal tbody tr:last-child td {
+ border-right: 0.0714285714rem solid var(--table-border-color); }
+ table.horizontal tbody tr:last-child td:first-child {
+ border-top-right-radius: 0.25rem; }
+ table.horizontal tbody tr:last-child td:last-child {
+ border-bottom-right-radius: 0.25rem; }
+ table.horizontal thead tr:first-child th:first-child {
+ border-top-left-radius: 0.25rem; }
+ table.horizontal thead tr:first-child th:last-child {
+ border-bottom-left-radius: 0.25rem; }
+
+@media screen and (max-width: 499px) {
+ table, table.horizontal {
+ border-collapse: collapse;
+ border: 0;
+ width: 100%;
+ display: table; }
+ table thead, table th, table.horizontal thead, table.horizontal th {
+ border: 0;
+ height: 1px;
+ width: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ clip: rect(0 0 0 0);
+ -webkit-clip-path: inset(100%);
+ clip-path: inset(100%); }
+ table tbody, table.horizontal tbody {
+ border: 0;
+ display: table-row-group; }
+ table tr, table.horizontal tr {
+ display: block;
+ border: 0.0714285714rem solid var(--table-border-color);
+ border-radius: var(--universal-border-radius);
+ background: #ffffff;
+ padding: var(--universal-padding);
+ margin: var(--universal-margin);
+ margin-bottom: calc(1 * var(--universal-margin)); }
+ table th, table td, table.horizontal th, table.horizontal td {
+ width: auto; }
+ table td, table.horizontal td {
+ display: block;
+ border: 0;
+ text-align: right; }
+ table td:before, table.horizontal td:before {
+ content: attr(data-label);
+ float: left;
+ font-weight: 600; }
+ table th:first-child, table td:first-child, table.horizontal th:first-child, table.horizontal td:first-child {
+ border-top: 0; }
+ table tbody tr:last-child td, table.horizontal tbody tr:last-child td {
+ border-right: 0; } }
+table tr:nth-of-type(2n) > td {
+ background: var(--table-body-alt-back-color); }
+
+@media screen and (max-width: 500px) {
+ table tr:nth-of-type(2n) {
+ background: var(--table-body-alt-back-color); } }
+:root {
+ --table-body-hover-back-color: #90caf9; }
+
+table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td {
+ background: var(--table-body-hover-back-color); }
+
+@media screen and (max-width: 500px) {
+ table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td {
+ background: var(--table-body-hover-back-color); } }
+/*
+ Definitions for contextual background elements, toasts and tooltips.
+*/
+/* Contextual module CSS variable definitions */
+:root {
+ --mark-back-color: #3cb4e6;
+ --mark-fore-color: #ffffff; }
+
+mark {
+ background: var(--mark-back-color);
+ color: var(--mark-fore-color);
+ font-size: 0.95em;
+ line-height: 1em;
+ border-radius: var(--universal-border-radius);
+ padding: calc(var(--universal-padding) / 4) var(--universal-padding); }
+ mark.inline-block {
+ display: inline-block;
+ font-size: 1em;
+ line-height: 1.4;
+ padding: calc(var(--universal-padding) / 2) var(--universal-padding); }
+
+:root {
+ --toast-back-color: #424242;
+ --toast-fore-color: #fafafa; }
+
+.toast {
+ position: fixed;
+ bottom: calc(var(--universal-margin) * 3);
+ left: 50%;
+ transform: translate(-50%, -50%);
+ z-index: 1111;
+ color: var(--toast-fore-color);
+ background: var(--toast-back-color);
+ border-radius: calc(var(--universal-border-radius) * 16);
+ padding: var(--universal-padding) calc(var(--universal-padding) * 3); }
+
+:root {
+ --tooltip-back-color: #212121;
+ --tooltip-fore-color: #fafafa; }
+
+.tooltip {
+ position: relative;
+ display: inline-block; }
+ .tooltip:before, .tooltip:after {
+ position: absolute;
+ opacity: 0;
+ clip: rect(0 0 0 0);
+ -webkit-clip-path: inset(100%);
+ clip-path: inset(100%);
+ transition: all 0.3s;
+ z-index: 1010;
+ left: 50%; }
+ .tooltip:not(.bottom):before, .tooltip:not(.bottom):after {
+ bottom: 75%; }
+ .tooltip.bottom:before, .tooltip.bottom:after {
+ top: 75%; }
+ .tooltip:hover:before, .tooltip:hover:after, .tooltip:focus:before, .tooltip:focus:after {
+ opacity: 1;
+ clip: auto;
+ -webkit-clip-path: inset(0%);
+ clip-path: inset(0%); }
+ .tooltip:before {
+ content: '';
+ background: transparent;
+ border: var(--universal-margin) solid transparent;
+ left: calc(50% - var(--universal-margin)); }
+ .tooltip:not(.bottom):before {
+ border-top-color: #212121; }
+ .tooltip.bottom:before {
+ border-bottom-color: #212121; }
+ .tooltip:after {
+ content: attr(aria-label);
+ color: var(--tooltip-fore-color);
+ background: var(--tooltip-back-color);
+ border-radius: var(--universal-border-radius);
+ padding: var(--universal-padding);
+ white-space: nowrap;
+ transform: translateX(-50%); }
+ .tooltip:not(.bottom):after {
+ margin-bottom: calc(2 * var(--universal-margin)); }
+ .tooltip.bottom:after {
+ margin-top: calc(2 * var(--universal-margin)); }
+
+:root {
+ --modal-overlay-color: rgba(0, 0, 0, 0.45);
+ --modal-close-color: #e6007e;
+ --modal-close-hover-color: #ffe97f; }
+
+[type="checkbox"].modal {
+ height: 1px;
+ width: 1px;
+ margin: -1px;
+ overflow: hidden;
+ position: absolute;
+ clip: rect(0 0 0 0);
+ -webkit-clip-path: inset(100%);
+ clip-path: inset(100%); }
+ [type="checkbox"].modal + div {
+ position: fixed;
+ top: 0;
+ left: 0;
+ display: none;
+ width: 100vw;
+ height: 100vh;
+ background: var(--modal-overlay-color); }
+ [type="checkbox"].modal + div .card {
+ margin: 0 auto;
+ max-height: 50vh;
+ overflow: auto; }
+ [type="checkbox"].modal + div .card .modal-close {
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 1.75rem;
+ height: 1.75rem;
+ border-radius: var(--universal-border-radius);
+ padding: var(--universal-padding);
+ margin: 0;
+ cursor: pointer;
+ transition: background 0.3s; }
+ [type="checkbox"].modal + div .card .modal-close:before {
+ display: block;
+ content: '\00D7';
+ color: var(--modal-close-color);
+ position: relative;
+ font-family: sans-serif;
+ font-size: 1.75rem;
+ line-height: 1;
+ text-align: center; }
+ [type="checkbox"].modal + div .card .modal-close:hover, [type="checkbox"].modal + div .card .modal-close:focus {
+ background: var(--modal-close-hover-color); }
+ [type="checkbox"].modal:checked + div {
+ display: flex;
+ flex: 0 1 auto;
+ z-index: 1200; }
+ [type="checkbox"].modal:checked + div .card .modal-close {
+ z-index: 1211; }
+
+:root {
+ --collapse-label-back-color: #03234b;
+ --collapse-label-fore-color: #ffffff;
+ --collapse-label-hover-back-color: #3cb4e6;
+ --collapse-selected-label-back-color: #3cb4e6;
+ --collapse-border-color: var(--collapse-label-back-color);
+ --collapse-selected-border-color: #ceecf8;
+ --collapse-content-back-color: #ffffff;
+ --collapse-selected-label-border-color: #3cb4e6; }
+
+.collapse {
+ width: calc(100% - 2 * var(--universal-margin));
+ opacity: 1;
+ display: flex;
+ flex-direction: column;
+ margin: var(--universal-margin);
+ border-radius: var(--universal-border-radius); }
+ .collapse > [type="radio"], .collapse > [type="checkbox"] {
+ height: 1px;
+ width: 1px;
+ margin: -1px;
+ overflow: hidden;
+ position: absolute;
+ clip: rect(0 0 0 0);
+ -webkit-clip-path: inset(100%);
+ clip-path: inset(100%); }
+ .collapse > label {
+ flex-grow: 1;
+ display: inline-block;
+ height: 1.25rem;
+ cursor: pointer;
+ transition: background 0.2s;
+ color: var(--collapse-label-fore-color);
+ background: var(--collapse-label-back-color);
+ border: 0.0714285714rem solid var(--collapse-selected-border-color);
+ padding: calc(1.25 * var(--universal-padding)); }
+ .collapse > label:hover, .collapse > label:focus {
+ background: var(--collapse-label-hover-back-color); }
+ .collapse > label + div {
+ flex-basis: auto;
+ height: 1px;
+ width: 1px;
+ margin: -1px;
+ overflow: hidden;
+ position: absolute;
+ clip: rect(0 0 0 0);
+ -webkit-clip-path: inset(100%);
+ clip-path: inset(100%);
+ transition: max-height 0.3s;
+ max-height: 1px; }
+ .collapse > :checked + label {
+ background: var(--collapse-selected-label-back-color);
+ border-color: var(--collapse-selected-label-border-color); }
+ .collapse > :checked + label + div {
+ box-sizing: border-box;
+ position: relative;
+ width: 100%;
+ height: auto;
+ overflow: auto;
+ margin: 0;
+ background: var(--collapse-content-back-color);
+ border: 0.0714285714rem solid var(--collapse-selected-border-color);
+ border-top: 0;
+ padding: var(--universal-padding);
+ clip: auto;
+ -webkit-clip-path: inset(0%);
+ clip-path: inset(0%);
+ max-height: 100%; }
+ .collapse > label:not(:first-of-type) {
+ border-top: 0; }
+ .collapse > label:first-of-type {
+ border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; }
+ .collapse > label:last-of-type:not(:first-of-type) {
+ border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); }
+ .collapse > label:last-of-type:first-of-type {
+ border-radius: var(--universal-border-radius); }
+ .collapse > :checked:last-of-type:not(:first-of-type) + label {
+ border-radius: 0; }
+ .collapse > :checked:last-of-type + label + div {
+ border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); }
+
+/*
+ Custom elements for contextual background elements, toasts and tooltips.
+*/
+mark.tertiary {
+ --mark-back-color: #3cb4e6; }
+
+mark.tag {
+ padding: calc(var(--universal-padding)/2) var(--universal-padding);
+ border-radius: 1em; }
+
+/*
+ Definitions for progress elements and spinners.
+*/
+/* Progress module CSS variable definitions */
+:root {
+ --progress-back-color: #3cb4e6;
+ --progress-fore-color: #555; }
+
+progress {
+ display: block;
+ vertical-align: baseline;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ height: 0.75rem;
+ width: calc(100% - 2 * var(--universal-margin));
+ margin: var(--universal-margin);
+ border: 0;
+ border-radius: calc(2 * var(--universal-border-radius));
+ background: var(--progress-back-color);
+ color: var(--progress-fore-color); }
+ progress::-webkit-progress-value {
+ background: var(--progress-fore-color);
+ border-top-left-radius: calc(2 * var(--universal-border-radius));
+ border-bottom-left-radius: calc(2 * var(--universal-border-radius)); }
+ progress::-webkit-progress-bar {
+ background: var(--progress-back-color); }
+ progress::-moz-progress-bar {
+ background: var(--progress-fore-color);
+ border-top-left-radius: calc(2 * var(--universal-border-radius));
+ border-bottom-left-radius: calc(2 * var(--universal-border-radius)); }
+ progress[value="1000"]::-webkit-progress-value {
+ border-radius: calc(2 * var(--universal-border-radius)); }
+ progress[value="1000"]::-moz-progress-bar {
+ border-radius: calc(2 * var(--universal-border-radius)); }
+ progress.inline {
+ display: inline-block;
+ vertical-align: middle;
+ width: 60%; }
+
+:root {
+ --spinner-back-color: #ddd;
+ --spinner-fore-color: #555; }
+
+@keyframes spinner-donut-anim {
+ 0% {
+ transform: rotate(0deg); }
+ 100% {
+ transform: rotate(360deg); } }
+.spinner {
+ display: inline-block;
+ margin: var(--universal-margin);
+ border: 0.25rem solid var(--spinner-back-color);
+ border-left: 0.25rem solid var(--spinner-fore-color);
+ border-radius: 50%;
+ width: 1.25rem;
+ height: 1.25rem;
+ animation: spinner-donut-anim 1.2s linear infinite; }
+
+/*
+ Custom elements for progress bars and spinners.
+*/
+progress.primary {
+ --progress-fore-color: #1976d2; }
+
+progress.secondary {
+ --progress-fore-color: #d32f2f; }
+
+progress.tertiary {
+ --progress-fore-color: #308732; }
+
+.spinner.primary {
+ --spinner-fore-color: #1976d2; }
+
+.spinner.secondary {
+ --spinner-fore-color: #d32f2f; }
+
+.spinner.tertiary {
+ --spinner-fore-color: #308732; }
+
+/*
+ Definitions for icons - powered by Feather (https://feathericons.com/).
+*/
+span[class^='icon-'] {
+ display: inline-block;
+ height: 1em;
+ width: 1em;
+ vertical-align: -0.125em;
+ background-size: contain;
+ margin: 0 calc(var(--universal-margin) / 4); }
+ span[class^='icon-'].secondary {
+ -webkit-filter: invert(25%);
+ filter: invert(25%); }
+ span[class^='icon-'].inverse {
+ -webkit-filter: invert(100%);
+ filter: invert(100%); }
+
+span.icon-alert {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E"); }
+span.icon-bookmark {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E"); }
+span.icon-calendar {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); }
+span.icon-credit {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E"); }
+span.icon-edit {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E"); }
+span.icon-link {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E"); }
+span.icon-help {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E"); }
+span.icon-home {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E"); }
+span.icon-info {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E"); }
+span.icon-lock {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E"); }
+span.icon-mail {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E"); }
+span.icon-location {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E"); }
+span.icon-phone {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E"); }
+span.icon-rss {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E"); }
+span.icon-search {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); }
+span.icon-settings {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E"); }
+span.icon-share {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E"); }
+span.icon-cart {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E"); }
+span.icon-upload {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E"); }
+span.icon-user {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); }
+
+/*
+ Definitions for STMicroelectronics icons (https://brandportal.st.com/document/26).
+*/
+span.icon-st-update {
+ background-image: url("Update.svg"); }
+span.icon-st-add {
+ background-image: url("Add button.svg"); }
+
+/*
+ Definitions for utilities and helper classes.
+*/
+/* Utility module CSS variable definitions */
+:root {
+ --generic-border-color: rgba(0, 0, 0, 0.3);
+ --generic-box-shadow: 0 0.2857142857rem 0.2857142857rem 0 rgba(0, 0, 0, 0.125), 0 0.1428571429rem 0.1428571429rem -0.1428571429rem rgba(0, 0, 0, 0.125); }
+
+.hidden {
+ display: none !important; }
+
+.visually-hidden {
+ position: absolute !important;
+ width: 1px !important;
+ height: 1px !important;
+ margin: -1px !important;
+ border: 0 !important;
+ padding: 0 !important;
+ clip: rect(0 0 0 0) !important;
+ -webkit-clip-path: inset(100%) !important;
+ clip-path: inset(100%) !important;
+ overflow: hidden !important; }
+
+.bordered {
+ border: 0.0714285714rem solid var(--generic-border-color) !important; }
+
+.rounded {
+ border-radius: var(--universal-border-radius) !important; }
+
+.circular {
+ border-radius: 50% !important; }
+
+.shadowed {
+ box-shadow: var(--generic-box-shadow) !important; }
+
+.responsive-margin {
+ margin: calc(var(--universal-margin) / 4) !important; }
+ @media screen and (min-width: 500px) {
+ .responsive-margin {
+ margin: calc(var(--universal-margin) / 2) !important; } }
+ @media screen and (min-width: 1280px) {
+ .responsive-margin {
+ margin: var(--universal-margin) !important; } }
+
+.responsive-padding {
+ padding: calc(var(--universal-padding) / 4) !important; }
+ @media screen and (min-width: 500px) {
+ .responsive-padding {
+ padding: calc(var(--universal-padding) / 2) !important; } }
+ @media screen and (min-width: 1280px) {
+ .responsive-padding {
+ padding: var(--universal-padding) !important; } }
+
+@media screen and (max-width: 499px) {
+ .hidden-sm {
+ display: none !important; } }
+@media screen and (min-width: 500px) and (max-width: 1279px) {
+ .hidden-md {
+ display: none !important; } }
+@media screen and (min-width: 1280px) {
+ .hidden-lg {
+ display: none !important; } }
+@media screen and (max-width: 499px) {
+ .visually-hidden-sm {
+ position: absolute !important;
+ width: 1px !important;
+ height: 1px !important;
+ margin: -1px !important;
+ border: 0 !important;
+ padding: 0 !important;
+ clip: rect(0 0 0 0) !important;
+ -webkit-clip-path: inset(100%) !important;
+ clip-path: inset(100%) !important;
+ overflow: hidden !important; } }
+@media screen and (min-width: 500px) and (max-width: 1279px) {
+ .visually-hidden-md {
+ position: absolute !important;
+ width: 1px !important;
+ height: 1px !important;
+ margin: -1px !important;
+ border: 0 !important;
+ padding: 0 !important;
+ clip: rect(0 0 0 0) !important;
+ -webkit-clip-path: inset(100%) !important;
+ clip-path: inset(100%) !important;
+ overflow: hidden !important; } }
+@media screen and (min-width: 1280px) {
+ .visually-hidden-lg {
+ position: absolute !important;
+ width: 1px !important;
+ height: 1px !important;
+ margin: -1px !important;
+ border: 0 !important;
+ padding: 0 !important;
+ clip: rect(0 0 0 0) !important;
+ -webkit-clip-path: inset(100%) !important;
+ clip-path: inset(100%) !important;
+ overflow: hidden !important; } }
+
+/*# sourceMappingURL=mini-custom.css.map */
+
+img[alt="ST logo"] { display: block; margin: auto; width: 75%; max-width: 250px; min-width: 71px; }
+img[alt="Cube logo"] { float: right; width: 30%; max-width: 10rem; min-width: 8rem; padding-right: 1rem;}
+
+.figure {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ text-align: center;
+}
\ No newline at end of file
diff --git a/Drivers/BSP/STM32F429I-Discovery/_htmresc/st_logo_2020.png b/Drivers/BSP/STM32F429I-Discovery/_htmresc/st_logo_2020.png
new file mode 100644
index 0000000..d6cebb5
Binary files /dev/null and b/Drivers/BSP/STM32F429I-Discovery/_htmresc/st_logo_2020.png differ
diff --git a/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery.c b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery.c
new file mode 100644
index 0000000..ac4f7d6
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery.c
@@ -0,0 +1,1108 @@
+/**
+ ******************************************************************************
+ * @file stm32f429i_discovery.c
+ * @author MCD Application Team
+ * @brief This file provides set of firmware functions to manage Leds and
+ * push-button available on STM32F429I-Discovery Kit from STMicroelectronics.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f429i_discovery.h"
+
+/** @defgroup BSP BSP
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY STM32F429I DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LOW_LEVEL STM32F429I DISCOVERY LOW LEVEL
+ * @brief This file provides set of firmware functions to manage Leds and push-button
+ * available on STM32F429I-Discovery Kit from STMicroelectronics.
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LOW_LEVEL_Private_TypesDefinitions STM32F429I DISCOVERY LOW LEVEL Private TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LOW_LEVEL_Private_Defines STM32F429I DISCOVERY LOW LEVEL Private Defines
+ * @{
+ */
+
+/**
+ * @brief STM32F429I DISCO BSP Driver version number V2.1.8
+ */
+#define __STM32F429I_DISCO_BSP_VERSION_MAIN (0x02) /*!< [31:24] main version */
+#define __STM32F429I_DISCO_BSP_VERSION_SUB1 (0x01) /*!< [23:16] sub1 version */
+#define __STM32F429I_DISCO_BSP_VERSION_SUB2 (0x08) /*!< [15:8] sub2 version */
+#define __STM32F429I_DISCO_BSP_VERSION_RC (0x00) /*!< [7:0] release candidate */
+#define __STM32F429I_DISCO_BSP_VERSION ((__STM32F429I_DISCO_BSP_VERSION_MAIN << 24)\
+ |(__STM32F429I_DISCO_BSP_VERSION_SUB1 << 16)\
+ |(__STM32F429I_DISCO_BSP_VERSION_SUB2 << 8 )\
+ |(__STM32F429I_DISCO_BSP_VERSION_RC))
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LOW_LEVEL_Private_Macros STM32F429I DISCOVERY LOW LEVEL Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LOW_LEVEL_Private_Variables STM32F429I DISCOVERY LOW LEVEL Private Variables
+ * @{
+ */
+GPIO_TypeDef *GPIO_PORT[LEDn] = {LED3_GPIO_PORT,
+ LED4_GPIO_PORT
+ };
+
+const uint16_t GPIO_PIN[LEDn] = {LED3_PIN,
+ LED4_PIN
+ };
+
+GPIO_TypeDef *BUTTON_PORT[BUTTONn] = {KEY_BUTTON_GPIO_PORT};
+const uint16_t BUTTON_PIN[BUTTONn] = {KEY_BUTTON_PIN};
+const uint8_t BUTTON_IRQn[BUTTONn] = {KEY_BUTTON_EXTI_IRQn};
+
+uint32_t I2cxTimeout = I2Cx_TIMEOUT_MAX; /*Instance == DISCOVERY_I2Cx)
+ {
+ /* Configure the GPIOs ---------------------------------------------------*/
+ /* Enable GPIO clock */
+ DISCOVERY_I2Cx_SDA_GPIO_CLK_ENABLE();
+ DISCOVERY_I2Cx_SCL_GPIO_CLK_ENABLE();
+
+ /* Configure I2C Tx as alternate function */
+ GPIO_InitStruct.Pin = DISCOVERY_I2Cx_SCL_PIN;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
+ GPIO_InitStruct.Alternate = DISCOVERY_I2Cx_SCL_SDA_AF;
+ HAL_GPIO_Init(DISCOVERY_I2Cx_SCL_GPIO_PORT, &GPIO_InitStruct);
+
+ /* Configure I2C Rx as alternate function */
+ GPIO_InitStruct.Pin = DISCOVERY_I2Cx_SDA_PIN;
+ HAL_GPIO_Init(DISCOVERY_I2Cx_SDA_GPIO_PORT, &GPIO_InitStruct);
+
+
+ /* Configure the Discovery I2Cx peripheral -------------------------------*/
+ /* Enable I2C3 clock */
+ DISCOVERY_I2Cx_CLOCK_ENABLE();
+
+ /* Force the I2C Peripheral Clock Reset */
+ DISCOVERY_I2Cx_FORCE_RESET();
+
+ /* Release the I2C Peripheral Clock Reset */
+ DISCOVERY_I2Cx_RELEASE_RESET();
+
+ /* Enable and set Discovery I2Cx Interrupt to the lowest priority */
+ HAL_NVIC_SetPriority(DISCOVERY_I2Cx_EV_IRQn, 0x0F, 0);
+ HAL_NVIC_EnableIRQ(DISCOVERY_I2Cx_EV_IRQn);
+
+ /* Enable and set Discovery I2Cx Interrupt to the lowest priority */
+ HAL_NVIC_SetPriority(DISCOVERY_I2Cx_ER_IRQn, 0x0F, 0);
+ HAL_NVIC_EnableIRQ(DISCOVERY_I2Cx_ER_IRQn);
+
+#ifdef EE_M24LR64
+ /* I2C DMA TX and RX channels configuration */
+ /* Enable the DMA clock */
+ EEPROM_I2C_DMA_CLK_ENABLE();
+
+ /* Configure the DMA stream for the EE I2C peripheral TX direction */
+ /* Configure the DMA Stream */
+ hdma_tx.Instance = EEPROM_I2C_DMA_STREAM_TX;
+ /* Set the parameters to be configured */
+ hdma_tx.Init.Channel = EEPROM_I2C_DMA_CHANNEL;
+ hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+ hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+ hdma_tx.Init.Mode = DMA_NORMAL;
+ hdma_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
+ hdma_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
+ hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_tx.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+ /* Associate the initilalized hdma_tx handle to the the pI2cHandle handle */
+ __HAL_LINKDMA(pI2cHandle, hdmatx, hdma_tx);
+
+ /* Configure the DMA Stream */
+ HAL_DMA_Init(&hdma_tx);
+
+ /* Configure and enable I2C DMA TX Channel interrupt */
+ HAL_NVIC_SetPriority((IRQn_Type)(EEPROM_I2C_DMA_TX_IRQn), EEPROM_I2C_DMA_PREPRIO, 0);
+ HAL_NVIC_EnableIRQ((IRQn_Type)(EEPROM_I2C_DMA_TX_IRQn));
+
+ /* Configure the DMA stream for the EE I2C peripheral TX direction */
+ /* Configure the DMA Stream */
+ hdma_rx.Instance = EEPROM_I2C_DMA_STREAM_RX;
+ /* Set the parameters to be configured */
+ hdma_rx.Init.Channel = EEPROM_I2C_DMA_CHANNEL;
+ hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+ hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+ hdma_rx.Init.Mode = DMA_NORMAL;
+ hdma_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
+ hdma_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
+ hdma_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_rx.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+ /* Associate the initilalized hdma_rx handle to the the pI2cHandle handle*/
+ __HAL_LINKDMA(pI2cHandle, hdmarx, hdma_rx);
+
+ /* Configure the DMA Stream */
+ HAL_DMA_Init(&hdma_rx);
+
+ /* Configure and enable I2C DMA RX Channel interrupt */
+ HAL_NVIC_SetPriority((IRQn_Type)(EEPROM_I2C_DMA_RX_IRQn), EEPROM_I2C_DMA_PREPRIO, 0);
+ HAL_NVIC_EnableIRQ((IRQn_Type)(EEPROM_I2C_DMA_RX_IRQn));
+#endif /* EE_M24LR64 */
+ }
+}
+
+/**
+ * @brief I2Cx Bus initialization.
+ */
+static void I2Cx_Init(void)
+{
+ if (HAL_I2C_GetState(&I2cHandle) == HAL_I2C_STATE_RESET)
+ {
+ I2cHandle.Instance = DISCOVERY_I2Cx;
+ I2cHandle.Init.ClockSpeed = BSP_I2C_SPEED;
+ I2cHandle.Init.DutyCycle = I2C_DUTYCYCLE_2;
+ I2cHandle.Init.OwnAddress1 = 0;
+ I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
+ I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
+ I2cHandle.Init.OwnAddress2 = 0;
+ I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
+ I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
+
+ /* Init the I2C */
+ I2Cx_MspInit(&I2cHandle);
+ HAL_I2C_Init(&I2cHandle);
+ }
+}
+
+/**
+ * @brief Configures Interruption pin for I2C communication.
+ */
+static void I2Cx_ITConfig(void)
+{
+ GPIO_InitTypeDef GPIO_InitStruct;
+
+ /* Enable the GPIO EXTI Clock */
+ STMPE811_INT_CLK_ENABLE();
+
+ GPIO_InitStruct.Pin = STMPE811_INT_PIN;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+ GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
+ HAL_GPIO_Init(STMPE811_INT_GPIO_PORT, &GPIO_InitStruct);
+
+ /* Enable and set GPIO EXTI Interrupt to the highest priority */
+ HAL_NVIC_SetPriority((IRQn_Type)(STMPE811_INT_EXTI), 0x0F, 0x00);
+ HAL_NVIC_EnableIRQ((IRQn_Type)(STMPE811_INT_EXTI));
+}
+
+/**
+ * @brief Writes a value in a register of the device through BUS.
+ * @param Addr: Device address on BUS Bus.
+ * @param Reg: The target register address to write
+ * @param Value: The target register value to be written
+ */
+static void I2Cx_WriteData(uint8_t Addr, uint8_t Reg, uint8_t Value)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ status = HAL_I2C_Mem_Write(&I2cHandle, Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, &Value, 1, I2cxTimeout);
+
+ /* Check the communication status */
+ if (status != HAL_OK)
+ {
+ /* Re-Initialize the BUS */
+ I2Cx_Error();
+ }
+}
+
+/**
+ * @brief Writes a value in a register of the device through BUS.
+ * @param Addr: Device address on BUS Bus.
+ * @param Reg: The target register address to write
+ * @param pBuffer: The target register value to be written
+ * @param Length: buffer size to be written
+ */
+static void I2Cx_WriteBuffer(uint8_t Addr, uint8_t Reg, uint8_t *pBuffer, uint16_t Length)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ status = HAL_I2C_Mem_Write(&I2cHandle, Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, pBuffer, Length, I2cxTimeout);
+
+ /* Check the communication status */
+ if (status != HAL_OK)
+ {
+ /* Re-Initialize the BUS */
+ I2Cx_Error();
+ }
+}
+
+/**
+ * @brief Reads a register of the device through BUS.
+ * @param Addr: Device address on BUS Bus.
+ * @param Reg: The target register address to write
+ * @retval Data read at register address
+ */
+static uint8_t I2Cx_ReadData(uint8_t Addr, uint8_t Reg)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ uint8_t value = 0;
+
+ status = HAL_I2C_Mem_Read(&I2cHandle, Addr, Reg, I2C_MEMADD_SIZE_8BIT, &value, 1, I2cxTimeout);
+
+ /* Check the communication status */
+ if (status != HAL_OK)
+ {
+ /* Re-Initialize the BUS */
+ I2Cx_Error();
+
+ }
+ return value;
+}
+
+/**
+ * @brief Reads multiple data on the BUS.
+ * @param Addr: I2C Address
+ * @param Reg: Reg Address
+ * @param pBuffer: pointer to read data buffer
+ * @param Length: length of the data
+ * @retval 0 if no problems to read multiple data
+ */
+static uint8_t I2Cx_ReadBuffer(uint8_t Addr, uint8_t Reg, uint8_t *pBuffer, uint16_t Length)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ status = HAL_I2C_Mem_Read(&I2cHandle, Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, pBuffer, Length, I2cxTimeout);
+
+ /* Check the communication status */
+ if (status == HAL_OK)
+ {
+ return 0;
+ }
+ else
+ {
+ /* Re-Initialize the BUS */
+ I2Cx_Error();
+
+ return 1;
+ }
+}
+
+#ifdef EE_M24LR64
+/**
+ * @brief Writes a value in a register of the device through BUS in using DMA mode.
+ * @param Addr: Device address on BUS Bus.
+ * @param Reg: The target register address to write
+ * @param pBuffer: The target register value to be written
+ * @param Length: buffer size to be written
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2Cx_WriteBufferDMA(uint8_t Addr, uint16_t Reg, uint8_t *pBuffer, uint16_t Length)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ status = HAL_I2C_Mem_Write_DMA(&I2cHandle, Addr, Reg, I2C_MEMADD_SIZE_16BIT, pBuffer, Length);
+
+ /* Check the communication status */
+ if (status != HAL_OK)
+ {
+ /* Re-Initialize the BUS */
+ I2Cx_Error();
+ }
+
+ return status;
+}
+
+/**
+ * @brief Reads multiple data on the BUS in using DMA mode.
+ * @param Addr: I2C Address
+ * @param Reg: Reg Address
+ * @param pBuffer: pointer to read data buffer
+ * @param Length: length of the data
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2Cx_ReadBufferDMA(uint8_t Addr, uint16_t Reg, uint8_t *pBuffer, uint16_t Length)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ status = HAL_I2C_Mem_Read_DMA(&I2cHandle, Addr, Reg, I2C_MEMADD_SIZE_16BIT, pBuffer, Length);
+
+ /* Check the communication status */
+ if (status != HAL_OK)
+ {
+ /* Re-Initialize the BUS */
+ I2Cx_Error();
+ }
+
+ return status;
+}
+
+/**
+ * @brief Checks if target device is ready for communication.
+ * @note This function is used with Memory devices
+ * @param DevAddress: Target device address
+ * @param Trials: Number of trials
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2Cx_IsDeviceReady(uint16_t DevAddress, uint32_t Trials)
+{
+ return (HAL_I2C_IsDeviceReady(&I2cHandle, DevAddress, Trials, I2cxTimeout));
+}
+#endif /* EE_M24LR64 */
+
+/**
+ * @brief I2Cx error treatment function
+ */
+static void I2Cx_Error(void)
+{
+ /* De-initialize the SPI communication BUS */
+ HAL_I2C_DeInit(&I2cHandle);
+
+ /* Re-Initialize the SPI communication BUS */
+ I2Cx_Init();
+}
+
+/******************************* SPI Routines *********************************/
+
+/**
+ * @brief SPIx Bus initialization
+ */
+static void SPIx_Init(void)
+{
+ if (HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_RESET)
+ {
+ /* SPI configuration -----------------------------------------------------*/
+ SpiHandle.Instance = DISCOVERY_SPIx;
+ /* SPI baudrate is set to 5.6 MHz (PCLK2/SPI_BaudRatePrescaler = 90/16 = 5.625 MHz)
+ to verify these constraints:
+ - ILI9341 LCD SPI interface max baudrate is 10MHz for write and 6.66MHz for read
+ - l3gd20 SPI interface max baudrate is 10MHz for write/read
+ - PCLK2 frequency is set to 90 MHz
+ */
+ SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
+
+ /* On STM32F429I-Discovery, LCD ID cannot be read then keep a common configuration */
+ /* for LCD and GYRO (SPI_DIRECTION_2LINES) */
+ /* Note: To read a register a LCD, SPI_DIRECTION_1LINE should be set */
+ SpiHandle.Init.Direction = SPI_DIRECTION_2LINES;
+ SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
+ SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
+ SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
+ SpiHandle.Init.CRCPolynomial = 7;
+ SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT;
+ SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
+ SpiHandle.Init.NSS = SPI_NSS_SOFT;
+ SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED;
+ SpiHandle.Init.Mode = SPI_MODE_MASTER;
+
+ SPIx_MspInit(&SpiHandle);
+ HAL_SPI_Init(&SpiHandle);
+ }
+}
+
+/**
+ * @brief Reads 4 bytes from device.
+ * @param ReadSize: Number of bytes to read (max 4 bytes)
+ * @retval Value read on the SPI
+ */
+static uint32_t SPIx_Read(uint8_t ReadSize)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ uint32_t readvalue;
+
+ status = HAL_SPI_Receive(&SpiHandle, (uint8_t *) &readvalue, ReadSize, SpixTimeout);
+
+ /* Check the communication status */
+ if (status != HAL_OK)
+ {
+ /* Re-Initialize the BUS */
+ SPIx_Error();
+ }
+
+ return readvalue;
+}
+
+/**
+ * @brief Writes a byte to device.
+ * @param Value: value to be written
+ */
+static void SPIx_Write(uint16_t Value)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ status = HAL_SPI_Transmit(&SpiHandle, (uint8_t *) &Value, 1, SpixTimeout);
+
+ /* Check the communication status */
+ if (status != HAL_OK)
+ {
+ /* Re-Initialize the BUS */
+ SPIx_Error();
+ }
+}
+
+/**
+ * @brief Sends a Byte through the SPI interface and return the Byte received
+ * from the SPI bus.
+ * @param Byte: Byte send.
+ * @retval The received byte value
+ */
+static uint8_t SPIx_WriteRead(uint8_t Byte)
+{
+ uint8_t receivedbyte = 0;
+
+ /* Send a Byte through the SPI peripheral */
+ /* Read byte from the SPI bus */
+ if (HAL_SPI_TransmitReceive(&SpiHandle, (uint8_t *) &Byte, (uint8_t *) &receivedbyte, 1, SpixTimeout) != HAL_OK)
+ {
+ SPIx_Error();
+ }
+
+ return receivedbyte;
+}
+
+/**
+ * @brief SPIx error treatment function.
+ */
+static void SPIx_Error(void)
+{
+ /* De-initialize the SPI communication BUS */
+ HAL_SPI_DeInit(&SpiHandle);
+
+ /* Re- Initialize the SPI communication BUS */
+ SPIx_Init();
+}
+
+/**
+ * @brief SPI MSP Init.
+ * @param hspi: SPI handle
+ */
+static void SPIx_MspInit(SPI_HandleTypeDef *hspi)
+{
+ GPIO_InitTypeDef GPIO_InitStructure;
+
+ /* Enable SPIx clock */
+ DISCOVERY_SPIx_CLK_ENABLE();
+
+ /* Enable DISCOVERY_SPI GPIO clock */
+ DISCOVERY_SPIx_GPIO_CLK_ENABLE();
+
+ /* configure SPI SCK, MOSI and MISO */
+ GPIO_InitStructure.Pin = (DISCOVERY_SPIx_SCK_PIN | DISCOVERY_SPIx_MOSI_PIN | DISCOVERY_SPIx_MISO_PIN);
+ GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStructure.Pull = GPIO_PULLDOWN;
+ GPIO_InitStructure.Speed = GPIO_SPEED_MEDIUM;
+ GPIO_InitStructure.Alternate = DISCOVERY_SPIx_AF;
+ HAL_GPIO_Init(DISCOVERY_SPIx_GPIO_PORT, &GPIO_InitStructure);
+}
+
+/********************************* LINK LCD ***********************************/
+
+/**
+ * @brief Configures the LCD_SPI interface.
+ */
+void LCD_IO_Init(void)
+{
+ GPIO_InitTypeDef GPIO_InitStructure;
+
+ if (Is_LCD_IO_Initialized == 0)
+ {
+ Is_LCD_IO_Initialized = 1;
+
+ /* Configure NCS in Output Push-Pull mode */
+ LCD_WRX_GPIO_CLK_ENABLE();
+ GPIO_InitStructure.Pin = LCD_WRX_PIN;
+ GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStructure.Pull = GPIO_NOPULL;
+ GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
+ HAL_GPIO_Init(LCD_WRX_GPIO_PORT, &GPIO_InitStructure);
+
+ LCD_RDX_GPIO_CLK_ENABLE();
+ GPIO_InitStructure.Pin = LCD_RDX_PIN;
+ GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStructure.Pull = GPIO_NOPULL;
+ GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
+ HAL_GPIO_Init(LCD_RDX_GPIO_PORT, &GPIO_InitStructure);
+
+ /* Configure the LCD Control pins ----------------------------------------*/
+ LCD_NCS_GPIO_CLK_ENABLE();
+
+ /* Configure NCS in Output Push-Pull mode */
+ GPIO_InitStructure.Pin = LCD_NCS_PIN;
+ GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStructure.Pull = GPIO_NOPULL;
+ GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
+ HAL_GPIO_Init(LCD_NCS_GPIO_PORT, &GPIO_InitStructure);
+
+ /* Set or Reset the control line */
+ LCD_CS_LOW();
+ LCD_CS_HIGH();
+
+ SPIx_Init();
+ }
+}
+
+/**
+ * @brief Writes register value.
+ */
+void LCD_IO_WriteData(uint16_t RegValue)
+{
+ /* Set WRX to send data */
+ LCD_WRX_HIGH();
+
+ /* Reset LCD control line(/CS) and Send data */
+ LCD_CS_LOW();
+ SPIx_Write(RegValue);
+
+ /* Deselect: Chip Select high */
+ LCD_CS_HIGH();
+}
+
+/**
+ * @brief Writes register address.
+ */
+void LCD_IO_WriteReg(uint8_t Reg)
+{
+ /* Reset WRX to send command */
+ LCD_WRX_LOW();
+
+ /* Reset LCD control line(/CS) and Send command */
+ LCD_CS_LOW();
+ SPIx_Write(Reg);
+
+ /* Deselect: Chip Select high */
+ LCD_CS_HIGH();
+}
+
+/**
+ * @brief Reads register value.
+ * @param RegValue Address of the register to read
+ * @param ReadSize Number of bytes to read
+ * @retval Content of the register value
+ */
+uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize)
+{
+ uint32_t readvalue = 0;
+
+ /* Select: Chip Select low */
+ LCD_CS_LOW();
+
+ /* Reset WRX to send command */
+ LCD_WRX_LOW();
+
+ SPIx_Write(RegValue);
+
+ readvalue = SPIx_Read(ReadSize);
+
+ /* Set WRX to send data */
+ LCD_WRX_HIGH();
+
+ /* Deselect: Chip Select high */
+ LCD_CS_HIGH();
+
+ return readvalue;
+}
+
+/**
+ * @brief Wait for loop in ms.
+ * @param Delay in ms.
+ */
+void LCD_Delay(uint32_t Delay)
+{
+ HAL_Delay(Delay);
+}
+
+/*******************************************************************************
+ LINK OPERATIONS
+ *******************************************************************************/
+
+/********************************* LINK IOE ***********************************/
+
+/**
+ * @brief IOE Low Level Initialization.
+ */
+void IOE_Init(void)
+{
+ I2Cx_Init();
+}
+
+/**
+ * @brief IOE Low Level Interrupt configuration.
+ */
+void IOE_ITConfig(void)
+{
+ I2Cx_ITConfig();
+}
+
+/**
+ * @brief IOE Writes single data operation.
+ * @param Addr: I2C Address
+ * @param Reg: Reg Address
+ * @param Value: Data to be written
+ */
+void IOE_Write(uint8_t Addr, uint8_t Reg, uint8_t Value)
+{
+ I2Cx_WriteData(Addr, Reg, Value);
+}
+
+/**
+ * @brief IOE Reads single data.
+ * @param Addr: I2C Address
+ * @param Reg: Reg Address
+ * @retval The read data
+ */
+uint8_t IOE_Read(uint8_t Addr, uint8_t Reg)
+{
+ return I2Cx_ReadData(Addr, Reg);
+}
+
+/**
+ * @brief IOE Writes multiple data.
+ * @param Addr: I2C Address
+ * @param Reg: Reg Address
+ * @param pBuffer: pointer to data buffer
+ * @param Length: length of the data
+ */
+void IOE_WriteMultiple(uint8_t Addr, uint8_t Reg, uint8_t *pBuffer, uint16_t Length)
+{
+ I2Cx_WriteBuffer(Addr, Reg, pBuffer, Length);
+}
+
+/**
+ * @brief IOE Reads multiple data.
+ * @param Addr: I2C Address
+ * @param Reg: Reg Address
+ * @param pBuffer: pointer to data buffer
+ * @param Length: length of the data
+ * @retval 0 if no problems to read multiple data
+ */
+uint16_t IOE_ReadMultiple(uint8_t Addr, uint8_t Reg, uint8_t *pBuffer, uint16_t Length)
+{
+ return I2Cx_ReadBuffer(Addr, Reg, pBuffer, Length);
+}
+
+/**
+ * @brief IOE Delay.
+ * @param Delay in ms
+ */
+void IOE_Delay(uint32_t Delay)
+{
+ HAL_Delay(Delay);
+}
+
+/********************************* LINK GYROSCOPE *****************************/
+
+/**
+ * @brief Configures the Gyroscope SPI interface.
+ */
+void GYRO_IO_Init(void)
+{
+ GPIO_InitTypeDef GPIO_InitStructure;
+
+ /* Configure the Gyroscope Control pins ------------------------------------*/
+ /* Enable CS GPIO clock and Configure GPIO PIN for Gyroscope Chip select */
+ GYRO_CS_GPIO_CLK_ENABLE();
+ GPIO_InitStructure.Pin = GYRO_CS_PIN;
+ GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStructure.Pull = GPIO_NOPULL;
+ GPIO_InitStructure.Speed = GPIO_SPEED_MEDIUM;
+ HAL_GPIO_Init(GYRO_CS_GPIO_PORT, &GPIO_InitStructure);
+
+ /* Deselect: Chip Select high */
+ GYRO_CS_HIGH();
+
+ /* Enable INT1, INT2 GPIO clock and Configure GPIO PINs to detect Interrupts */
+ GYRO_INT_GPIO_CLK_ENABLE();
+ GPIO_InitStructure.Pin = GYRO_INT1_PIN | GYRO_INT2_PIN;
+ GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
+ GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
+ GPIO_InitStructure.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(GYRO_INT_GPIO_PORT, &GPIO_InitStructure);
+
+ SPIx_Init();
+}
+
+/**
+ * @brief Writes one byte to the Gyroscope.
+ * @param pBuffer: Pointer to the buffer containing the data to be written to the Gyroscope.
+ * @param WriteAddr: Gyroscope's internal address to write to.
+ * @param NumByteToWrite: Number of bytes to write.
+ */
+void GYRO_IO_Write(uint8_t *pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite)
+{
+ /* Configure the MS bit:
+ - When 0, the address will remain unchanged in multiple read/write commands.
+ - When 1, the address will be auto incremented in multiple read/write commands.
+ */
+ if (NumByteToWrite > 0x01)
+ {
+ WriteAddr |= (uint8_t)MULTIPLEBYTE_CMD;
+ }
+ /* Set chip select Low at the start of the transmission */
+ GYRO_CS_LOW();
+
+ /* Send the Address of the indexed register */
+ SPIx_WriteRead(WriteAddr);
+
+ /* Send the data that will be written into the device (MSB First) */
+ while (NumByteToWrite >= 0x01)
+ {
+ SPIx_WriteRead(*pBuffer);
+ NumByteToWrite--;
+ pBuffer++;
+ }
+
+ /* Set chip select High at the end of the transmission */
+ GYRO_CS_HIGH();
+}
+
+/**
+ * @brief Reads a block of data from the Gyroscope.
+ * @param pBuffer: Pointer to the buffer that receives the data read from the Gyroscope.
+ * @param ReadAddr: Gyroscope's internal address to read from.
+ * @param NumByteToRead: Number of bytes to read from the Gyroscope.
+ */
+void GYRO_IO_Read(uint8_t *pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead)
+{
+ if (NumByteToRead > 0x01)
+ {
+ ReadAddr |= (uint8_t)(READWRITE_CMD | MULTIPLEBYTE_CMD);
+ }
+ else
+ {
+ ReadAddr |= (uint8_t)READWRITE_CMD;
+ }
+ /* Set chip select Low at the start of the transmission */
+ GYRO_CS_LOW();
+
+ /* Send the Address of the indexed register */
+ SPIx_WriteRead(ReadAddr);
+
+ /* Receive the data that will be read from the device (MSB First) */
+ while (NumByteToRead > 0x00)
+ {
+ /* Send dummy byte (0x00) to generate the SPI clock to Gyroscope (Slave device) */
+ *pBuffer = SPIx_WriteRead(DUMMY_BYTE);
+ NumByteToRead--;
+ pBuffer++;
+ }
+
+ /* Set chip select High at the end of the transmission */
+ GYRO_CS_HIGH();
+}
+
+
+#ifdef EE_M24LR64
+
+/******************************** LINK I2C EEPROM *****************************/
+
+/**
+ * @brief Initializes peripherals used by the I2C EEPROM driver.
+ */
+void EEPROM_IO_Init(void)
+{
+ I2Cx_Init();
+}
+
+/**
+ * @brief Writes data to I2C EEPROM driver in using DMA channel.
+ * @param DevAddress: Target device address
+ * @param MemAddress: Internal memory address
+ * @param pBuffer: Pointer to data buffer
+ * @param BufferSize: Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef EEPROM_IO_WriteData(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pBuffer, uint32_t BufferSize)
+{
+ return (I2Cx_WriteBufferDMA(DevAddress, MemAddress, pBuffer, BufferSize));
+}
+
+/**
+ * @brief Reads data from I2C EEPROM driver in using DMA channel.
+ * @param DevAddress: Target device address
+ * @param MemAddress: Internal memory address
+ * @param pBuffer: Pointer to data buffer
+ * @param BufferSize: Amount of data to be read
+ * @retval HAL status
+ */
+HAL_StatusTypeDef EEPROM_IO_ReadData(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pBuffer, uint32_t BufferSize)
+{
+ return (I2Cx_ReadBufferDMA(DevAddress, MemAddress, pBuffer, BufferSize));
+}
+
+/**
+ * @brief Checks if target device is ready for communication.
+ * @note This function is used with Memory devices
+ * @param DevAddress: Target device address
+ * @param Trials: Number of trials
+ * @retval HAL status
+ */
+HAL_StatusTypeDef EEPROM_IO_IsDeviceReady(uint16_t DevAddress, uint32_t Trials)
+{
+ return (I2Cx_IsDeviceReady(DevAddress, Trials));
+}
+#endif /* EE_M24LR64 */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery.h b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery.h
new file mode 100644
index 0000000..1eac191
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery.h
@@ -0,0 +1,333 @@
+/**
+ ******************************************************************************
+ * @file stm32f429i_discovery.h
+ * @author MCD Application Team
+ * @brief This file contains definitions for STM32F429I-Discovery Kit LEDs,
+ * push-buttons hardware resources.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+/* IMPORTANT: One of the following flags must be defined in the preprocessor */
+/* options in order to select the target board revision: !!!!!!!!!! */
+/* USE_STM32F429I_DISCO */ /* Applicable for all boards except STM32F429I DISCOVERY REVD and above */
+/* USE_STM32F429I_DISCOVERY_REVD */ /* Applicable only for STM32F429I DISCOVERY REVD and above */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F429I_DISCOVERY_H
+#define __STM32F429I_DISCOVERY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY_LOW_LEVEL
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY_LOW_LEVEL_Exported_Types STM32F429I DISCOVERY LOW LEVEL Exported Types
+ * @{
+ */
+typedef enum
+{
+ LED3 = 0,
+ LED4 = 1
+} Led_TypeDef;
+
+typedef enum
+{
+ BUTTON_KEY = 0,
+} Button_TypeDef;
+
+typedef enum
+{
+ BUTTON_MODE_GPIO = 0,
+ BUTTON_MODE_EXTI = 1
+} ButtonMode_TypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LOW_LEVEL_Exported_Constants STM32F429I DISCOVERY LOW LEVEL Exported Constants
+ * @{
+ */
+
+/**
+ * @brief Define for STM32F429I_DISCO board
+ */
+#if !defined(USE_STM32F429I_DISCOVERY_REVD) && \
+ !defined(USE_STM32F429I_DISCO)
+#define USE_STM32F429I_DISCO
+#endif
+
+/** @defgroup STM32F429I_DISCOVERY_LOW_LEVEL_LED STM32F429I DISCOVERY LOW LEVEL LED
+ * @{
+ */
+#define LEDn 2
+
+#define LED3_PIN GPIO_PIN_13
+#define LED3_GPIO_PORT GPIOG
+#define LED3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
+#define LED3_GPIO_CLK_DISABLE() __HAL_RCC_GPIOG_CLK_DISABLE()
+
+#define LED4_PIN GPIO_PIN_14
+#define LED4_GPIO_PORT GPIOG
+#define LED4_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
+#define LED4_GPIO_CLK_DISABLE() __HAL_RCC_GPIOG_CLK_DISABLE()
+
+#define LEDx_GPIO_CLK_ENABLE(__INDEX__) do{if((__INDEX__) == 0) LED3_GPIO_CLK_ENABLE(); else \
+ if((__INDEX__) == 1) LED4_GPIO_CLK_ENABLE(); \
+ }while(0)
+#define LEDx_GPIO_CLK_DISABLE(__INDEX__) do{if((__INDEX__) == 0) LED3_GPIO_CLK_DISABLE(); else \
+ if((__INDEX__) == 1) LED4_GPIO_CLK_DISABLE(); \
+ }while(0)
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LOW_LEVEL_BUTTON STM32F429I DISCOVERY LOW LEVEL BUTTON
+ * @{
+ */
+#define BUTTONn 1
+
+/**
+ * @brief Wakeup push-button
+ */
+#define KEY_BUTTON_PIN GPIO_PIN_0
+#define KEY_BUTTON_GPIO_PORT GPIOA
+#define KEY_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define KEY_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#define KEY_BUTTON_EXTI_IRQn EXTI0_IRQn
+
+#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) do{if((__INDEX__) == 0) KEY_BUTTON_GPIO_CLK_ENABLE(); \
+ }while(0)
+#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__) do{if((__INDEX__) == 0) KEY_BUTTON_GPIO_CLK_DISABLE(); \
+ }while(0)
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LOW_LEVEL_BUS STM32F429I DISCOVERY LOW LEVEL BUS
+ * @{
+ */
+/* Exported constanIO --------------------------------------------------------*/
+#define IO_I2C_ADDRESS 0x82
+#define TS_I2C_ADDRESS 0x82
+
+#ifdef EE_M24LR64
+#define EEPROM_I2C_ADDRESS_A01 0xA0
+#define EEPROM_I2C_ADDRESS_A02 0xA6
+#endif /* EE_M24LR64 */
+
+/*############################### I2Cx #######################################*/
+/* User can use this section to tailor I2Cx instance used and associated
+ resources */
+#define DISCOVERY_I2Cx I2C3
+#define DISCOVERY_I2Cx_CLOCK_ENABLE() __HAL_RCC_I2C3_CLK_ENABLE()
+#define DISCOVERY_I2Cx_FORCE_RESET() __HAL_RCC_I2C3_FORCE_RESET()
+#define DISCOVERY_I2Cx_RELEASE_RESET() __HAL_RCC_I2C3_RELEASE_RESET()
+#define DISCOVERY_I2Cx_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define DISCOVERY_I2Cx_SCL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define DISCOVERY_I2Cx_SDA_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
+
+/* Definition for DISCO I2Cx Pins */
+#define DISCOVERY_I2Cx_SCL_PIN GPIO_PIN_8
+#define DISCOVERY_I2Cx_SCL_GPIO_PORT GPIOA
+#define DISCOVERY_I2Cx_SCL_SDA_AF GPIO_AF4_I2C3
+#define DISCOVERY_I2Cx_SDA_PIN GPIO_PIN_9
+#define DISCOVERY_I2Cx_SDA_GPIO_PORT GPIOC
+
+/* Definition for IOE I2Cx's NVIC */
+#define DISCOVERY_I2Cx_EV_IRQn I2C3_EV_IRQn
+#define DISCOVERY_I2Cx_ER_IRQn I2C3_ER_IRQn
+
+/* I2C clock speed configuration (in Hz)
+ WARNING:
+ Make sure that this define is not already declared in other files.
+ It can be used in parallel by other modules. */
+#ifndef BSP_I2C_SPEED
+#define BSP_I2C_SPEED 100000
+#endif /* BSP_I2C_SPEED */
+
+#define I2Cx_TIMEOUT_MAX 0x3000 /* 0)
+ {
+ if (HAL_GetTick() > EEPROMTimeout)
+ {
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ return EEPROM_TIMEOUT;
+ }
+ }
+
+ /* 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)
+ {
+ status = EEPROM_FAIL;
+ }
+
+ /* Wait transfer through DMA to be complete */
+ EEPROMTimeout = HAL_GetTick() + EEPROM_WRITE_TIMEOUT;
+ while (EEPROMDataWrite > 0)
+ {
+ if (HAL_GetTick() > EEPROMTimeout)
+ {
+ BSP_EEPROM_TIMEOUT_UserCallback();
+ return EEPROM_TIMEOUT;
+ }
+ }
+
+ 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 Memory Tx Transfer completed callbacks.
+ * @param hi2c: I2C handle
+ */
+void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c)
+{
+ EEPROMDataWrite = 0;
+}
+
+/**
+ * @brief Memory Rx Transfer completed callbacks.
+ * @param hi2c: I2C handle
+ */
+void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c)
+{
+ EEPROMDataRead = 0;
+}
+
+/**
+ * @brief Basic management of the timeout situation.
+ */
+__weak void BSP_EEPROM_TIMEOUT_UserCallback(void)
+{
+}
+
+#endif /* EE_M24LR64 */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_eeprom.h b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_eeprom.h
new file mode 100644
index 0000000..8aeb4a7
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_eeprom.h
@@ -0,0 +1,124 @@
+/**
+ ******************************************************************************
+ * @file stm32f429i_discovery_eeprom.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for
+ * the stm32f429i_discovery_eeprom.c firmware driver.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F429I_DISCOVERY_EEPROM_H
+#define __STM32F429I_DISCOVERY_EEPROM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f429i_discovery.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY_EEPROM STM32F429I DISCOVERY EEPROM
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_EEPROM_Exported_Types STM32F429I DISCOVERY EEPROM Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_EEPROM_Exported_Constants STM32F429I DISCOVERY EEPROM Exported Constants
+ * @{
+ */
+/* EEPROM hardware address and page size */
+#define EEPROM_PAGESIZE 4
+#define EEPROM_MAX_SIZE 0x2000 /* 64Kbit*/
+
+/* Maximum Timeout values for flags and events waiting loops.
+This timeout is based on systick set to 1ms*/
+/* Timeout for read based if read all the EEPROM : EEPROM_MAX_SIZE * BSP_I2C_SPEED (640ms)*/
+#define EEPROM_READ_TIMEOUT ((uint32_t)(1000))
+/* Timeout for write based on max write which is EEPROM_PAGESIZE bytes: EEPROM_PAGESIZE * BSP_I2C_SPEED (320us)*/
+#define EEPROM_WRITE_TIMEOUT ((uint32_t)(1))
+
+/* Maximum number of trials for EEPROM_WaitEepromStandbyState() function */
+#define EEPROM_MAX_TRIALS 300
+
+#define EEPROM_OK 0
+#define EEPROM_FAIL 1
+#define EEPROM_TIMEOUT 2
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_EEPROM_Exported_Macros STM32F429I DISCOVERY EEPROM Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_EEPROM_Exported_Functions STM32F429I DISCOVERY EEPROM Exported Functions
+ * @{
+ */
+uint32_t BSP_EEPROM_Init(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 /* __STM32F429I_DISCOVERY_EEPROM_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_gyroscope.c b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_gyroscope.c
new file mode 100644
index 0000000..4a9209a
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_gyroscope.c
@@ -0,0 +1,273 @@
+/**
+ ******************************************************************************
+ * @file stm32f429i_discovery_gyroscope.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the
+ * MEMS gyroscope available on STM32F429I-Discovery Kit.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f429i_discovery_gyroscope.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_GYROSCOPE STM32F429I DISCOVERY GYROSCOPE
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_GYROSCOPE_Private_TypesDefinitions STM32F429I DISCOVERY GYROSCOPE Private TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_GYROSCOPE_Private_Defines STM32F429I DISCOVERY GYROSCOPE Private Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_GYROSCOPE_Private_Macros STM32F429I DISCOVERY GYROSCOPE Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_GYROSCOPE_Private_Variables STM32F429I DISCOVERY GYROSCOPE Private Variables
+ * @{
+ */
+static GYRO_DrvTypeDef *GyroscopeDrv;
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_GYROSCOPE_Private_FunctionPrototypes STM32F429I DISCOVERY GYROSCOPE Private FunctionPrototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_GYROSCOPE_Private_Functions STM32F429I DISCOVERY GYROSCOPE Private Functions
+ * @{
+ */
+
+/**
+ * @brief Set gyroscope Initialization.
+ * @retval GYRO_OK if no problem during initialization
+ */
+uint8_t BSP_GYRO_Init(void)
+{
+ uint8_t ret = GYRO_ERROR;
+ uint16_t ctrl = 0x0000;
+ GYRO_InitTypeDef Gyro_InitStructure;
+ GYRO_FilterConfigTypeDef Gyro_FilterStructure = {0, 0};
+
+ if ((L3gd20Drv.ReadID() == I_AM_L3GD20) || (L3gd20Drv.ReadID() == I_AM_L3GD20_TR))
+ {
+ /* Initialize the gyroscope driver structure */
+ GyroscopeDrv = &L3gd20Drv;
+
+ /* MEMS configuration ----------------------------------------------------*/
+ /* Fill the gyroscope structure */
+ Gyro_InitStructure.Power_Mode = L3GD20_MODE_ACTIVE;
+ Gyro_InitStructure.Output_DataRate = L3GD20_OUTPUT_DATARATE_1;
+ Gyro_InitStructure.Axes_Enable = L3GD20_AXES_ENABLE;
+ Gyro_InitStructure.Band_Width = L3GD20_BANDWIDTH_4;
+ Gyro_InitStructure.BlockData_Update = L3GD20_BlockDataUpdate_Continous;
+ Gyro_InitStructure.Endianness = L3GD20_BLE_LSB;
+ Gyro_InitStructure.Full_Scale = L3GD20_FULLSCALE_500;
+
+ /* Configure MEMS: data rate, power mode, full scale and axes */
+ ctrl = (uint16_t)(Gyro_InitStructure.Power_Mode | Gyro_InitStructure.Output_DataRate | \
+ Gyro_InitStructure.Axes_Enable | Gyro_InitStructure.Band_Width);
+
+ ctrl |= (uint16_t)((Gyro_InitStructure.BlockData_Update | Gyro_InitStructure.Endianness | \
+ Gyro_InitStructure.Full_Scale) << 8);
+
+ /* Initialize the gyroscope */
+ GyroscopeDrv->Init(ctrl);
+
+ Gyro_FilterStructure.HighPassFilter_Mode_Selection = L3GD20_HPM_NORMAL_MODE_RES;
+ Gyro_FilterStructure.HighPassFilter_CutOff_Frequency = L3GD20_HPFCF_0;
+
+ ctrl = (uint8_t)((Gyro_FilterStructure.HighPassFilter_Mode_Selection | \
+ Gyro_FilterStructure.HighPassFilter_CutOff_Frequency));
+
+ /* Configure the gyroscope main parameters */
+ GyroscopeDrv->FilterConfig(ctrl) ;
+
+ GyroscopeDrv->FilterCmd(L3GD20_HIGHPASSFILTER_ENABLE);
+
+ ret = GYRO_OK;
+ }
+#if defined(USE_STM32F429I_DISCOVERY_REVD)
+ else if (I3g4250Drv.ReadID() == I_AM_I3G4250D)
+ {
+ /* Initialize the gyroscope driver structure */
+ GyroscopeDrv = &I3g4250Drv;
+
+ /* Configure Mems : data rate, power mode, full scale and axes */
+ Gyro_InitStructure.Power_Mode = I3G4250D_MODE_ACTIVE;
+ Gyro_InitStructure.Output_DataRate = I3G4250D_OUTPUT_DATARATE_1;
+ Gyro_InitStructure.Axes_Enable = I3G4250D_AXES_ENABLE;
+ Gyro_InitStructure.Band_Width = I3G4250D_BANDWIDTH_4;
+ Gyro_InitStructure.BlockData_Update = I3G4250D_BlockDataUpdate_Continous;
+ Gyro_InitStructure.Endianness = I3G4250D_BLE_LSB;
+ Gyro_InitStructure.Full_Scale = I3G4250D_FULLSCALE_500;
+
+ /* Configure MEMS: data rate, power mode, full scale and axes */
+ ctrl = (uint16_t)(Gyro_InitStructure.Power_Mode | Gyro_InitStructure.Output_DataRate | \
+ Gyro_InitStructure.Axes_Enable | Gyro_InitStructure.Band_Width);
+
+ ctrl |= (uint16_t)((Gyro_InitStructure.BlockData_Update | Gyro_InitStructure.Endianness | \
+ Gyro_InitStructure.Full_Scale) << 8);
+
+ /* Initialize the gyroscope */
+ GyroscopeDrv->Init(ctrl);
+
+ Gyro_FilterStructure.HighPassFilter_Mode_Selection = I3G4250D_HPM_NORMAL_MODE_RES;
+ Gyro_FilterStructure.HighPassFilter_CutOff_Frequency = I3G4250D_HPFCF_0;
+
+ ctrl = (uint8_t)((Gyro_FilterStructure.HighPassFilter_Mode_Selection | \
+ Gyro_FilterStructure.HighPassFilter_CutOff_Frequency));
+
+ /* Configure the gyroscope main parameters */
+ GyroscopeDrv->FilterConfig(ctrl);
+
+ GyroscopeDrv->FilterCmd(I3G4250D_HIGHPASSFILTER_ENABLE);
+
+ ret = GYRO_OK;
+ }
+#endif /* USE_STM32F429I_DISCOVERY_REVD */
+ return ret;
+}
+
+/**
+ * @brief Read ID of gyroscope component.
+ * @retval ID
+ */
+uint8_t BSP_GYRO_ReadID(void)
+{
+ uint8_t id = 0x00;
+
+ if (GyroscopeDrv->ReadID != NULL)
+ {
+ id = GyroscopeDrv->ReadID();
+ }
+ return id;
+}
+
+/**
+ * @brief Reboot memory content of Gyroscope.
+ */
+void BSP_GYRO_Reset(void)
+{
+ if (GyroscopeDrv->Reset != NULL)
+ {
+ GyroscopeDrv->Reset();
+ }
+}
+
+/**
+ * @brief Configures INT1 interrupt.
+ * @param pIntConfig: pointer to a L3GD20_InterruptConfig_TypeDef
+ * structure that contains the configuration setting for the L3GD20 Interrupt.
+ */
+void BSP_GYRO_ITConfig(GYRO_InterruptConfigTypeDef *pIntConfig)
+{
+ uint16_t interruptconfig = 0x0000;
+
+ if (GyroscopeDrv->ConfigIT != NULL)
+ {
+ /* Configure latch Interrupt request and axe interrupts */
+ interruptconfig |= ((uint8_t)(pIntConfig->Latch_Request | \
+ pIntConfig->Interrupt_Axes) << 8);
+
+ interruptconfig |= (uint8_t)(pIntConfig->Interrupt_ActiveEdge);
+
+ GyroscopeDrv->ConfigIT(interruptconfig);
+ }
+}
+
+/**
+ * @brief Enables INT1 or INT2 interrupt.
+ * @param IntPin: Interrupt pin
+ * This parameter can be:
+ * @arg L3GD20_INT1
+ * @arg L3GD20_INT2
+ * @arg I3G4250D_INT1
+ * @arg I3G4250D_INT2
+ */
+void BSP_GYRO_EnableIT(uint8_t IntPin)
+{
+ if (GyroscopeDrv->EnableIT != NULL)
+ {
+ GyroscopeDrv->EnableIT(IntPin);
+ }
+}
+
+/**
+ * @brief Disables INT1 or INT2 interrupt.
+ * @param IntPin: Interrupt pin
+ * This parameter can be:
+ * @arg L3GD20_INT1
+ * @arg L3GD20_INT2
+ * @arg I3G4250D_INT1
+ * @arg I3G4250D_INT2
+ */
+void BSP_GYRO_DisableIT(uint8_t IntPin)
+{
+ if (GyroscopeDrv->DisableIT != NULL)
+ {
+ GyroscopeDrv->DisableIT(IntPin);
+ }
+}
+
+/**
+ * @brief Get XYZ angular acceleration.
+ * @param pfData: pointer on floating array
+ */
+void BSP_GYRO_GetXYZ(float *pfData)
+{
+ if (GyroscopeDrv->GetXYZ != NULL)
+ {
+ GyroscopeDrv->GetXYZ(pfData);
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_gyroscope.h b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_gyroscope.h
new file mode 100644
index 0000000..05e4816
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_gyroscope.h
@@ -0,0 +1,106 @@
+/**
+ ******************************************************************************
+ * @file stm32f429i_discovery_gyroscope.h
+ * @author MCD Application Team
+ * @brief This file contains definitions for stm32f429i_discovery_gyroscope.c
+ * firmware driver.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F429I_DISCOVERY_GYROSCOPE_H
+#define __STM32F429I_DISCOVERY_GYROSCOPE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f429i_discovery.h"
+/* Include Gyroscope component driver */
+#include "../Components/l3gd20/l3gd20.h"
+#if defined(USE_STM32F429I_DISCOVERY_REVD)
+#include "../Components/i3g4250d/i3g4250d.h"
+#endif /* USE_STM32F429I_DISCOVERY_REVD */
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY_GYROSCOPE
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_GYROSCOPE_Exported_Types STM32F429I DISCOVERY GYROSCOPE Exported Types
+ * @{
+ */
+typedef enum
+{
+ GYRO_OK = 0,
+ GYRO_ERROR = 1,
+ GYRO_TIMEOUT = 2
+} GYRO_StatusTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_GYROSCOPE_Exported_Constants STM32F429I DISCOVERY GYROSCOPE Exported Constants
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_GYROSCOPE_Exported_Macros STM32F429I DISCOVERY GYROSCOPE Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_GYROSCOPE_Exported_Functions STM32F429I DISCOVERY GYROSCOPE Exported Functions
+ * @{
+ */
+/* Gyroscope Functions */
+uint8_t BSP_GYRO_Init(void);
+void BSP_GYRO_Reset(void);
+uint8_t BSP_GYRO_ReadID(void);
+void BSP_GYRO_ITConfig(GYRO_InterruptConfigTypeDef *pIntConfigStruct);
+void BSP_GYRO_EnableIT(uint8_t IntPin);
+void BSP_GYRO_DisableIT(uint8_t IntPin);
+void BSP_GYRO_GetXYZ(float *pfData);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F429I_DISCOVERY_GYROSCOPE_H */
diff --git a/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_io.c b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_io.c
new file mode 100644
index 0000000..9ed9a2e
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_io.c
@@ -0,0 +1,204 @@
+/**
+ ******************************************************************************
+ * @file stm32f429i_discovery_io.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the STMPE811
+ * IO Expander device mounted on STM32F429I-Discovery Kit.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f429i_discovery_io.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_IO STM32F429I DISCOVERY IO
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_IO_Private_Types_Definitions STM32F429I DISCOVERY IO Private Types Definitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_IO_Private_Defines STM32F429I DISCOVERY IO Private Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_IO_Private_Macros STM32F429I DISCOVERY IO Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup STM32F429I_DISCOVERY_IO_Private_Variables STM32F429I DISCOVERY IO Private Variables
+ * @{
+ */
+static IO_DrvTypeDef *IoDrv;
+
+/**
+ * @}
+ */
+
+
+/** @defgroup STM32F429I_DISCOVERY_IO_Private_Function_Prototypes STM32F429I DISCOVERY IO Private Function Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_IO_Private_Functions STM32F429I DISCOVERY IO Private Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes and configures the IO functionalities and configures all
+ * necessary hardware resources (GPIOs, clocks..).
+ * @note BSP_IO_Init() is using HAL_Delay() function to ensure that stmpe811
+ * 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 done correctly. Other value if error.
+ */
+uint8_t BSP_IO_Init(void)
+{
+ uint8_t ret = IO_ERROR;
+
+ /* Read ID and verify the IO expander is ready */
+ if (stmpe811_io_drv.ReadID(IO_I2C_ADDRESS) == STMPE811_ID)
+ {
+ /* Initialize the IO driver structure */
+ IoDrv = &stmpe811_io_drv;
+ ret = IO_OK;
+ }
+
+ if (ret == IO_OK)
+ {
+ IoDrv->Init(IO_I2C_ADDRESS);
+ IoDrv->Start(IO_I2C_ADDRESS, IO_PIN_ALL);
+ }
+ return ret;
+}
+
+/**
+ * @brief Gets the selected pins IT status.
+ * @param IoPin: The selected pins to check the status.
+ * This parameter could be any combination of the IO pins.
+ * @retval Status of IO Pin checked.
+ */
+uint8_t BSP_IO_ITGetStatus(uint16_t IoPin)
+{
+ /* Return the IO Pin IT status */
+ return (IoDrv->ITStatus(IO_I2C_ADDRESS, IoPin));
+}
+
+/**
+ * @brief Clears all the IO IT pending bits
+ */
+void BSP_IO_ITClear(void)
+{
+ /* Clear all IO IT pending bits */
+ IoDrv->ClearIT(IO_I2C_ADDRESS, IO_PIN_ALL);
+}
+
+/**
+ * @brief Configures the IO pin(s) according to IO mode structure value.
+ * @param IoPin: IO pin(s) 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 IoMode: 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
+ */
+void BSP_IO_ConfigPin(uint16_t IoPin, IO_ModeTypedef IoMode)
+{
+ /* Configure the selected IO pin(s) mode */
+ IoDrv->Config(IO_I2C_ADDRESS, IoPin, IoMode);
+}
+
+/**
+ * @brief Sets the selected pins state.
+ * @param IoPin: The selected pins to write.
+ * This parameter could be any combination of the IO pins.
+ * @param PinState: the new pins state to write
+ */
+void BSP_IO_WritePin(uint16_t IoPin, uint8_t PinState)
+{
+ /* Set the Pin state */
+ IoDrv->WritePin(IO_I2C_ADDRESS, IoPin, PinState);
+}
+
+/**
+ * @brief Gets the selected pins current state.
+ * @param IoPin: The selected pins to read.
+ * This parameter could be any combination of the IO pins.
+ * @retval The current pins state
+ */
+uint16_t BSP_IO_ReadPin(uint16_t IoPin)
+{
+ return (IoDrv->ReadPin(IO_I2C_ADDRESS, IoPin));
+}
+
+/**
+ * @brief Toggles the selected pins state.
+ * @param IoPin: The selected pins to toggle.
+ * This parameter could be any combination of the IO pins.
+ */
+void BSP_IO_TogglePin(uint16_t IoPin)
+{
+ /* Toggle the current pin state */
+ if (IoDrv->ReadPin(IO_I2C_ADDRESS, IoPin) == 1 /* Set */)
+ {
+ IoDrv->WritePin(IO_I2C_ADDRESS, IoPin, 0 /* Reset */);
+ }
+ else
+ {
+ IoDrv->WritePin(IO_I2C_ADDRESS, IoPin, 1 /* Set */);
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_io.h b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_io.h
new file mode 100644
index 0000000..d43cf8a
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_io.h
@@ -0,0 +1,112 @@
+/**
+ ******************************************************************************
+ * @file stm32f429i_discovery_io.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for the
+ * stm32f429i_discovery_io.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F429I_DISCOVERY_IO_H
+#define __STM32F429I_DISCOVERY_IO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f429i_discovery.h"
+/* Include IO component driver */
+#include "../Components/stmpe811/stmpe811.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY_IO
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_IO_Exported_Types STM32F429I DISCOVERY IO Exported Types
+ * @{
+ */
+typedef enum
+{
+ IO_OK = 0,
+ IO_ERROR = 1,
+ IO_TIMEOUT = 2
+} IO_StatusTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_IO_Exported_Constants STM32F429I DISCOVERY IO Exported Constants
+ * @{
+ */
+#define IO_PIN_0 0x01
+#define IO_PIN_1 0x02
+#define IO_PIN_2 0x04
+#define IO_PIN_3 0x08
+#define IO_PIN_4 0x10
+#define IO_PIN_5 0x20
+#define IO_PIN_6 0x40
+#define IO_PIN_7 0x80
+#define IO_PIN_ALL 0xFF
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_IO_Exported_Macros STM32F429I DISCOVERY IO Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_IO_Exported_Functions STM32F429I DISCOVERY IO Exported Functions
+ * @{
+ */
+uint8_t BSP_IO_Init(void);
+uint8_t BSP_IO_ITGetStatus(uint16_t IoPin);
+void BSP_IO_ITClear(void);
+void BSP_IO_ConfigPin(uint16_t IoPin, IO_ModeTypedef IoMode);
+void BSP_IO_WritePin(uint16_t IoPin, uint8_t PinState);
+uint16_t BSP_IO_ReadPin(uint16_t IoPin);
+void BSP_IO_TogglePin(uint16_t IoPin);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F429I_DISCOVERY_IO_H */
diff --git a/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_lcd.c b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_lcd.c
new file mode 100644
index 0000000..efc2210
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_lcd.c
@@ -0,0 +1,1440 @@
+/**
+ ******************************************************************************
+ * @file stm32f429i_discovery_lcd.c
+ * @author MCD Application Team
+ * @brief This file includes the LCD driver for ILI9341 Liquid Crystal
+ * Display Modules of STM32F429I-Discovery kit (MB1075).
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* File Info : -----------------------------------------------------------------
+ User NOTES
+1. How To use this driver:
+--------------------------
+ - This driver is used to drive directly an LCD TFT using LTDC controller.
+ - This driver select dynamically the mounted LCD, ILI9341 240x320 LCD mounted
+ on MB1075B discovery board, and use the adequate timing and setting for
+ the specified LCD using device ID of the ILI9341 mounted on MB1075B discovery board
+
+2. Driver description:
+---------------------
+ + Initialization steps :
+ o Initialize the LCD using the LCD_Init() function.
+ o Apply the Layer configuration using LCD_LayerDefaultInit() function
+ o Select the LCD layer to be used using LCD_SelectLayer() function.
+ o Enable the LCD display using LCD_DisplayOn() function.
+
+ + Options
+ o Configure and enable the color keying functionality using LCD_SetColorKeying()
+ function.
+ o Modify in the fly the transparency and/or the frame buffer address
+ using the following functions :
+ - LCD_SetTransparency()
+ - LCD_SetLayerAddress()
+
+ + Display on LCD
+ o Clear the hole LCD using LCD_Clear() function or only one specified string
+ line using LCD_ClearStringLine() function.
+ o Display a character on the specified line and column using LCD_DisplayChar()
+ function or a complete string line using LCD_DisplayStringAtLine() function.
+ o Display a string line on the specified position (x,y in pixel) and align mode
+ using LCD_DisplayStringAtLine() function.
+ o Draw and fill a basic shapes (dot, line, rectangle, circle, ellipse, .. bitmap)
+ on LCD using the available set of functions
+
+------------------------------------------------------------------------------*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f429i_discovery_lcd.h"
+#include "../../../Utilities/Fonts/fonts.h"
+#include "../../../Utilities/Fonts/font24.c"
+#include "../../../Utilities/Fonts/font20.c"
+#include "../../../Utilities/Fonts/font16.c"
+#include "../../../Utilities/Fonts/font12.c"
+#include "../../../Utilities/Fonts/font8.c"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LCD STM32F429I DISCOVERY LCD
+ * @brief This file includes the LCD driver for (ILI9341)
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LCD_Private_TypesDefinitions STM32F429I DISCOVERY LCD Private TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LCD_Private_Defines STM32F429I DISCOVERY LCD Private Defines
+ * @{
+ */
+#define POLY_X(Z) ((int32_t)((Points + Z)->X))
+#define POLY_Y(Z) ((int32_t)((Points + Z)->Y))
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LCD_Private_Macros STM32F429I DISCOVERY LCD Private Macros
+ * @{
+ */
+#define ABS(X) ((X) > 0 ? (X) : -(X))
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LCD_Private_Variables STM32F429I DISCOVERY LCD Private Variables
+ * @{
+ */
+LTDC_HandleTypeDef LtdcHandler;
+static DMA2D_HandleTypeDef Dma2dHandler;
+static RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
+
+/* Default LCD configuration with LCD Layer 1 */
+static uint32_t ActiveLayer = 0;
+static LCD_DrawPropTypeDef DrawProp[MAX_LAYER_NUMBER];
+LCD_DrvTypeDef *LcdDrv;
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LCD_Private_FunctionPrototypes STM32F429I DISCOVERY LCD Private FunctionPrototypes
+ * @{
+ */
+static void DrawChar(uint16_t Xpos, uint16_t Ypos, const uint8_t *c);
+static void FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine,
+ uint32_t ColorIndex);
+static void ConvertLineToARGB8888(void *pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode);
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LCD_Private_Functions STM32F429I DISCOVERY LCD Private Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes the LCD.
+ * @retval LCD state
+ */
+uint8_t BSP_LCD_Init(void)
+{
+ /* On STM32F429I-DISCO, it is not possible to read ILI9341 ID because */
+ /* PIN EXTC is not connected to VDD and then LCD_READ_ID4 is not accessible. */
+ /* In this case, ReadID function is bypassed.*/
+ /*if(ili9341_drv.ReadID() == ILI9341_ID)*/
+
+ /* LTDC Configuration ----------------------------------------------------*/
+ LtdcHandler.Instance = LTDC;
+
+ /* Timing configuration (Typical configuration from ILI9341 datasheet)
+ HSYNC=10 (9+1)
+ HBP=20 (29-10+1)
+ ActiveW=240 (269-20-10+1)
+ HFP=10 (279-240-20-10+1)
+
+ VSYNC=2 (1+1)
+ VBP=2 (3-2+1)
+ ActiveH=320 (323-2-2+1)
+ VFP=4 (327-320-2-2+1)
+ */
+
+ /* Configure horizontal synchronization width */
+ LtdcHandler.Init.HorizontalSync = ILI9341_HSYNC;
+ /* Configure vertical synchronization height */
+ LtdcHandler.Init.VerticalSync = ILI9341_VSYNC;
+ /* Configure accumulated horizontal back porch */
+ LtdcHandler.Init.AccumulatedHBP = ILI9341_HBP;
+ /* Configure accumulated vertical back porch */
+ LtdcHandler.Init.AccumulatedVBP = ILI9341_VBP;
+ /* Configure accumulated active width */
+ LtdcHandler.Init.AccumulatedActiveW = 269;
+ /* Configure accumulated active height */
+ LtdcHandler.Init.AccumulatedActiveH = 323;
+ /* Configure total width */
+ LtdcHandler.Init.TotalWidth = 279;
+ /* Configure total height */
+ LtdcHandler.Init.TotalHeigh = 327;
+
+ /* Configure R,G,B component values for LCD background color */
+ LtdcHandler.Init.Backcolor.Red = 0;
+ LtdcHandler.Init.Backcolor.Blue = 0;
+ LtdcHandler.Init.Backcolor.Green = 0;
+
+ /* LCD clock configuration */
+ /* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */
+ /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 192 Mhz */
+ /* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 192/4 = 48 Mhz */
+ /* LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_8 = 48/4 = 6Mhz */
+ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
+ PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
+ PeriphClkInitStruct.PLLSAI.PLLSAIR = 4;
+ PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_8;
+ HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
+
+ /* Polarity */
+ LtdcHandler.Init.HSPolarity = LTDC_HSPOLARITY_AL;
+ LtdcHandler.Init.VSPolarity = LTDC_VSPOLARITY_AL;
+ LtdcHandler.Init.DEPolarity = LTDC_DEPOLARITY_AL;
+ LtdcHandler.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
+
+ BSP_LCD_MspInit();
+ HAL_LTDC_Init(&LtdcHandler);
+
+ /* Select the device */
+ LcdDrv = &ili9341_drv;
+
+ /* LCD Init */
+ LcdDrv->Init();
+
+ /* Initialize the SDRAM */
+ BSP_SDRAM_Init();
+
+ /* Initialize the font */
+ BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
+
+ return LCD_OK;
+}
+
+/**
+ * @brief Gets the LCD X size.
+ * @retval The used LCD X size
+ */
+uint32_t BSP_LCD_GetXSize(void)
+{
+ return LcdDrv->GetLcdPixelWidth();
+}
+
+/**
+ * @brief Gets the LCD Y size.
+ * @retval The used LCD Y size
+ */
+uint32_t BSP_LCD_GetYSize(void)
+{
+ return LcdDrv->GetLcdPixelHeight();
+}
+
+/**
+ * @brief Initializes the LCD layers.
+ * @param LayerIndex: the layer foreground or background.
+ * @param FB_Address: the layer frame buffer.
+ */
+void BSP_LCD_LayerDefaultInit(uint16_t LayerIndex, uint32_t FB_Address)
+{
+ LCD_LayerCfgTypeDef Layercfg;
+
+ /* Layer Init */
+ Layercfg.WindowX0 = 0;
+ Layercfg.WindowX1 = BSP_LCD_GetXSize();
+ Layercfg.WindowY0 = 0;
+ Layercfg.WindowY1 = BSP_LCD_GetYSize();
+ Layercfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB8888;
+ Layercfg.FBStartAdress = FB_Address;
+ Layercfg.Alpha = 255;
+ Layercfg.Alpha0 = 0;
+ Layercfg.Backcolor.Blue = 0;
+ Layercfg.Backcolor.Green = 0;
+ Layercfg.Backcolor.Red = 0;
+ Layercfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
+ Layercfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
+ Layercfg.ImageWidth = BSP_LCD_GetXSize();
+ Layercfg.ImageHeight = BSP_LCD_GetYSize();
+
+ HAL_LTDC_ConfigLayer(&LtdcHandler, &Layercfg, LayerIndex);
+
+ DrawProp[LayerIndex].BackColor = LCD_COLOR_WHITE;
+ DrawProp[LayerIndex].pFont = &Font24;
+ DrawProp[LayerIndex].TextColor = LCD_COLOR_BLACK;
+
+ /* Dithering activation */
+ HAL_LTDC_EnableDither(&LtdcHandler);
+}
+
+/**
+ * @brief Selects the LCD Layer.
+ * @param LayerIndex: the Layer foreground or background.
+ */
+void BSP_LCD_SelectLayer(uint32_t LayerIndex)
+{
+ ActiveLayer = LayerIndex;
+}
+
+/**
+ * @brief Sets a LCD Layer visible.
+ * @param LayerIndex: the visible Layer.
+ * @param state: new state of the specified layer.
+ * This parameter can be: ENABLE or DISABLE.
+ */
+void BSP_LCD_SetLayerVisible(uint32_t LayerIndex, FunctionalState state)
+{
+ if (state == ENABLE)
+ {
+ __HAL_LTDC_LAYER_ENABLE(&LtdcHandler, LayerIndex);
+ }
+ else
+ {
+ __HAL_LTDC_LAYER_DISABLE(&LtdcHandler, LayerIndex);
+ }
+ __HAL_LTDC_RELOAD_CONFIG(&LtdcHandler);
+}
+
+/**
+ * @brief Sets an LCD Layer visible without reloading.
+ * @param LayerIndex: Visible Layer
+ * @param State: New state of the specified layer
+ * This parameter can be one of the following values:
+ * @arg ENABLE
+ * @arg DISABLE
+ * @retval None
+ */
+void BSP_LCD_SetLayerVisible_NoReload(uint32_t LayerIndex, FunctionalState State)
+{
+ if (State == ENABLE)
+ {
+ __HAL_LTDC_LAYER_ENABLE(&LtdcHandler, LayerIndex);
+ }
+ else
+ {
+ __HAL_LTDC_LAYER_DISABLE(&LtdcHandler, LayerIndex);
+ }
+ /* Do not Sets the Reload */
+}
+
+/**
+ * @brief Configures the Transparency.
+ * @param LayerIndex: the Layer foreground or background.
+ * @param Transparency: the Transparency,
+ * This parameter must range from 0x00 to 0xFF.
+ */
+void BSP_LCD_SetTransparency(uint32_t LayerIndex, uint8_t Transparency)
+{
+ HAL_LTDC_SetAlpha(&LtdcHandler, Transparency, LayerIndex);
+}
+
+/**
+ * @brief Configures the transparency without reloading.
+ * @param LayerIndex: Layer foreground or background.
+ * @param Transparency: Transparency
+ * This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF
+ * @retval None
+ */
+void BSP_LCD_SetTransparency_NoReload(uint32_t LayerIndex, uint8_t Transparency)
+{
+ HAL_LTDC_SetAlpha_NoReload(&LtdcHandler, Transparency, LayerIndex);
+}
+
+/**
+ * @brief Sets a LCD layer frame buffer address.
+ * @param LayerIndex: specifies the Layer foreground or background
+ * @param Address: new LCD frame buffer value
+ */
+void BSP_LCD_SetLayerAddress(uint32_t LayerIndex, uint32_t Address)
+{
+ HAL_LTDC_SetAddress(&LtdcHandler, Address, LayerIndex);
+}
+
+/**
+ * @brief Sets an LCD layer frame buffer address without reloading.
+ * @param LayerIndex: Layer foreground or background
+ * @param Address: New LCD frame buffer value
+ * @retval None
+ */
+void BSP_LCD_SetLayerAddress_NoReload(uint32_t LayerIndex, uint32_t Address)
+{
+ HAL_LTDC_SetAddress_NoReload(&LtdcHandler, Address, LayerIndex);
+}
+
+/**
+ * @brief Sets the Display window.
+ * @param LayerIndex: layer index
+ * @param Xpos: LCD X position
+ * @param Ypos: LCD Y position
+ * @param Width: LCD window width
+ * @param Height: LCD window height
+ */
+void BSP_LCD_SetLayerWindow(uint16_t LayerIndex, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
+{
+ /* reconfigure the layer size */
+ HAL_LTDC_SetWindowSize(&LtdcHandler, Width, Height, LayerIndex);
+
+ /* reconfigure the layer position */
+ HAL_LTDC_SetWindowPosition(&LtdcHandler, Xpos, Ypos, LayerIndex);
+}
+
+/**
+ * @brief Sets display window without reloading.
+ * @param LayerIndex: Layer index
+ * @param Xpos: LCD X position
+ * @param Ypos: LCD Y position
+ * @param Width: LCD window width
+ * @param Height: LCD window height
+ * @retval None
+ */
+void BSP_LCD_SetLayerWindow_NoReload(uint16_t LayerIndex, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
+{
+ /* Reconfigure the layer size */
+ HAL_LTDC_SetWindowSize_NoReload(&LtdcHandler, Width, Height, LayerIndex);
+
+ /* Reconfigure the layer position */
+ HAL_LTDC_SetWindowPosition_NoReload(&LtdcHandler, Xpos, Ypos, LayerIndex);
+}
+
+/**
+ * @brief Configures and sets the color Keying.
+ * @param LayerIndex: the Layer foreground or background
+ * @param RGBValue: the Color reference
+ */
+void BSP_LCD_SetColorKeying(uint32_t LayerIndex, uint32_t RGBValue)
+{
+ /* Configure and Enable the color Keying for LCD Layer */
+ HAL_LTDC_ConfigColorKeying(&LtdcHandler, RGBValue, LayerIndex);
+ HAL_LTDC_EnableColorKeying(&LtdcHandler, LayerIndex);
+}
+
+/**
+ * @brief Configures and sets the color keying without reloading.
+ * @param LayerIndex: Layer foreground or background
+ * @param RGBValue: Color reference
+ * @retval None
+ */
+void BSP_LCD_SetColorKeying_NoReload(uint32_t LayerIndex, uint32_t RGBValue)
+{
+ /* Configure and Enable the color Keying for LCD Layer */
+ HAL_LTDC_ConfigColorKeying_NoReload(&LtdcHandler, RGBValue, LayerIndex);
+ HAL_LTDC_EnableColorKeying_NoReload(&LtdcHandler, LayerIndex);
+}
+
+/**
+ * @brief Disables the color Keying.
+ * @param LayerIndex: the Layer foreground or background
+ */
+void BSP_LCD_ResetColorKeying(uint32_t LayerIndex)
+{
+ /* Disable the color Keying for LCD Layer */
+ HAL_LTDC_DisableColorKeying(&LtdcHandler, LayerIndex);
+}
+
+/**
+ * @brief Disables the color keying without reloading.
+ * @param LayerIndex: Layer foreground or background
+ * @retval None
+ */
+void BSP_LCD_ResetColorKeying_NoReload(uint32_t LayerIndex)
+{
+ /* Disable the color Keying for LCD Layer */
+ HAL_LTDC_DisableColorKeying_NoReload(&LtdcHandler, LayerIndex);
+}
+
+/**
+ * @brief Disables the color keying without reloading.
+ * @param ReloadType: can be one of the following values
+ * - LCD_RELOAD_IMMEDIATE
+ * - LCD_RELOAD_VERTICAL_BLANKING
+ * @retval None
+ */
+void BSP_LCD_Relaod(uint32_t ReloadType)
+{
+ HAL_LTDC_Relaod(&LtdcHandler, ReloadType);
+}
+
+/**
+ * @brief Gets the LCD Text color.
+ * @retval Text color
+ */
+uint32_t BSP_LCD_GetTextColor(void)
+{
+ return DrawProp[ActiveLayer].TextColor;
+}
+
+/**
+ * @brief Gets the LCD Background color.
+ * @retval Background color
+ */
+uint32_t BSP_LCD_GetBackColor(void)
+{
+ return DrawProp[ActiveLayer].BackColor;
+}
+
+/**
+ * @brief Sets the Text color.
+ * @param Color: the Text color code ARGB(8-8-8-8)
+ */
+void BSP_LCD_SetTextColor(uint32_t Color)
+{
+ DrawProp[ActiveLayer].TextColor = Color;
+}
+
+/**
+ * @brief Sets the Background color.
+ * @param Color: the layer Background color code ARGB(8-8-8-8)
+ */
+void BSP_LCD_SetBackColor(uint32_t Color)
+{
+ DrawProp[ActiveLayer].BackColor = Color;
+}
+
+/**
+ * @brief Sets the Text Font.
+ * @param pFonts: the layer font to be used
+ */
+void BSP_LCD_SetFont(sFONT *pFonts)
+{
+ DrawProp[ActiveLayer].pFont = pFonts;
+}
+
+/**
+ * @brief Gets the Text Font.
+ * @retval Layer font
+ */
+sFONT *BSP_LCD_GetFont(void)
+{
+ return DrawProp[ActiveLayer].pFont;
+}
+
+/**
+ * @brief Reads Pixel.
+ * @param Xpos: the X position
+ * @param Ypos: the Y position
+ * @retval RGB pixel color
+ */
+uint32_t BSP_LCD_ReadPixel(uint16_t Xpos, uint16_t Ypos)
+{
+ uint32_t ret = 0;
+
+ if (LtdcHandler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888)
+ {
+ /* Read data value from SDRAM memory */
+ ret = *(__IO uint32_t *)(LtdcHandler.LayerCfg[ActiveLayer].FBStartAdress + (4 * (Ypos * BSP_LCD_GetXSize() + Xpos)));
+ }
+ else if (LtdcHandler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB888)
+ {
+ /* Read data value from SDRAM memory */
+ ret = (*(__IO uint32_t *)(LtdcHandler.LayerCfg[ActiveLayer].FBStartAdress + (4 * (Ypos * BSP_LCD_GetXSize() + Xpos))) & 0x00FFFFFF);
+ }
+ else if ((LtdcHandler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \
+ (LtdcHandler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \
+ (LtdcHandler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_AL88))
+ {
+ /* Read data value from SDRAM memory */
+ ret = *(__IO uint16_t *)(LtdcHandler.LayerCfg[ActiveLayer].FBStartAdress + (2 * (Ypos * BSP_LCD_GetXSize() + Xpos)));
+ }
+ else
+ {
+ /* Read data value from SDRAM memory */
+ ret = *(__IO uint8_t *)(LtdcHandler.LayerCfg[ActiveLayer].FBStartAdress + (2 * (Ypos * BSP_LCD_GetXSize() + Xpos)));
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Clears the hole LCD.
+ * @param Color: the color of the background
+ */
+void BSP_LCD_Clear(uint32_t Color)
+{
+ /* Clear the LCD */
+ FillBuffer(ActiveLayer, (uint32_t *)(LtdcHandler.LayerCfg[ActiveLayer].FBStartAdress), BSP_LCD_GetXSize(),
+ BSP_LCD_GetYSize(), 0, Color);
+}
+
+/**
+ * @brief Clears the selected line.
+ * @param Line: the line to be cleared
+ */
+void BSP_LCD_ClearStringLine(uint32_t Line)
+{
+ uint32_t colorbackup = DrawProp[ActiveLayer].TextColor;
+ DrawProp[ActiveLayer].TextColor = DrawProp[ActiveLayer].BackColor;
+
+ /* Draw rectangle with background color */
+ BSP_LCD_FillRect(0, (Line * DrawProp[ActiveLayer].pFont->Height), BSP_LCD_GetXSize(),
+ DrawProp[ActiveLayer].pFont->Height);
+
+ DrawProp[ActiveLayer].TextColor = colorbackup;
+ BSP_LCD_SetTextColor(DrawProp[ActiveLayer].TextColor);
+}
+
+/**
+ * @brief Displays one character.
+ * @param Xpos: start column address
+ * @param Ypos: the Line where to display the character shape
+ * @param Ascii: character ascii code, must be between 0x20 and 0x7E
+ */
+void BSP_LCD_DisplayChar(uint16_t Xpos, uint16_t Ypos, uint8_t Ascii)
+{
+ DrawChar(Xpos, Ypos, &DrawProp[ActiveLayer].pFont->table[(Ascii - ' ') *\
+ DrawProp[ActiveLayer].pFont->Height * ((DrawProp[ActiveLayer].pFont->Width + 7) / 8)]);
+}
+
+/**
+ * @brief Displays a maximum of 60 char on the LCD.
+ * @param X: pointer to x position (in pixel)
+ * @param Y: pointer to y position (in pixel)
+ * @param pText: pointer to string to display on LCD
+ * @param mode: The display mode
+ * This parameter can be one of the following values:
+ * @arg CENTER_MODE
+ * @arg RIGHT_MODE
+ * @arg LEFT_MODE
+ */
+void BSP_LCD_DisplayStringAt(uint16_t X, uint16_t Y, uint8_t *pText, Text_AlignModeTypdef mode)
+{
+ uint16_t refcolumn = 1, i = 0;
+ uint32_t size = 0, xsize = 0;
+ uint8_t *ptr = pText;
+
+ /* Get the text size */
+ while (*ptr++) { size ++ ; }
+
+ /* Characters number per line */
+ xsize = (BSP_LCD_GetXSize() / DrawProp[ActiveLayer].pFont->Width);
+
+ switch (mode)
+ {
+ case CENTER_MODE:
+ {
+ refcolumn = X + ((xsize - size) * DrawProp[ActiveLayer].pFont->Width) / 2;
+ break;
+ }
+ case LEFT_MODE:
+ {
+ refcolumn = X;
+ break;
+ }
+ case RIGHT_MODE:
+ {
+ refcolumn = X + ((xsize - size) * DrawProp[ActiveLayer].pFont->Width);
+ break;
+ }
+ default:
+ {
+ refcolumn = X;
+ break;
+ }
+ }
+
+ /* Send the string character by character on LCD */
+ while ((*pText != 0) & (((BSP_LCD_GetXSize() - (i * DrawProp[ActiveLayer].pFont->Width)) & 0xFFFF) >=
+ DrawProp[ActiveLayer].pFont->Width))
+ {
+ /* Display one character on LCD */
+ BSP_LCD_DisplayChar(refcolumn, Y, *pText);
+ /* Decrement the column position by 16 */
+ refcolumn += DrawProp[ActiveLayer].pFont->Width;
+ /* Point on the next character */
+ pText++;
+ i++;
+ }
+}
+
+/**
+ * @brief Displays a maximum of 20 char on the LCD.
+ * @param Line: the Line where to display the character shape
+ * @param ptr: pointer to string to display on LCD
+ */
+void BSP_LCD_DisplayStringAtLine(uint16_t Line, uint8_t *ptr)
+{
+ BSP_LCD_DisplayStringAt(0, LINE(Line), ptr, LEFT_MODE);
+}
+
+/**
+ * @brief Displays an horizontal line.
+ * @param Xpos: the X position
+ * @param Ypos: the Y position
+ * @param Length: line length
+ */
+void BSP_LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length)
+{
+ uint32_t xaddress = 0;
+
+ /* Get the line address */
+ xaddress = (LtdcHandler.LayerCfg[ActiveLayer].FBStartAdress) + 4 * (BSP_LCD_GetXSize() * Ypos + Xpos);
+
+ /* Write line */
+ FillBuffer(ActiveLayer, (uint32_t *)xaddress, Length, 1, 0, DrawProp[ActiveLayer].TextColor);
+}
+
+/**
+ * @brief Displays a vertical line.
+ * @param Xpos: the X position
+ * @param Ypos: the Y position
+ * @param Length: line length
+ */
+void BSP_LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length)
+{
+ uint32_t xaddress = 0;
+
+ /* Get the line address */
+ xaddress = (LtdcHandler.LayerCfg[ActiveLayer].FBStartAdress) + 4 * (BSP_LCD_GetXSize() * Ypos + Xpos);
+
+ /* Write line */
+ FillBuffer(ActiveLayer, (uint32_t *)xaddress, 1, Length, (BSP_LCD_GetXSize() - 1), DrawProp[ActiveLayer].TextColor);
+}
+
+/**
+ * @brief Displays an uni-line (between two points).
+ * @param X1: the point 1 X position
+ * @param Y1: the point 1 Y position
+ * @param X2: the point 2 X position
+ * @param Y2: the point 2 Y position
+ */
+void BSP_LCD_DrawLine(uint16_t X1, uint16_t Y1, uint16_t X2, uint16_t Y2)
+{
+ int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
+ yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0,
+ curpixel = 0;
+
+ deltax = ABS(X2 - X1); /* The difference between the x's */
+ deltay = ABS(Y2 - Y1); /* The difference between the y's */
+ x = X1; /* Start x off at the first pixel */
+ y = Y1; /* Start y off at the first pixel */
+
+ if (X2 >= X1) /* The x-values are increasing */
+ {
+ xinc1 = 1;
+ xinc2 = 1;
+ }
+ else /* The x-values are decreasing */
+ {
+ xinc1 = -1;
+ xinc2 = -1;
+ }
+
+ if (Y2 >= Y1) /* The y-values are increasing */
+ {
+ yinc1 = 1;
+ yinc2 = 1;
+ }
+ else /* The y-values are decreasing */
+ {
+ yinc1 = -1;
+ yinc2 = -1;
+ }
+
+ if (deltax >= deltay) /* There is at least one x-value for every y-value */
+ {
+ xinc1 = 0; /* Don't change the x when numerator >= denominator */
+ yinc2 = 0; /* Don't change the y for every iteration */
+ den = deltax;
+ num = deltax / 2;
+ numadd = deltay;
+ numpixels = deltax; /* There are more x-values than y-values */
+ }
+ else /* There is at least one y-value for every x-value */
+ {
+ xinc2 = 0; /* Don't change the x for every iteration */
+ yinc1 = 0; /* Don't change the y when numerator >= denominator */
+ den = deltay;
+ num = deltay / 2;
+ numadd = deltax;
+ numpixels = deltay; /* There are more y-values than x-values */
+ }
+
+ for (curpixel = 0; curpixel <= numpixels; curpixel++)
+ {
+ BSP_LCD_DrawPixel(x, y, DrawProp[ActiveLayer].TextColor); /* Draw the current pixel */
+ num += numadd; /* Increase the numerator by the top of the fraction */
+ if (num >= den) /* Check if numerator >= denominator */
+ {
+ num -= den; /* Calculate the new numerator value */
+ x += xinc1; /* Change the x as appropriate */
+ y += yinc1; /* Change the y as appropriate */
+ }
+ x += xinc2; /* Change the x as appropriate */
+ y += yinc2; /* Change the y as appropriate */
+ }
+}
+
+/**
+ * @brief Displays a rectangle.
+ * @param Xpos: the X position
+ * @param Ypos: the Y position
+ * @param Height: display rectangle height
+ * @param Width: display rectangle width
+ */
+void BSP_LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
+{
+ /* Draw horizontal lines */
+ BSP_LCD_DrawHLine(Xpos, Ypos, Width);
+ BSP_LCD_DrawHLine(Xpos, (Ypos + Height), Width);
+
+ /* Draw vertical lines */
+ BSP_LCD_DrawVLine(Xpos, Ypos, Height);
+ BSP_LCD_DrawVLine((Xpos + Width), Ypos, Height);
+}
+
+/**
+ * @brief Displays a circle.
+ * @param Xpos: the X position
+ * @param Ypos: the Y position
+ * @param Radius: the circle radius
+ */
+void BSP_LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
+{
+ int32_t d;/* Decision Variable */
+ uint32_t curx;/* Current X Value */
+ uint32_t cury;/* Current Y Value */
+
+ d = 3 - (Radius << 1);
+ curx = 0;
+ cury = Radius;
+
+ while (curx <= cury)
+ {
+ BSP_LCD_DrawPixel((Xpos + curx), (Ypos - cury), DrawProp[ActiveLayer].TextColor);
+ BSP_LCD_DrawPixel((Xpos - curx), (Ypos - cury), DrawProp[ActiveLayer].TextColor);
+ BSP_LCD_DrawPixel((Xpos + cury), (Ypos - curx), DrawProp[ActiveLayer].TextColor);
+ BSP_LCD_DrawPixel((Xpos - cury), (Ypos - curx), DrawProp[ActiveLayer].TextColor);
+ BSP_LCD_DrawPixel((Xpos + curx), (Ypos + cury), DrawProp[ActiveLayer].TextColor);
+ BSP_LCD_DrawPixel((Xpos - curx), (Ypos + cury), DrawProp[ActiveLayer].TextColor);
+ BSP_LCD_DrawPixel((Xpos + cury), (Ypos + curx), DrawProp[ActiveLayer].TextColor);
+ BSP_LCD_DrawPixel((Xpos - cury), (Ypos + curx), DrawProp[ActiveLayer].TextColor);
+
+ if (d < 0)
+ {
+ d += (curx << 2) + 6;
+ }
+ else
+ {
+ d += ((curx - cury) << 2) + 10;
+ cury--;
+ }
+ curx++;
+ }
+}
+
+/**
+ * @brief Displays an poly-line (between many points).
+ * @param Points: pointer to the points array
+ * @param PointCount: Number of points
+ */
+void BSP_LCD_DrawPolygon(pPoint Points, uint16_t PointCount)
+{
+ int16_t x = 0, y = 0;
+
+ if (PointCount < 2)
+ {
+ return;
+ }
+
+ BSP_LCD_DrawLine(Points->X, Points->Y, (Points + PointCount - 1)->X, (Points + PointCount - 1)->Y);
+
+ while (--PointCount)
+ {
+ x = Points->X;
+ y = Points->Y;
+ Points++;
+ BSP_LCD_DrawLine(x, y, Points->X, Points->Y);
+ }
+}
+
+/**
+ * @brief Displays an Ellipse.
+ * @param Xpos: the X position
+ * @param Ypos: the Y position
+ * @param XRadius: the X radius of ellipse
+ * @param YRadius: the Y radius of ellipse
+ */
+void BSP_LCD_DrawEllipse(int Xpos, int Ypos, int XRadius, int YRadius)
+{
+ int x = 0, y = -YRadius, err = 2 - 2 * XRadius, e2;
+ float k = 0, rad1 = 0, rad2 = 0;
+
+ rad1 = XRadius;
+ rad2 = YRadius;
+
+ k = (float)(rad2 / rad1);
+
+ do
+ {
+ BSP_LCD_DrawPixel((Xpos - (uint16_t)(x / k)), (Ypos + y), DrawProp[ActiveLayer].TextColor);
+ BSP_LCD_DrawPixel((Xpos + (uint16_t)(x / k)), (Ypos + y), DrawProp[ActiveLayer].TextColor);
+ BSP_LCD_DrawPixel((Xpos + (uint16_t)(x / k)), (Ypos - y), DrawProp[ActiveLayer].TextColor);
+ BSP_LCD_DrawPixel((Xpos - (uint16_t)(x / k)), (Ypos - y), DrawProp[ActiveLayer].TextColor);
+
+ e2 = err;
+ if (e2 <= x)
+ {
+ err += ++x * 2 + 1;
+ if (-y == x && e2 <= y) { e2 = 0; }
+ }
+ if (e2 > y) { err += ++y * 2 + 1; }
+ } while (y <= 0);
+}
+
+/**
+ * @brief Displays a bitmap picture loaded in the internal Flash (32 bpp).
+ * @param X: the bmp x position in the LCD
+ * @param Y: the bmp Y position in the LCD
+ * @param pBmp: Bmp picture address in the internal Flash
+ */
+void BSP_LCD_DrawBitmap(uint32_t X, uint32_t Y, uint8_t *pBmp)
+{
+ uint32_t index = 0, width = 0, height = 0, bitpixel = 0;
+ uint32_t address;
+ uint32_t inputcolormode = 0;
+
+ /* Get bitmap data address offset */
+ index = pBmp[10] + (pBmp[11] << 8) + (pBmp[12] << 16) + (pBmp[13] << 24);
+
+ /* Read bitmap width */
+ width = pBmp[18] + (pBmp[19] << 8) + (pBmp[20] << 16) + (pBmp[21] << 24);
+
+ /* Read bitmap height */
+ height = pBmp[22] + (pBmp[23] << 8) + (pBmp[24] << 16) + (pBmp[25] << 24);
+
+ /* Read bit/pixel */
+ bitpixel = pBmp[28] + (pBmp[29] << 8);
+
+ /* Set Address */
+ address = LtdcHandler.LayerCfg[ActiveLayer].FBStartAdress + (((BSP_LCD_GetXSize() * Y) + X) * (4));
+
+ /* Get the Layer pixel format */
+ if ((bitpixel / 8) == 4)
+ {
+ inputcolormode = CM_ARGB8888;
+ }
+ else if ((bitpixel / 8) == 2)
+ {
+ inputcolormode = CM_RGB565;
+ }
+ else
+ {
+ inputcolormode = CM_RGB888;
+ }
+
+ /* bypass the bitmap header */
+ pBmp += (index + (width * (height - 1) * (bitpixel / 8)));
+
+ /* Convert picture to ARGB8888 pixel format */
+ for (index = 0; index < height; index++)
+ {
+ /* Pixel format conversion */
+ ConvertLineToARGB8888((uint32_t *)pBmp, (uint32_t *)address, width, inputcolormode);
+
+ /* Increment the source and destination buffers */
+ address += ((BSP_LCD_GetXSize() - width + width) * 4);
+ pBmp -= width * (bitpixel / 8);
+ }
+}
+
+/**
+ * @brief Displays a full rectangle.
+ * @param Xpos: the X position
+ * @param Ypos: the Y position
+ * @param Height: rectangle height
+ * @param Width: rectangle width
+ */
+void BSP_LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
+{
+ uint32_t xaddress = 0;
+
+ /* Set the text color */
+ BSP_LCD_SetTextColor(DrawProp[ActiveLayer].TextColor);
+
+ /* Get the rectangle start address */
+ xaddress = (LtdcHandler.LayerCfg[ActiveLayer].FBStartAdress) + 4 * (BSP_LCD_GetXSize() * Ypos + Xpos);
+
+ /* Fill the rectangle */
+ FillBuffer(ActiveLayer, (uint32_t *)xaddress, Width, Height, (BSP_LCD_GetXSize() - Width),
+ DrawProp[ActiveLayer].TextColor);
+}
+
+/**
+ * @brief Displays a full circle.
+ * @param Xpos: the X position
+ * @param Ypos: the Y position
+ * @param Radius: the circle radius
+ */
+void BSP_LCD_FillCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
+{
+ int32_t d; /* Decision Variable */
+ uint32_t curx;/* Current X Value */
+ uint32_t cury;/* Current Y Value */
+
+ d = 3 - (Radius << 1);
+
+ curx = 0;
+ cury = Radius;
+
+ BSP_LCD_SetTextColor(DrawProp[ActiveLayer].TextColor);
+
+ while (curx <= cury)
+ {
+ if (cury > 0)
+ {
+ BSP_LCD_DrawHLine(Xpos - cury, Ypos + curx, 2 * cury);
+ BSP_LCD_DrawHLine(Xpos - cury, Ypos - curx, 2 * cury);
+ }
+
+ if (curx > 0)
+ {
+ BSP_LCD_DrawHLine(Xpos - curx, Ypos - cury, 2 * curx);
+ BSP_LCD_DrawHLine(Xpos - curx, Ypos + cury, 2 * curx);
+ }
+ if (d < 0)
+ {
+ d += (curx << 2) + 6;
+ }
+ else
+ {
+ d += ((curx - cury) << 2) + 10;
+ cury--;
+ }
+ curx++;
+ }
+
+ BSP_LCD_SetTextColor(DrawProp[ActiveLayer].TextColor);
+ BSP_LCD_DrawCircle(Xpos, Ypos, Radius);
+}
+
+/**
+ * @brief Fill triangle.
+ * @param X1: the point 1 x position
+ * @param Y1: the point 1 y position
+ * @param X2: the point 2 x position
+ * @param Y2: the point 2 y position
+ * @param X3: the point 3 x position
+ * @param Y3: the point 3 y position
+ */
+void BSP_LCD_FillTriangle(uint16_t X1, uint16_t X2, uint16_t X3, uint16_t Y1, uint16_t Y2, uint16_t Y3)
+{
+ int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
+ yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0,
+ curpixel = 0;
+
+ deltax = ABS(X2 - X1); /* The difference between the x's */
+ deltay = ABS(Y2 - Y1); /* The difference between the y's */
+ x = X1; /* Start x off at the first pixel */
+ y = Y1; /* Start y off at the first pixel */
+
+ if (X2 >= X1) /* The x-values are increasing */
+ {
+ xinc1 = 1;
+ xinc2 = 1;
+ }
+ else /* The x-values are decreasing */
+ {
+ xinc1 = -1;
+ xinc2 = -1;
+ }
+
+ if (Y2 >= Y1) /* The y-values are increasing */
+ {
+ yinc1 = 1;
+ yinc2 = 1;
+ }
+ else /* The y-values are decreasing */
+ {
+ yinc1 = -1;
+ yinc2 = -1;
+ }
+
+ if (deltax >= deltay) /* There is at least one x-value for every y-value */
+ {
+ xinc1 = 0; /* Don't change the x when numerator >= denominator */
+ yinc2 = 0; /* Don't change the y for every iteration */
+ den = deltax;
+ num = deltax / 2;
+ numadd = deltay;
+ numpixels = deltax; /* There are more x-values than y-values */
+ }
+ else /* There is at least one y-value for every x-value */
+ {
+ xinc2 = 0; /* Don't change the x for every iteration */
+ yinc1 = 0; /* Don't change the y when numerator >= denominator */
+ den = deltay;
+ num = deltay / 2;
+ numadd = deltax;
+ numpixels = deltay; /* There are more y-values than x-values */
+ }
+
+ for (curpixel = 0; curpixel <= numpixels; curpixel++)
+ {
+ BSP_LCD_DrawLine(x, y, X3, Y3);
+
+ num += numadd; /* Increase the numerator by the top of the fraction */
+ if (num >= den) /* Check if numerator >= denominator */
+ {
+ num -= den; /* Calculate the new numerator value */
+ x += xinc1; /* Change the x as appropriate */
+ y += yinc1; /* Change the y as appropriate */
+ }
+ x += xinc2; /* Change the x as appropriate */
+ y += yinc2; /* Change the y as appropriate */
+ }
+}
+
+/**
+ * @brief Displays a full poly-line (between many points).
+ * @param Points: pointer to the points array
+ * @param PointCount: Number of points
+ */
+void BSP_LCD_FillPolygon(pPoint Points, uint16_t PointCount)
+{
+
+ int16_t x = 0, y = 0, x2 = 0, y2 = 0, xcenter = 0, ycenter = 0, xfirst = 0, yfirst = 0, pixelx = 0, pixely = 0, counter = 0;
+ uint16_t imageleft = 0, imageright = 0, imagetop = 0, imagebottom = 0;
+
+ imageleft = imageright = Points->X;
+ imagetop = imagebottom = Points->Y;
+
+ for (counter = 1; counter < PointCount; counter++)
+ {
+ pixelx = POLY_X(counter);
+ if (pixelx < imageleft)
+ {
+ imageleft = pixelx;
+ }
+ if (pixelx > imageright)
+ {
+ imageright = pixelx;
+ }
+
+ pixely = POLY_Y(counter);
+ if (pixely < imagetop)
+ {
+ imagetop = pixely;
+ }
+ if (pixely > imagebottom)
+ {
+ imagebottom = pixely;
+ }
+ }
+
+ if (PointCount < 2)
+ {
+ return;
+ }
+
+ xcenter = (imageleft + imageright) / 2;
+ ycenter = (imagebottom + imagetop) / 2;
+
+ xfirst = Points->X;
+ yfirst = Points->Y;
+
+ while (--PointCount)
+ {
+ x = Points->X;
+ y = Points->Y;
+ Points++;
+ x2 = Points->X;
+ y2 = Points->Y;
+
+ BSP_LCD_FillTriangle(x, x2, xcenter, y, y2, ycenter);
+ BSP_LCD_FillTriangle(x, xcenter, x2, y, ycenter, y2);
+ BSP_LCD_FillTriangle(xcenter, x2, x, ycenter, y2, y);
+ }
+
+ BSP_LCD_FillTriangle(xfirst, x2, xcenter, yfirst, y2, ycenter);
+ BSP_LCD_FillTriangle(xfirst, xcenter, x2, yfirst, ycenter, y2);
+ BSP_LCD_FillTriangle(xcenter, x2, xfirst, ycenter, y2, yfirst);
+}
+
+/**
+ * @brief Draw a full ellipse.
+ * @param Xpos: the X position
+ * @param Ypos: the Y position
+ * @param XRadius: X radius of ellipse
+ * @param YRadius: Y radius of ellipse.
+ */
+void BSP_LCD_FillEllipse(int Xpos, int Ypos, int XRadius, int YRadius)
+{
+ int x = 0, y = -YRadius, err = 2 - 2 * XRadius, e2;
+ float K = 0, rad1 = 0, rad2 = 0;
+
+ rad1 = XRadius;
+ rad2 = YRadius;
+ K = (float)(rad2 / rad1);
+
+ do
+ {
+ BSP_LCD_DrawHLine((Xpos - (uint16_t)(x / K)), (Ypos + y), (2 * (uint16_t)(x / K) + 1));
+ BSP_LCD_DrawHLine((Xpos - (uint16_t)(x / K)), (Ypos - y), (2 * (uint16_t)(x / K) + 1));
+
+ e2 = err;
+ if (e2 <= x)
+ {
+ err += ++x * 2 + 1;
+ if (-y == x && e2 <= y) { e2 = 0; }
+ }
+ if (e2 > y) { err += ++y * 2 + 1; }
+ } while (y <= 0);
+}
+
+/**
+ * @brief Enables the Display.
+ */
+void BSP_LCD_DisplayOn(void)
+{
+ if (LcdDrv->DisplayOn != NULL)
+ {
+ LcdDrv->DisplayOn();
+ }
+}
+
+/**
+ * @brief Disables the Display.
+ */
+void BSP_LCD_DisplayOff(void)
+{
+ if (LcdDrv->DisplayOff != NULL)
+ {
+ LcdDrv->DisplayOff();
+ }
+}
+
+/*******************************************************************************
+ LTDC and DMA2D BSP Routines
+ *******************************************************************************/
+
+/**
+ * @brief Initializes the LTDC MSP.
+ */
+__weak void BSP_LCD_MspInit(void)
+{
+ GPIO_InitTypeDef GPIO_InitStructure;
+
+ /* Enable the LTDC and DMA2D Clock */
+ __HAL_RCC_LTDC_CLK_ENABLE();
+ __HAL_RCC_DMA2D_CLK_ENABLE();
+
+ /* Enable GPIOs clock */
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOD_CLK_ENABLE();
+ __HAL_RCC_GPIOF_CLK_ENABLE();
+ __HAL_RCC_GPIOG_CLK_ENABLE();
+
+ /* GPIOs Configuration */
+ /*
+ +------------------------+-----------------------+----------------------------+
+ + LCD pins assignment +
+ +------------------------+-----------------------+----------------------------+
+ | LCD_TFT R2 <-> PC.10 | LCD_TFT G2 <-> PA.06 | LCD_TFT B2 <-> PD.06 |
+ | LCD_TFT R3 <-> PB.00 | LCD_TFT G3 <-> PG.10 | LCD_TFT B3 <-> PG.11 |
+ | LCD_TFT R4 <-> PA.11 | LCD_TFT G4 <-> PB.10 | LCD_TFT B4 <-> PG.12 |
+ | LCD_TFT R5 <-> PA.12 | LCD_TFT G5 <-> PB.11 | LCD_TFT B5 <-> PA.03 |
+ | LCD_TFT R6 <-> PB.01 | LCD_TFT G6 <-> PC.07 | LCD_TFT B6 <-> PB.08 |
+ | LCD_TFT R7 <-> PG.06 | LCD_TFT G7 <-> PD.03 | LCD_TFT B7 <-> PB.09 |
+ -------------------------------------------------------------------------------
+ | LCD_TFT HSYNC <-> PC.06 | LCDTFT VSYNC <-> PA.04 |
+ | LCD_TFT CLK <-> PG.07 | LCD_TFT DE <-> PF.10 |
+ -----------------------------------------------------
+ */
+
+ /* GPIOA configuration */
+ GPIO_InitStructure.Pin = GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_6 |
+ GPIO_PIN_11 | GPIO_PIN_12;
+ GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStructure.Pull = GPIO_NOPULL;
+ GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
+ GPIO_InitStructure.Alternate = GPIO_AF14_LTDC;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+ /* GPIOB configuration */
+ GPIO_InitStructure.Pin = GPIO_PIN_8 | \
+ GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+ /* GPIOC configuration */
+ GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_10;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
+
+ /* GPIOD configuration */
+ GPIO_InitStructure.Pin = GPIO_PIN_3 | GPIO_PIN_6;
+ HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+ /* GPIOF configuration */
+ GPIO_InitStructure.Pin = GPIO_PIN_10;
+ HAL_GPIO_Init(GPIOF, &GPIO_InitStructure);
+
+ /* GPIOG configuration */
+ GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7 | \
+ GPIO_PIN_11;
+ HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
+
+ /* GPIOB configuration */
+ GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1;
+ GPIO_InitStructure.Alternate = GPIO_AF9_LTDC;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+ /* GPIOG configuration */
+ GPIO_InitStructure.Pin = GPIO_PIN_10 | GPIO_PIN_12;
+ HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
+}
+
+/*******************************************************************************
+ Static Functions
+ *******************************************************************************/
+
+/**
+ * @brief Writes Pixel.
+ * @param Xpos: the X position
+ * @param Ypos: the Y position
+ * @param RGB_Code: the pixel color in ARGB mode (8-8-8-8)
+ */
+void BSP_LCD_DrawPixel(uint16_t Xpos, uint16_t Ypos, uint32_t RGB_Code)
+{
+ /* Write data value to all SDRAM memory */
+ *(__IO uint32_t *)(LtdcHandler.LayerCfg[ActiveLayer].FBStartAdress + (4 * (Ypos * BSP_LCD_GetXSize() + Xpos))) = RGB_Code;
+}
+
+/**
+ * @brief Draws a character on LCD.
+ * @param Xpos: the Line where to display the character shape
+ * @param Ypos: start column address
+ * @param c: pointer to the character data
+ */
+static void DrawChar(uint16_t Xpos, uint16_t Ypos, const uint8_t *c)
+{
+ uint32_t i = 0, j = 0;
+ uint16_t height, width;
+ uint8_t offset;
+ uint8_t *pchar;
+ uint32_t line = 0;
+
+ height = DrawProp[ActiveLayer].pFont->Height;
+ width = DrawProp[ActiveLayer].pFont->Width;
+
+ offset = 8 * ((width + 7) / 8) - width ;
+
+ for (i = 0; i < height; i++)
+ {
+ pchar = ((uint8_t *)c + (width + 7) / 8 * i);
+
+ switch (((width + 7) / 8))
+ {
+ case 1:
+ line = pchar[0];
+ break;
+
+ case 2:
+ line = (pchar[0] << 8) | pchar[1];
+ break;
+
+ case 3:
+ default:
+ line = (pchar[0] << 16) | (pchar[1] << 8) | pchar[2];
+ break;
+ }
+
+ for (j = 0; j < width; j++)
+ {
+ if (line & (1 << (width - j + offset - 1)))
+ {
+ BSP_LCD_DrawPixel((Xpos + j), Ypos, DrawProp[ActiveLayer].TextColor);
+ }
+ else
+ {
+ BSP_LCD_DrawPixel((Xpos + j), Ypos, DrawProp[ActiveLayer].BackColor);
+ }
+ }
+ Ypos++;
+ }
+}
+
+/**
+ * @brief Fills buffer.
+ * @param LayerIndex: layer index
+ * @param pDst: output color
+ * @param xSize: buffer width
+ * @param ySize: buffer height
+ * @param OffLine: offset
+ * @param ColorIndex: color Index
+ */
+static void FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine,
+ uint32_t ColorIndex)
+{
+
+ /* Register to memory mode with ARGB8888 as color Mode */
+ Dma2dHandler.Init.Mode = DMA2D_R2M;
+ Dma2dHandler.Init.ColorMode = DMA2D_ARGB8888;
+ Dma2dHandler.Init.OutputOffset = OffLine;
+
+ Dma2dHandler.Instance = DMA2D;
+
+ /* DMA2D Initialization */
+ if (HAL_DMA2D_Init(&Dma2dHandler) == HAL_OK)
+ {
+ if (HAL_DMA2D_ConfigLayer(&Dma2dHandler, LayerIndex) == HAL_OK)
+ {
+ if (HAL_DMA2D_Start(&Dma2dHandler, ColorIndex, (uint32_t)pDst, xSize, ySize) == HAL_OK)
+ {
+ /* Polling For DMA transfer */
+ HAL_DMA2D_PollForTransfer(&Dma2dHandler, 10);
+ }
+ }
+ }
+}
+
+/**
+ * @brief Converts Line to ARGB8888 pixel format.
+ * @param pSrc: pointer to source buffer
+ * @param pDst: output color
+ * @param xSize: buffer width
+ * @param ColorMode: input color mode
+ */
+static void ConvertLineToARGB8888(void *pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode)
+{
+ /* Configure the DMA2D Mode, Color Mode and output offset */
+ Dma2dHandler.Init.Mode = DMA2D_M2M_PFC;
+ Dma2dHandler.Init.ColorMode = DMA2D_ARGB8888;
+ Dma2dHandler.Init.OutputOffset = 0;
+
+ /* Foreground Configuration */
+ Dma2dHandler.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
+ Dma2dHandler.LayerCfg[1].InputAlpha = 0xFF;
+ Dma2dHandler.LayerCfg[1].InputColorMode = ColorMode;
+ Dma2dHandler.LayerCfg[1].InputOffset = 0;
+
+ Dma2dHandler.Instance = DMA2D;
+
+ /* DMA2D Initialization */
+ if (HAL_DMA2D_Init(&Dma2dHandler) == HAL_OK)
+ {
+ if (HAL_DMA2D_ConfigLayer(&Dma2dHandler, 1) == HAL_OK)
+ {
+ if (HAL_DMA2D_Start(&Dma2dHandler, (uint32_t)pSrc, (uint32_t)pDst, xSize, 1) == HAL_OK)
+ {
+ /* Polling For DMA transfer */
+ HAL_DMA2D_PollForTransfer(&Dma2dHandler, 10);
+ }
+ }
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_lcd.h b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_lcd.h
new file mode 100644
index 0000000..1869696
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_lcd.h
@@ -0,0 +1,246 @@
+/**
+ ******************************************************************************
+ * @file stm32f429i_discovery_lcd.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for the
+ * stm32f429i_discovery_lcd.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F429I_DISCOVERY_LCD_H
+#define __STM32F429I_DISCOVERY_LCD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f429i_discovery.h"
+/* Include SDRAM Driver */
+#include "stm32f429i_discovery_sdram.h"
+#include "../../../Utilities/Fonts/fonts.h"
+/* Include LCD component driver */
+#include "../Components/ili9341/ili9341.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY_LCD
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LCD_Exported_Types STM32F429I DISCOVERY LCD Exported Types
+ * @{
+ */
+typedef enum
+{
+ LCD_OK = 0,
+ LCD_ERROR = 1,
+ LCD_TIMEOUT = 2
+} LCD_StatusTypeDef;
+
+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 STM32F429I_DISCOVERY_LCD_Exported_Constants STM32F429I DISCOVERY LCD Exported Constants
+ * @{
+ */
+#define LCD_LayerCfgTypeDef LTDC_LayerCfgTypeDef
+
+/**
+ * @brief LCD status structure definition
+ */
+#define MAX_LAYER_NUMBER 2
+#define LCD_FRAME_BUFFER ((uint32_t)0xD0000000)
+#define BUFFER_OFFSET ((uint32_t)0x50000)
+
+/**
+ * @brief LCD color
+ */
+#define LCD_COLOR_BLUE 0xFF0000FF
+#define LCD_COLOR_GREEN 0xFF00FF00
+#define LCD_COLOR_RED 0xFFFF0000
+#define LCD_COLOR_CYAN 0xFF00FFFF
+#define LCD_COLOR_MAGENTA 0xFFFF00FF
+#define LCD_COLOR_YELLOW 0xFFFFFF00
+#define LCD_COLOR_LIGHTBLUE 0xFF8080FF
+#define LCD_COLOR_LIGHTGREEN 0xFF80FF80
+#define LCD_COLOR_LIGHTRED 0xFFFF8080
+#define LCD_COLOR_LIGHTCYAN 0xFF80FFFF
+#define LCD_COLOR_LIGHTMAGENTA 0xFFFF80FF
+#define LCD_COLOR_LIGHTYELLOW 0xFFFFFF80
+#define LCD_COLOR_DARKBLUE 0xFF000080
+#define LCD_COLOR_DARKGREEN 0xFF008000
+#define LCD_COLOR_DARKRED 0xFF800000
+#define LCD_COLOR_DARKCYAN 0xFF008080
+#define LCD_COLOR_DARKMAGENTA 0xFF800080
+#define LCD_COLOR_DARKYELLOW 0xFF808000
+#define LCD_COLOR_WHITE 0xFFFFFFFF
+#define LCD_COLOR_LIGHTGRAY 0xFFD3D3D3
+#define LCD_COLOR_GRAY 0xFF808080
+#define LCD_COLOR_DARKGRAY 0xFF404040
+#define LCD_COLOR_BLACK 0xFF000000
+#define LCD_COLOR_BROWN 0xFFA52A2A
+#define LCD_COLOR_ORANGE 0xFFFFA500
+#define LCD_COLOR_TRANSPARENT 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)
+
+/**
+ * @brief LCD Layer
+ */
+#define LCD_BACKGROUND_LAYER 0x0000
+#define LCD_FOREGROUND_LAYER 0x0001
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LCD_Exported_Macros STM32F429I DISCOVERY LCD Exported Macros
+ * @{
+ */
+/**
+ * @brief LCD Pixel format
+ */
+#define LCD_PIXEL_FORMAT_ARGB8888 LTDC_PIXEL_FORMAT_ARGB8888
+#define LCD_PIXEL_FORMAT_RGB888 LTDC_PIXEL_FORMAT_RGB888
+#define LCD_PIXEL_FORMAT_RGB565 LTDC_PIXEL_FORMAT_RGB565
+#define LCD_PIXEL_FORMAT_ARGB1555 LTDC_PIXEL_FORMAT_ARGB1555
+#define LCD_PIXEL_FORMAT_ARGB4444 LTDC_PIXEL_FORMAT_ARGB4444
+#define LCD_PIXEL_FORMAT_L8 LTDC_PIXEL_FORMAT_L8
+#define LCD_PIXEL_FORMAT_AL44 LTDC_PIXEL_FORMAT_AL44
+#define LCD_PIXEL_FORMAT_AL88 LTDC_PIXEL_FORMAT_AL88
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_LCD_Exported_Functions STM32F429I DISCOVERY LCD Exported Functions
+ * @{
+ */
+uint8_t BSP_LCD_Init(void);
+uint32_t BSP_LCD_GetXSize(void);
+uint32_t BSP_LCD_GetYSize(void);
+
+/* 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);
+void BSP_LCD_SetBackColor(uint32_t Color);
+uint32_t BSP_LCD_GetTextColor(void);
+uint32_t BSP_LCD_GetBackColor(void);
+void BSP_LCD_SetFont(sFONT *pFonts);
+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 X, uint16_t Y, uint8_t *pText, 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 X, uint32_t Y, 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_FillTriangle(uint16_t X1, uint16_t X2, uint16_t X3, uint16_t Y1, uint16_t Y2, uint16_t Y3);
+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);
+
+/* This function can be modified in case the current settings need to be changed
+ for specific application needs */
+void BSP_LCD_MspInit(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F429I_DISCOVERY_LCD_H */
diff --git a/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_sdram.c b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_sdram.c
new file mode 100644
index 0000000..23de02b
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_sdram.c
@@ -0,0 +1,460 @@
+/**
+ ******************************************************************************
+ * @file stm32f429i_discovery_sdram.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to drive the
+ * IS42S16400J SDRAM memory mounted on STM32F429I-Discovery Kit.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f429i_discovery_sdram.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_SDRAM STM32F429I DISCOVERY SDRAM
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Types_Definitions STM32F429I DISCOVERY SDRAM Private Types Definitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Defines STM32F429I DISCOVERY SDRAM Private Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Macros STM32F429I DISCOVERY SDRAM Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Variables STM32F429I DISCOVERY SDRAM Private Variables
+ * @{
+ */
+static SDRAM_HandleTypeDef SdramHandle;
+static FMC_SDRAM_TimingTypeDef Timing;
+static FMC_SDRAM_CommandTypeDef Command;
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Function_Prototypes STM32F429I DISCOVERY SDRAM Private Function Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Functions STM32F429I DISCOVERY SDRAM Private Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes the SDRAM device.
+ */
+uint8_t BSP_SDRAM_Init(void)
+{
+ static uint8_t sdramstatus = SDRAM_ERROR;
+
+ /* SDRAM device configuration */
+ SdramHandle.Instance = FMC_SDRAM_DEVICE;
+
+ /* FMC Configuration -------------------------------------------------------*/
+ /* FMC SDRAM Bank configuration */
+ /* Timing configuration for 90 Mhz of SD clock frequency (180Mhz/2) */
+ /* TMRD: 2 Clock cycles */
+ Timing.LoadToActiveDelay = 2;
+ /* TXSR: min=70ns (7x11.11ns) */
+ Timing.ExitSelfRefreshDelay = 7;
+ /* TRAS: min=42ns (4x11.11ns) max=120k (ns) */
+ Timing.SelfRefreshTime = 4;
+ /* TRC: min=70 (7x11.11ns) */
+ Timing.RowCycleDelay = 7;
+ /* TWR: min=1+ 7ns (1+1x11.11ns) */
+ Timing.WriteRecoveryTime = 2;
+ /* TRP: 20ns => 2x11.11ns*/
+ Timing.RPDelay = 2;
+ /* TRCD: 20ns => 2x11.11ns */
+ Timing.RCDDelay = 2;
+
+ /* FMC SDRAM control configuration */
+ SdramHandle.Init.SDBank = FMC_SDRAM_BANK2;
+ /* Row addressing: [7:0] */
+ SdramHandle.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
+ /* Column addressing: [11:0] */
+ SdramHandle.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
+ SdramHandle.Init.MemoryDataWidth = SDRAM_MEMORY_WIDTH;
+ SdramHandle.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
+ SdramHandle.Init.CASLatency = SDRAM_CAS_LATENCY;
+ SdramHandle.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
+ SdramHandle.Init.SDClockPeriod = SDCLOCK_PERIOD;
+ SdramHandle.Init.ReadBurst = SDRAM_READBURST;
+ SdramHandle.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1;
+
+ /* SDRAM controller initialization */
+ /* __weak function can be surcharged by the application code */
+ BSP_SDRAM_MspInit(&SdramHandle, (void *)NULL);
+ if (HAL_SDRAM_Init(&SdramHandle, &Timing) != HAL_OK)
+ {
+ sdramstatus = SDRAM_ERROR;
+ }
+ else
+ {
+ sdramstatus = SDRAM_OK;
+ }
+
+ /* SDRAM initialization sequence */
+ BSP_SDRAM_Initialization_sequence(REFRESH_COUNT);
+
+ return sdramstatus;
+}
+
+/**
+ * @brief Programs the SDRAM device.
+ * @param RefreshCount: SDRAM refresh counter value
+ */
+void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount)
+{
+ __IO uint32_t tmpmrd = 0;
+
+ /* Step 1: Configure a clock configuration enable command */
+ Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
+ Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
+ Command.AutoRefreshNumber = 1;
+ Command.ModeRegisterDefinition = 0;
+
+ /* Send the command */
+ HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);
+
+ /* Step 2: Insert 100 us minimum delay */
+ /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
+ HAL_Delay(1);
+
+ /* Step 3: Configure a PALL (precharge all) command */
+ Command.CommandMode = FMC_SDRAM_CMD_PALL;
+ Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
+ Command.AutoRefreshNumber = 1;
+ Command.ModeRegisterDefinition = 0;
+
+ /* Send the command */
+ HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);
+
+ /* Step 4: Configure an Auto Refresh command */
+ Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
+ Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
+ Command.AutoRefreshNumber = 4;
+ Command.ModeRegisterDefinition = 0;
+
+ /* Send the command */
+ HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);
+
+ /* Step 5: Program the external memory mode register */
+ tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
+ SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
+ SDRAM_MODEREG_CAS_LATENCY_3 |
+ SDRAM_MODEREG_OPERATING_MODE_STANDARD |
+ SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
+
+ Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
+ Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
+ Command.AutoRefreshNumber = 1;
+ Command.ModeRegisterDefinition = tmpmrd;
+
+ /* Send the command */
+ HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);
+
+ /* Step 6: Set the refresh rate counter */
+ /* Set the device refresh rate */
+ HAL_SDRAM_ProgramRefreshRate(&SdramHandle, RefreshCount);
+}
+
+/**
+ * @brief Reads an mount of data from the SDRAM memory in polling mode.
+ * @param uwStartAddress : Read start address
+ * @param pData : Pointer to data to be read
+ * @param uwDataSize: Size of read data from the memory
+ */
+uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)
+{
+ if (HAL_SDRAM_Read_32b(&SdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
+ {
+ return SDRAM_ERROR;
+ }
+ else
+ {
+ return SDRAM_OK;
+ }
+}
+
+/**
+ * @brief Reads an mount of data from the SDRAM memory in DMA mode.
+ * @param uwStartAddress : Read start address
+ * @param pData : Pointer to data to be read
+ * @param uwDataSize: Size of read data from the memory
+ */
+uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)
+{
+ if (HAL_SDRAM_Read_DMA(&SdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
+ {
+ return SDRAM_ERROR;
+ }
+ else
+ {
+ return SDRAM_OK;
+ }
+}
+
+/**
+ * @brief Writes an mount of data to the SDRAM memory in polling mode.
+ * @param uwStartAddress : Write start address
+ * @param pData : Pointer to data to be written
+ * @param uwDataSize: Size of written data from the memory
+ */
+uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)
+{
+ /* Disable write protection */
+ HAL_SDRAM_WriteProtection_Disable(&SdramHandle);
+
+ /*Write 32-bit data buffer to SDRAM memory*/
+ if (HAL_SDRAM_Write_32b(&SdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
+ {
+ return SDRAM_ERROR;
+ }
+ else
+ {
+ return SDRAM_OK;
+ }
+}
+
+/**
+ * @brief Writes an mount of data to the SDRAM memory in DMA mode.
+ * @param uwStartAddress : Write start address
+ * @param pData : Pointer to data to be written
+ * @param uwDataSize: Size of written data from the memory
+ */
+uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)
+{
+ if (HAL_SDRAM_Write_DMA(&SdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
+ {
+ return SDRAM_ERROR;
+ }
+ else
+ {
+ return SDRAM_OK;
+ }
+}
+
+/**
+ * @brief Sends command to the SDRAM bank.
+ * @param SdramCmd: Pointer to SDRAM command structure
+ * @retval HAL status
+ */
+uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd)
+{
+ if (HAL_SDRAM_SendCommand(&SdramHandle, SdramCmd, SDRAM_TIMEOUT) != HAL_OK)
+ {
+ return SDRAM_ERROR;
+ }
+ else
+ {
+ return SDRAM_OK;
+ }
+}
+
+/**
+ * @brief Handles SDRAM DMA transfer interrupt request.
+ */
+void BSP_SDRAM_DMA_IRQHandler(void)
+{
+ HAL_DMA_IRQHandler(SdramHandle.hdma);
+}
+
+/**
+ * @brief Initializes SDRAM MSP.
+ * @note This function can be surcharged by application code.
+ * @param hsdram: pointer on SDRAM handle
+ * @param Params: pointer on additional configuration parameters, can be NULL.
+ */
+__weak void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram, void *Params)
+{
+ static DMA_HandleTypeDef dmaHandle;
+ GPIO_InitTypeDef GPIO_InitStructure;
+
+ if (hsdram != (SDRAM_HandleTypeDef *)NULL)
+ {
+ /* Enable FMC clock */
+ __HAL_RCC_FMC_CLK_ENABLE();
+
+ /* Enable chosen DMAx clock */
+ __DMAx_CLK_ENABLE();
+
+ /* Enable GPIOs clock */
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOD_CLK_ENABLE();
+ __HAL_RCC_GPIOE_CLK_ENABLE();
+ __HAL_RCC_GPIOF_CLK_ENABLE();
+ __HAL_RCC_GPIOG_CLK_ENABLE();
+
+ /*-- GPIOs Configuration -----------------------------------------------------*/
+ /*
+ +-------------------+--------------------+--------------------+--------------------+
+ + SDRAM pins assignment +
+ +-------------------+--------------------+--------------------+--------------------+
+ | PD0 <-> FMC_D2 | PE0 <-> FMC_NBL0 | PF0 <-> FMC_A0 | PG0 <-> FMC_A10 |
+ | PD1 <-> FMC_D3 | PE1 <-> FMC_NBL1 | PF1 <-> FMC_A1 | PG1 <-> FMC_A11 |
+ | PD8 <-> FMC_D13 | PE7 <-> FMC_D4 | PF2 <-> FMC_A2 | PG8 <-> FMC_SDCLK |
+ | PD9 <-> FMC_D14 | PE8 <-> FMC_D5 | PF3 <-> FMC_A3 | PG15 <-> FMC_NCAS |
+ | PD10 <-> FMC_D15 | PE9 <-> FMC_D6 | PF4 <-> FMC_A4 |--------------------+
+ | PD14 <-> FMC_D0 | PE10 <-> FMC_D7 | PF5 <-> FMC_A5 |
+ | PD15 <-> FMC_D1 | PE11 <-> FMC_D8 | PF11 <-> FMC_NRAS |
+ +-------------------| PE12 <-> FMC_D9 | PF12 <-> FMC_A6 |
+ | PE13 <-> FMC_D10 | PF13 <-> FMC_A7 |
+ | PE14 <-> FMC_D11 | PF14 <-> FMC_A8 |
+ | PE15 <-> FMC_D12 | PF15 <-> FMC_A9 |
+ +-------------------+--------------------+--------------------+
+ | PB5 <-> FMC_SDCKE1|
+ | PB6 <-> FMC_SDNE1 |
+ | PC0 <-> FMC_SDNWE |
+ +-------------------+
+
+ */
+
+ /* Common GPIO configuration */
+ GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
+ GPIO_InitStructure.Pull = GPIO_NOPULL;
+ GPIO_InitStructure.Alternate = GPIO_AF12_FMC;
+
+ /* GPIOB configuration */
+ GPIO_InitStructure.Pin = GPIO_PIN_5 | GPIO_PIN_6;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+ /* GPIOC configuration */
+ GPIO_InitStructure.Pin = GPIO_PIN_0;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
+
+ /* GPIOD configuration */
+ GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 |
+ GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 |
+ GPIO_PIN_15;
+ HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+ /* GPIOE configuration */
+ GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7 |
+ GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 |
+ GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |
+ GPIO_PIN_14 | GPIO_PIN_15;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
+
+ /* GPIOF configuration */
+ GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 |
+ GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 |
+ GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |
+ GPIO_PIN_14 | GPIO_PIN_15;
+ HAL_GPIO_Init(GPIOF, &GPIO_InitStructure);
+
+ /* GPIOG configuration */
+ GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 |
+ GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15;
+ HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
+
+ /* Configure common DMA parameters */
+ dmaHandle.Init.Channel = SDRAM_DMAx_CHANNEL;
+ dmaHandle.Init.Direction = DMA_MEMORY_TO_MEMORY;
+ dmaHandle.Init.PeriphInc = DMA_PINC_ENABLE;
+ dmaHandle.Init.MemInc = DMA_MINC_ENABLE;
+ dmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ dmaHandle.Init.Mode = DMA_NORMAL;
+ dmaHandle.Init.Priority = DMA_PRIORITY_HIGH;
+ dmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+ dmaHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ dmaHandle.Init.MemBurst = DMA_MBURST_SINGLE;
+ dmaHandle.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+ dmaHandle.Instance = SDRAM_DMAx_STREAM;
+
+ /* Associate the DMA handle */
+ __HAL_LINKDMA(hsdram, hdma, dmaHandle);
+
+ /* Deinitialize the stream for new transfer */
+ HAL_DMA_DeInit(&dmaHandle);
+
+ /* Configure the DMA stream */
+ HAL_DMA_Init(&dmaHandle);
+
+ /* NVIC configuration for DMA transfer complete interrupt */
+ HAL_NVIC_SetPriority(SDRAM_DMAx_IRQn, 0x0F, 0);
+ HAL_NVIC_EnableIRQ(SDRAM_DMAx_IRQn);
+ } /* of if(hsdram != (SDRAM_HandleTypeDef *)NULL) */
+}
+
+/**
+ * @brief DeInitializes SDRAM MSP.
+ * @note This function can be surcharged by application code.
+ * @param hsdram: pointer on SDRAM handle
+ * @param Params: pointer on additional configuration parameters, can be NULL.
+ */
+__weak void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram, void *Params)
+{
+ static DMA_HandleTypeDef dma_handle;
+
+ if (hsdram != (SDRAM_HandleTypeDef *)NULL)
+ {
+ /* Disable NVIC configuration for DMA interrupt */
+ HAL_NVIC_DisableIRQ(SDRAM_DMAx_IRQn);
+
+ /* Deinitialize the stream for new transfer */
+ dma_handle.Instance = SDRAM_DMAx_STREAM;
+ HAL_DMA_DeInit(&dma_handle);
+
+ /* DeInit GPIO pins can be done in the application
+ (by surcharging this __weak function) */
+
+ /* GPIO pins clock, FMC clock and DMA clock can be shut down in the application
+ by surcharging this __weak function */
+
+ } /* of if(hsdram != (SDRAM_HandleTypeDef *)NULL) */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_sdram.h b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_sdram.h
new file mode 100644
index 0000000..f2cb9c2
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_sdram.h
@@ -0,0 +1,169 @@
+/**
+ ******************************************************************************
+ * @file stm32f429i_discovery_sdram.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for the
+ * stm32f429i_discovery_sdram.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F429I_DISCOVERY_SDRAM_H
+#define __STM32F429I_DISCOVERY_SDRAM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f429i_discovery.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY_SDRAM
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_SDRAM_Exported_Types STM32F429I DISCOVERY SDRAM Exported Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_SDRAM_Exported_Constants STM32F429I DISCOVERY SDRAM Exported Constants
+ * @{
+ */
+
+/**
+ * @brief SDRAM status structure definition
+ */
+#define SDRAM_OK ((uint8_t)0x00)
+#define SDRAM_ERROR ((uint8_t)0x01)
+
+/**
+ * @brief FMC SDRAM Bank address
+ */
+#define SDRAM_DEVICE_ADDR ((uint32_t)0xD0000000)
+#define SDRAM_DEVICE_SIZE ((uint32_t)0x800000) /* SDRAM device size in Bytes */
+
+/**
+ * @brief FMC SDRAM Memory Width
+ */
+/* #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_8 */
+#define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16
+
+/**
+ * @brief FMC SDRAM CAS Latency
+ */
+/* #define SDRAM_CAS_LATENCY FMC_SDRAM_CAS_LATENCY_2 */
+#define SDRAM_CAS_LATENCY FMC_SDRAM_CAS_LATENCY_3
+
+/**
+ * @brief FMC SDRAM Memory clock period
+ */
+#define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_2 /* Default configuration used with LCD */
+/* #define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_3 */
+
+/**
+ * @brief FMC SDRAM Memory Read Burst feature
+ */
+#define SDRAM_READBURST FMC_SDRAM_RBURST_DISABLE /* Default configuration used with LCD */
+/* #define SDRAM_READBURST FMC_SDRAM_RBURST_ENABLE */
+
+/**
+ * @brief FMC SDRAM Bank Remap
+ */
+/* #define SDRAM_BANK_REMAP */
+
+/* Set the refresh rate counter */
+/* (15.62 us x Freq) - 20 */
+#define REFRESH_COUNT ((uint32_t)1386) /* SDRAM refresh counter */
+#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
+
+/* DMA definitions for SDRAM DMA transfer */
+#define __DMAx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
+#define SDRAM_DMAx_CHANNEL DMA_CHANNEL_0
+#define SDRAM_DMAx_STREAM DMA2_Stream0
+#define SDRAM_DMAx_IRQn DMA2_Stream0_IRQn
+#define SDRAM_DMAx_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 STM32F429I_DISCOVERY_SDRAM_Exported_Macro STM32F429I DISCOVERY SDRAM Exported Macro
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_SDRAM_Exported_Functions STM32F429I DISCOVERY SDRAM Exported Functions
+ * @{
+ */
+uint8_t BSP_SDRAM_Init(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);
+void BSP_SDRAM_DMA_IRQHandler(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_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram, void *Params);
+void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F429I_DISCOVERY_SDRAM_H */
diff --git a/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_ts.c b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_ts.c
new file mode 100644
index 0000000..b45f447
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_ts.c
@@ -0,0 +1,250 @@
+/**
+ ******************************************************************************
+ * @file stm32f429i_discovery_ts.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage Touch
+ * screen available with STMPE811 IO Expander device mounted on
+ * STM32F429I-Discovery Kit.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f429i_discovery_ts.h"
+#include "stm32f429i_discovery_io.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_TS STM32F429I DISCOVERY TS
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_TS_Private_Types_Definitions STM32F429I DISCOVERY TS Private Types Definitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_TS_Private_Defines STM32F429I DISCOVERY TS Private Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_TS_Private_Macros STM32F429I DISCOVERY TS Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_TS_Private_Variables STM32F429I DISCOVERY TS Private Variables
+ * @{
+ */
+static TS_DrvTypeDef *TsDrv;
+static uint16_t TsXBoundary, TsYBoundary;
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_TS_Private_Function_Prototypes STM32F429I DISCOVERY TS Private Function Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_TS_Private_Functions STM32F429I DISCOVERY TS Private Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes and configures the touch screen functionalities and
+ * configures all necessary hardware resources (GPIOs, clocks..).
+ * @param XSize: The maximum X size of the TS area on LCD
+ * @param YSize: The 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 XSize, uint16_t YSize)
+{
+ uint8_t ret = TS_ERROR;
+
+ /* Initialize x and y positions boundaries */
+ TsXBoundary = XSize;
+ TsYBoundary = YSize;
+
+ /* Read ID and verify if the IO expander is ready */
+ if (stmpe811_ts_drv.ReadID(TS_I2C_ADDRESS) == STMPE811_ID)
+ {
+ /* Initialize the TS driver structure */
+ TsDrv = &stmpe811_ts_drv;
+
+ ret = TS_OK;
+ }
+
+ if (ret == TS_OK)
+ {
+ /* Initialize the LL TS Driver */
+ TsDrv->Init(TS_I2C_ADDRESS);
+ TsDrv->Start(TS_I2C_ADDRESS);
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Configures and enables the touch screen interrupts.
+ * @retval TS_OK: if ITconfig is OK. Other value if error.
+ */
+uint8_t BSP_TS_ITConfig(void)
+{
+ /* Enable the TS ITs */
+ TsDrv->EnableIT(TS_I2C_ADDRESS);
+
+ return TS_OK;
+}
+
+/**
+ * @brief Gets the TS IT status.
+ * @retval Interrupt status.
+ */
+uint8_t BSP_TS_ITGetStatus(void)
+{
+ /* Return the TS IT status */
+ return (TsDrv->GetITStatus(TS_I2C_ADDRESS));
+}
+
+/**
+ * @brief Returns status and positions of the touch screen.
+ * @param TsState: Pointer to touch screen current state structure
+ */
+void BSP_TS_GetState(TS_StateTypeDef *TsState)
+{
+ static uint32_t _x = 0, _y = 0;
+ uint16_t xDiff, yDiff, x, y, xr, yr;
+
+ TsState->TouchDetected = TsDrv->DetectTouch(TS_I2C_ADDRESS);
+
+ if (TsState->TouchDetected)
+ {
+ TsDrv->GetXY(TS_I2C_ADDRESS, &x, &y);
+
+#if defined (USE_STM32F429I_DISCOVERY_REVD)
+ if (y > 3700)
+ {
+ y = 3700;
+ }
+ else if (y < 180)
+ {
+ y = 180;
+ }
+
+ /* Y value first correction */
+ y = 3700 - y;
+#else
+
+ /* Y value first correction */
+ y -= 360;
+
+#endif
+
+ /* Y value second correction */
+ yr = y / 11;
+
+ /* Return y position value */
+ if (yr <= 0)
+ {
+ yr = 0;
+ }
+ else if (yr > TsYBoundary)
+ {
+ yr = TsYBoundary - 1;
+ }
+ else
+ {}
+ y = yr;
+
+ /* X value first correction */
+ if (x <= 3000)
+ {
+ x = 3870 - x;
+ }
+ else
+ {
+ x = 3800 - x;
+ }
+
+ /* X value second correction */
+ xr = x / 15;
+
+ /* Return X position value */
+ if (xr <= 0)
+ {
+ xr = 0;
+ }
+ else if (xr > TsXBoundary)
+ {
+ xr = TsXBoundary - 1;
+ }
+ else
+ {}
+
+ x = xr;
+ xDiff = x > _x ? (x - _x): (_x - x);
+ yDiff = y > _y ? (y - _y) : (_y - y);
+
+ if (xDiff + yDiff > 5)
+ {
+ _x = x;
+ _y = y;
+ }
+
+ /* Update the X position */
+ TsState->X = _x;
+
+ /* Update the Y position */
+ TsState->Y = _y;
+ }
+}
+
+/**
+ * @brief Clears all touch screen interrupts.
+ */
+void BSP_TS_ITClear(void)
+{
+ /* Clear TS IT pending bits */
+ TsDrv->ClearIT(TS_I2C_ADDRESS);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
diff --git a/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_ts.h b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_ts.h
new file mode 100644
index 0000000..b2b7887
--- /dev/null
+++ b/Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_ts.h
@@ -0,0 +1,113 @@
+/**
+ ******************************************************************************
+ * @file stm32f429i_discovery_ts.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for the
+ * stm32f429i_discovery_ts.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F429I_DISCOVERY_TS_H
+#define __STM32F429I_DISCOVERY_TS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f429i_discovery.h"
+/* Include TouchScreen component driver */
+#include "../Components/stmpe811/stmpe811.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32F429I_DISCOVERY_TS
+ * @{
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_TS_Exported_Types STM32F429I DISCOVERY TS Exported Types
+ * @{
+ */
+typedef struct
+{
+ uint16_t TouchDetected;
+ uint16_t X;
+ uint16_t Y;
+ uint16_t Z;
+} TS_StateTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_TS_Exported_Constants STM32F429I DISCOVERY TS Exported Constants
+ * @{
+ */
+#define TS_SWAP_NONE 0x00
+#define TS_SWAP_X 0x01
+#define TS_SWAP_Y 0x02
+#define TS_SWAP_XY 0x04
+
+typedef enum
+{
+ TS_OK = 0x00,
+ TS_ERROR = 0x01,
+ TS_TIMEOUT = 0x02
+} TS_StatusTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_TS_Exported_Macros STM32F429I DISCOVERY TS Exported Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup STM32F429I_DISCOVERY_TS_Exported_Functions STM32F429I DISCOVERY TS Exported Functions
+ * @{
+ */
+uint8_t BSP_TS_Init(uint16_t XSize, uint16_t YSize);
+void BSP_TS_GetState(TS_StateTypeDef *TsState);
+uint8_t BSP_TS_ITConfig(void);
+uint8_t BSP_TS_ITGetStatus(void);
+void BSP_TS_ITClear(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F429I_DISCOVERY_TS_H */