Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: DISCO_H747I_LCD_demo DISCO_H747I_AUDIO_demo
Revision 0:146cf26a9bbb, committed 2019-09-25
- Comitter:
- Jerome Coutant
- Date:
- Wed Sep 25 13:37:39 2019 +0200
- Child:
- 1:9716849a8de8
- Commit message:
- STM32Cube_FW_H7_V1.5.0 BSP STM32H747I-DISCO
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/Common/audio.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,122 @@
+/**
+ ******************************************************************************
+ * @file audio.h
+ * @author MCD Application Team
+ * @version V4.0.1
+ * @date 21-July-2015
+ * @brief This header file contains the common defines and functions prototypes
+ * for the Audio driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AUDIO_H
+#define __AUDIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup AUDIO
+ * @{
+ */
+
+/** @defgroup AUDIO_Exported_Constants
+ * @{
+ */
+
+/* Codec audio Standards */
+#define CODEC_STANDARD 0x04
+#define I2S_STANDARD I2S_STANDARD_PHILIPS
+
+/**
+ * @}
+ */
+
+/** @defgroup AUDIO_Exported_Types
+ * @{
+ */
+
+/** @defgroup AUDIO_Driver_structure Audio Driver structure
+ * @{
+ */
+typedef struct
+{
+ uint32_t (*Init)(uint16_t, uint16_t, uint8_t, uint32_t);
+ void (*DeInit)(void);
+ uint32_t (*ReadID)(uint16_t);
+ uint32_t (*Play)(uint16_t, uint16_t*, uint16_t);
+ uint32_t (*Pause)(uint16_t);
+ uint32_t (*Resume)(uint16_t);
+ uint32_t (*Stop)(uint16_t, uint32_t);
+ uint32_t (*SetFrequency)(uint16_t, uint32_t);
+ uint32_t (*SetVolume)(uint16_t, uint8_t);
+ uint32_t (*SetMute)(uint16_t, uint32_t);
+ uint32_t (*SetOutputMode)(uint16_t, uint8_t);
+ uint32_t (*Reset)(uint16_t);
+}AUDIO_DrvTypeDef;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AUDIO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/Common/camera.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,141 @@
+/**
+ ******************************************************************************
+ * @file camera.h
+ * @author MCD Application Team
+ * @version V4.0.1
+ * @date 21-July-2015
+ * @brief This header file contains the common defines and functions prototypes
+ * for the camera driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __CAMERA_H
+#define __CAMERA_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup CAMERA
+ * @{
+ */
+
+
+/** @defgroup CAMERA_Exported_Types
+ * @{
+ */
+
+/** @defgroup CAMERA_Driver_structure Camera Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(uint16_t, uint32_t);
+ uint16_t (*ReadID)(uint16_t);
+ void (*Config)(uint16_t, uint32_t, uint32_t, uint32_t);
+}CAMERA_DrvTypeDef;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup CAMERA_Exported_Constants
+ * @{
+ */
+#define CAMERA_R160x120 0x00 /* QQVGA Resolution */
+#define CAMERA_R320x240 0x01 /* QVGA Resolution */
+#define CAMERA_R480x272 0x02 /* 480x272 Resolution */
+#define CAMERA_R640x480 0x03 /* VGA Resolution */
+
+#define CAMERA_CONTRAST_BRIGHTNESS 0x00 /* Camera contrast brightness features */
+#define CAMERA_BLACK_WHITE 0x01 /* Camera black white feature */
+#define CAMERA_COLOR_EFFECT 0x03 /* Camera color effect feature */
+
+#define CAMERA_BRIGHTNESS_LEVEL0 0x00 /* Brightness level -2 */
+#define CAMERA_BRIGHTNESS_LEVEL1 0x01 /* Brightness level -1 */
+#define CAMERA_BRIGHTNESS_LEVEL2 0x02 /* Brightness level 0 */
+#define CAMERA_BRIGHTNESS_LEVEL3 0x03 /* Brightness level +1 */
+#define CAMERA_BRIGHTNESS_LEVEL4 0x04 /* Brightness level +2 */
+
+#define CAMERA_CONTRAST_LEVEL0 0x05 /* Contrast level -2 */
+#define CAMERA_CONTRAST_LEVEL1 0x06 /* Contrast level -1 */
+#define CAMERA_CONTRAST_LEVEL2 0x07 /* Contrast level 0 */
+#define CAMERA_CONTRAST_LEVEL3 0x08 /* Contrast level +1 */
+#define CAMERA_CONTRAST_LEVEL4 0x09 /* Contrast level +2 */
+
+#define CAMERA_BLACK_WHITE_BW 0x00 /* Black and white effect */
+#define CAMERA_BLACK_WHITE_NEGATIVE 0x01 /* Negative effect */
+#define CAMERA_BLACK_WHITE_BW_NEGATIVE 0x02 /* BW and Negative effect */
+#define CAMERA_BLACK_WHITE_NORMAL 0x03 /* Normal effect */
+
+#define CAMERA_COLOR_EFFECT_NONE 0x00 /* No effects */
+#define CAMERA_COLOR_EFFECT_BLUE 0x01 /* Blue effect */
+#define CAMERA_COLOR_EFFECT_GREEN 0x02 /* Green effect */
+#define CAMERA_COLOR_EFFECT_RED 0x03 /* Red effect */
+#define CAMERA_COLOR_EFFECT_ANTIQUE 0x04 /* Antique effect */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CAMERA_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/Common/ts.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,107 @@
+/**
+ ******************************************************************************
+ * @file ts.h
+ * @author MCD Application Team
+ * @version V4.0.1
+ * @date 21-July-2015
+ * @brief This file contains all the functions prototypes for the Touch Screen driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TS_H
+#define __TS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup TS
+ * @{
+ */
+
+/** @defgroup TS_Exported_Types
+ * @{
+ */
+
+/** @defgroup TS_Driver_structure Touch Sensor Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(uint16_t);
+ uint16_t (*ReadID)(uint16_t);
+ void (*Reset)(uint16_t);
+ void (*Start)(uint16_t);
+ uint8_t (*DetectTouch)(uint16_t);
+ void (*GetXY)(uint16_t, uint16_t*, uint16_t*);
+ void (*EnableIT)(uint16_t);
+ void (*ClearIT)(uint16_t);
+ uint8_t (*GetITStatus)(uint16_t);
+ void (*DisableIT)(uint16_t);
+}TS_DrvTypeDef;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/ft6x06/ft6x06.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,516 @@
+/**
+ ******************************************************************************
+ * @file ft6x06.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 03-August-2015
+ * @brief This file provides a set of functions needed to manage the FT6X06
+ * IO Expander devices.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "ft6x06.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Component
+ * @{
+ */
+
+/** @defgroup FT6X06
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+
+/** @defgroup FT6X06_Private_Defines FT6X06 Private Defines
+ * @{
+ */
+#define FT6x06_MAX_INSTANCE 2
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+
+/** @defgroup FT6X06_Private_Variables FT6X06 Private Variables
+ * @{
+ */
+
+/* Touch screen driver structure initialization */
+TS_DrvTypeDef ft6x06_ts_drv =
+{
+ ft6x06_Init,
+ ft6x06_ReadID,
+ ft6x06_Reset,
+
+ ft6x06_TS_Start,
+ ft6x06_TS_DetectTouch,
+ ft6x06_TS_GetXY,
+
+ ft6x06_TS_EnableIT,
+ ft6x06_TS_ClearIT,
+ ft6x06_TS_ITStatus,
+ ft6x06_TS_DisableIT
+
+};
+
+/* ft6x06 instances by address */
+uint8_t ft6x06[FT6x06_MAX_INSTANCE] = {0};
+
+/* Global ft6x06 handle */
+static ft6x06_handle_TypeDef ft6x06_handle = { FT6206_I2C_NOT_INITIALIZED, 0, 0};
+
+/**
+ * @}
+ */
+
+/** @defgroup ft6x06_Private_Function_Prototypes ft6x06 Private Function Prototypes
+ * @{
+ */
+static uint8_t ft6x06_GetInstance(uint16_t DeviceAddr);
+/* Private functions prototypes-----------------------------------------------*/
+#if (TS_AUTO_CALIBRATION_SUPPORTED == 1)
+/**
+ * @brief Start TouchScreen calibration phase
+ * @param DeviceAddr: FT6206 Device address for communication on I2C Bus.
+ * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK.
+ */
+static uint32_t ft6x06_TS_Calibration(uint16_t DeviceAddr);
+#endif /* TS_AUTO_CALIBRATION_SUPPORTED == 1 */
+
+/**
+ * @brief Basic static configuration of TouchScreen
+ * @param DeviceAddr: FT6206 Device address for communication on I2C Bus.
+ * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK.
+ */
+static uint32_t ft6x06_TS_Configure(uint16_t DeviceAddr);
+
+/**
+ * @}
+ */
+
+/** @defgroup ft6x06_Private_Functions ft6x06 Private Functions
+ * @{
+ */
+
+/**
+ * @brief Initialize the ft6x06 communication bus
+ * from MCU to FT6206 : ie I2C channel initialization (if required).
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval None
+ */
+void ft6x06_Init(uint16_t DeviceAddr)
+{
+ uint8_t instance;
+ uint8_t empty;
+
+ /* Check if device instance already exists */
+ instance = ft6x06_GetInstance(DeviceAddr);
+
+ /* To prevent double initialization */
+ if(instance == 0xFF)
+ {
+ /* Look for empty instance */
+ empty = ft6x06_GetInstance(0);
+
+ if(empty < FT6x06_MAX_INSTANCE)
+ {
+ /* Register the current device instance */
+ ft6x06[empty] = DeviceAddr;
+
+ /* Initialize IO BUS layer */
+ TS_IO_Init();
+ }
+ }
+}
+
+/**
+ * @brief Software Reset the ft6x06.
+ * @note : Not applicable to FT6206.
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval None
+ */
+void ft6x06_Reset(uint16_t DeviceAddr)
+{
+ /* Do nothing */
+ /* No software reset sequence available in FT6206 IC */
+}
+
+/**
+ * @brief Read the ft6x06 device ID, pre initialize I2C in case of need to be
+ * able to read the FT6206 device ID, and verify this is a FT6206.
+ * @param DeviceAddr: I2C FT6x06 Slave address.
+ * @retval The Device ID (two bytes).
+ */
+uint16_t ft6x06_ReadID(uint16_t DeviceAddr)
+{
+ /* Initialize I2C link if needed */
+ TS_IO_Init();
+
+ /* Return the device ID value */
+ return (TS_IO_Read(DeviceAddr, FT6206_CHIP_ID_REG));
+}
+
+/**
+ * @brief Configures the touch Screen IC device to start detecting touches
+ * It goes through an internal calibration process (Hw calibration sequence of
+ * the touch screen).
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address).
+ * @retval None.
+ */
+void ft6x06_TS_Start(uint16_t DeviceAddr)
+{
+#if (TS_AUTO_CALIBRATION_SUPPORTED == 1)
+ /* Hw Calibration sequence start : should be done once after each power up */
+ /* This is called internal calibration of the touch screen */
+ ft6x06_TS_Calibration(DeviceAddr);
+#endif
+ /* Minimum static configuration of FT6206 */
+ ft6x06_TS_Configure(DeviceAddr);
+
+ /* By default set FT6206 IC in Polling mode : no INT generation on FT6206 for new touch available */
+ /* Note TS_INT is active low */
+ ft6x06_TS_DisableIT(DeviceAddr);
+}
+
+/**
+ * @brief Return if there is touches detected or not.
+ * Try to detect new touches and forget the old ones (reset internal global
+ * variables).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval : Number of active touches detected (can be 0, 1 or 2).
+ */
+uint8_t ft6x06_TS_DetectTouch(uint16_t DeviceAddr)
+{
+ volatile uint8_t nbTouch = 0;
+
+ /* Read register FT6206_TD_STAT_REG to check number of touches detection */
+ nbTouch = TS_IO_Read(DeviceAddr, FT6206_TD_STAT_REG);
+ nbTouch &= FT6206_TD_STAT_MASK;
+
+ if(nbTouch > FT6206_MAX_DETECTABLE_TOUCH)
+ {
+ /* If invalid number of touch detected, set it to zero */
+ nbTouch = 0;
+ }
+
+ /* Update ft6x06 driver internal global : current number of active touches */
+ ft6x06_handle.currActiveTouchNb = nbTouch;
+
+ /* Reset current active touch index on which to work on */
+ ft6x06_handle.currActiveTouchIdx = 0;
+
+ return(nbTouch);
+}
+
+/**
+ * @brief Get the touch screen X and Y positions values
+ * Manage multi touch thanks to touch Index global
+ * variable 'ft6x06_handle.currActiveTouchIdx'.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param X: Pointer to X position value
+ * @param Y: Pointer to Y position value
+ * @retval None.
+ */
+void ft6x06_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y)
+{
+ uint8_t regAddress = 0;
+ uint8_t dataxy[4];
+
+ if(ft6x06_handle.currActiveTouchIdx < ft6x06_handle.currActiveTouchNb)
+ {
+ switch(ft6x06_handle.currActiveTouchIdx)
+ {
+ case 0 :
+ regAddress = FT6206_P1_XH_REG;
+ break;
+ case 1 :
+ regAddress = FT6206_P2_XH_REG;
+ break;
+
+ default :
+ break;
+ }
+
+ /* Read X and Y positions */
+ TS_IO_ReadMultiple(DeviceAddr, regAddress, dataxy, sizeof(dataxy));
+
+ /* Send back ready X position to caller */
+ *X = ((dataxy[0] & FT6206_MSB_MASK) << 8) | (dataxy[1] & FT6206_LSB_MASK);
+
+ /* Send back ready Y position to caller */
+ *Y = ((dataxy[2] & FT6206_MSB_MASK) << 8) | (dataxy[3] & FT6206_LSB_MASK);
+
+ ft6x06_handle.currActiveTouchIdx++;
+ }
+}
+
+/**
+ * @brief Configure the FT6206 device to generate IT on given INT pin
+ * connected to MCU as EXTI.
+ * @param DeviceAddr: Device address on communication Bus (Slave I2C address of FT6206).
+ * @retval None
+ */
+void ft6x06_TS_EnableIT(uint16_t DeviceAddr)
+{
+ uint8_t regValue = 0;
+ regValue = (FT6206_G_MODE_INTERRUPT_TRIGGER & (FT6206_G_MODE_INTERRUPT_MASK >> FT6206_G_MODE_INTERRUPT_SHIFT)) << FT6206_G_MODE_INTERRUPT_SHIFT;
+
+ /* Set interrupt trigger mode in FT6206_GMODE_REG */
+ TS_IO_Write(DeviceAddr, FT6206_GMODE_REG, regValue);
+}
+
+/**
+ * @brief Configure the FT6206 device to stop generating IT on the given INT pin
+ * connected to MCU as EXTI.
+ * @param DeviceAddr: Device address on communication Bus (Slave I2C address of FT6206).
+ * @retval None
+ */
+void ft6x06_TS_DisableIT(uint16_t DeviceAddr)
+{
+ uint8_t regValue = 0;
+ regValue = (FT6206_G_MODE_INTERRUPT_POLLING & (FT6206_G_MODE_INTERRUPT_MASK >> FT6206_G_MODE_INTERRUPT_SHIFT)) << FT6206_G_MODE_INTERRUPT_SHIFT;
+
+ /* Set interrupt polling mode in FT6206_GMODE_REG */
+ TS_IO_Write(DeviceAddr, FT6206_GMODE_REG, regValue);
+}
+
+/**
+ * @brief Get IT status from FT6206 interrupt status registers
+ * Should be called Following an EXTI coming to the MCU to know the detailed
+ * reason of the interrupt.
+ * @note : This feature is not applicable to FT6206.
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval TS interrupts status : always return 0 here
+ */
+uint8_t ft6x06_TS_ITStatus(uint16_t DeviceAddr)
+{
+ /* Always return 0 as feature not applicable to FT6206 */
+ return 0;
+}
+
+/**
+ * @brief Clear IT status in FT6206 interrupt status clear registers
+ * Should be called Following an EXTI coming to the MCU.
+ * @note : This feature is not applicable to FT6206.
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval None
+ */
+void ft6x06_TS_ClearIT(uint16_t DeviceAddr)
+{
+ /* Nothing to be done here for FT6206 */
+}
+
+/**** NEW FEATURES enabled when Multi-touch support is enabled ****/
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+
+/**
+ * @brief Get the last touch gesture identification (zoom, move up/down...).
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6x06).
+ * @param pGestureId : Pointer to get last touch gesture Identification.
+ * @retval None.
+ */
+void ft6x06_TS_GetGestureID(uint16_t DeviceAddr, uint32_t * pGestureId)
+{
+ volatile uint8_t ucReadData = 0;
+
+ ucReadData = TS_IO_Read(DeviceAddr, FT6206_GEST_ID_REG);
+
+ * pGestureId = ucReadData;
+}
+
+/**
+ * @brief Get the touch detailed informations on touch number 'touchIdx' (0..1)
+ * This touch detailed information contains :
+ * - weight that was applied to this touch
+ * - sub-area of the touch in the touch panel
+ * - event of linked to the touch (press down, lift up, ...)
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6x06).
+ * @param touchIdx : Passed index of the touch (0..1) on which we want to get the
+ * detailed information.
+ * @param pWeight : Pointer to to get the weight information of 'touchIdx'.
+ * @param pArea : Pointer to to get the sub-area information of 'touchIdx'.
+ * @param pEvent : Pointer to to get the event information of 'touchIdx'.
+
+ * @retval None.
+ */
+void ft6x06_TS_GetTouchInfo(uint16_t DeviceAddr,
+ uint32_t touchIdx,
+ uint32_t * pWeight,
+ uint32_t * pArea,
+ uint32_t * pEvent)
+{
+ uint8_t regAddress = 0;
+ uint8_t dataxy[3];
+
+ if(touchIdx < ft6x06_handle.currActiveTouchNb)
+ {
+ switch(touchIdx)
+ {
+ case 0 :
+ regAddress = FT6206_P1_WEIGHT_REG;
+ break;
+
+ case 1 :
+ regAddress = FT6206_P2_WEIGHT_REG;
+ break;
+
+ default :
+ break;
+
+ } /* end switch(touchIdx) */
+
+ /* Read weight, area and Event Id of touch index */
+ TS_IO_ReadMultiple(DeviceAddr, regAddress, dataxy, sizeof(dataxy));
+
+ /* Return weight of touch index */
+ * pWeight = (dataxy[0] & FT6206_TOUCH_WEIGHT_MASK) >> FT6206_TOUCH_WEIGHT_SHIFT;
+ /* Return area of touch index */
+ * pArea = (dataxy[1] & FT6206_TOUCH_AREA_MASK) >> FT6206_TOUCH_AREA_SHIFT;
+ /* Return Event Id of touch index */
+ * pEvent = (dataxy[2] & FT6206_TOUCH_EVT_FLAG_MASK) >> FT6206_TOUCH_EVT_FLAG_SHIFT;
+
+ } /* of if(touchIdx < ft6x06_handle.currActiveTouchNb) */
+}
+
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+#if (TS_AUTO_CALIBRATION_SUPPORTED == 1)
+/**
+ * @brief Start TouchScreen calibration phase
+ * @param DeviceAddr: FT6206 Device address for communication on I2C Bus.
+ * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK.
+ */
+static uint32_t ft6x06_TS_Calibration(uint16_t DeviceAddr)
+{
+ uint32_t nbAttempt = 0;
+ volatile uint8_t ucReadData;
+ volatile uint8_t regValue;
+ uint32_t status = FT6206_STATUS_OK;
+ uint8_t bEndCalibration = 0;
+
+ /* >> Calibration sequence start */
+
+ /* Switch FT6206 back to factory mode to calibrate */
+ regValue = (FT6206_DEV_MODE_FACTORY & FT6206_DEV_MODE_MASK) << FT6206_DEV_MODE_SHIFT;
+ TS_IO_Write(DeviceAddr, FT6206_DEV_MODE_REG, regValue); /* 0x40 */
+
+ /* Read back the same register FT6206_DEV_MODE_REG */
+ ucReadData = TS_IO_Read(DeviceAddr, FT6206_DEV_MODE_REG);
+ TS_IO_Delay(300); /* Wait 300 ms */
+
+ if(((ucReadData & (FT6206_DEV_MODE_MASK << FT6206_DEV_MODE_SHIFT)) >> FT6206_DEV_MODE_SHIFT) != FT6206_DEV_MODE_FACTORY )
+ {
+ /* Return error to caller */
+ return(FT6206_STATUS_NOT_OK);
+ }
+
+ /* Start calibration command */
+ TS_IO_Write(DeviceAddr, FT6206_TD_STAT_REG, 0x04);
+ TS_IO_Delay(300); /* Wait 300 ms */
+
+ /* 100 attempts to wait switch from factory mode (calibration) to working mode */
+ for (nbAttempt=0; ((nbAttempt < 100) && (!bEndCalibration)) ; nbAttempt++)
+ {
+ ucReadData = TS_IO_Read(DeviceAddr, FT6206_DEV_MODE_REG);
+ ucReadData = (ucReadData & (FT6206_DEV_MODE_MASK << FT6206_DEV_MODE_SHIFT)) >> FT6206_DEV_MODE_SHIFT;
+ if(ucReadData == FT6206_DEV_MODE_WORKING)
+ {
+ /* Auto Switch to FT6206_DEV_MODE_WORKING : means calibration have ended */
+ bEndCalibration = 1; /* exit for loop */
+ }
+
+ TS_IO_Delay(200); /* Wait 200 ms */
+ }
+
+ /* Calibration sequence end << */
+
+ return(status);
+}
+#endif /* TS_AUTO_CALIBRATION_SUPPORTED == 1 */
+
+/**
+ * @brief Basic static configuration of TouchScreen
+ * @param DeviceAddr: FT6206 Device address for communication on I2C Bus.
+ * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK.
+ */
+static uint32_t ft6x06_TS_Configure(uint16_t DeviceAddr)
+{
+ uint32_t status = FT6206_STATUS_OK;
+
+ /* Nothing special to be done for FT6206 */
+
+ return(status);
+}
+
+/**
+ * @brief Check if the device instance of the selected address is already registered
+ * and return its index
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Index of the device instance if registered, 0xFF if not.
+ */
+static uint8_t ft6x06_GetInstance(uint16_t DeviceAddr)
+{
+ uint8_t idx = 0;
+
+ /* Check all the registered instances */
+ for(idx = 0; idx < FT6x06_MAX_INSTANCE ; idx ++)
+ {
+ if(ft6x06[idx] == DeviceAddr)
+ {
+ return idx;
+ }
+ }
+
+ return 0xFF;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/ft6x06/ft6x06.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,467 @@
+/**
+ ******************************************************************************
+ * @file ft6x06.h
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 03-August-2015
+ * @brief This file contains all the functions prototypes for the
+ * ft6x06.c IO expander driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __FT6X06_H
+#define __FT6X06_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Set Multi-touch as non supported */
+#ifndef TS_MULTI_TOUCH_SUPPORTED
+ #define TS_MULTI_TOUCH_SUPPORTED 0
+#endif
+
+/* Set Auto-calibration as non supported */
+#ifndef TS_AUTO_CALIBRATION_SUPPORTED
+ #define TS_AUTO_CALIBRATION_SUPPORTED 0
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "../Common/ts.h"
+
+/* Macros --------------------------------------------------------------------*/
+
+/** @typedef ft6x06_handle_TypeDef
+ * ft6x06 Handle definition.
+ */
+typedef struct
+{
+ uint8_t i2cInitialized;
+
+ /* field holding the current number of simultaneous active touches */
+ uint8_t currActiveTouchNb;
+
+ /* field holding the touch index currently managed */
+ uint8_t currActiveTouchIdx;
+
+} ft6x06_handle_TypeDef;
+
+ /** @addtogroup BSP
+ * @{
+ */
+
+ /** @addtogroup Component
+ * @{
+ */
+
+ /** @defgroup FT6X06
+ * @{
+ */
+
+ /* Exported types ------------------------------------------------------------*/
+
+ /** @defgroup FT6X06_Exported_Types
+ * @{
+ */
+
+ /* Exported constants --------------------------------------------------------*/
+
+ /** @defgroup FT6X06_Exported_Constants
+ * @{
+ */
+
+ /* Maximum border values of the touchscreen pad */
+#define FT_6206_MAX_WIDTH ((uint16_t)800) /* Touchscreen pad max width */
+#define FT_6206_MAX_HEIGHT ((uint16_t)480) /* Touchscreen pad max height */
+
+ /* Possible values of driver functions return status */
+#define FT6206_STATUS_OK 0
+#define FT6206_STATUS_NOT_OK 1
+
+ /* Possible values of global variable 'TS_I2C_Initialized' */
+#define FT6206_I2C_NOT_INITIALIZED 0
+#define FT6206_I2C_INITIALIZED 1
+
+ /* Max detectable simultaneous touches */
+#define FT6206_MAX_DETECTABLE_TOUCH 2
+
+ /**
+ * @brief : Definitions for FT6206 I2C register addresses on 8 bit
+ **/
+
+ /* Current mode register of the FT6206 (R/W) */
+#define FT6206_DEV_MODE_REG 0x00
+
+ /* Possible values of FT6206_DEV_MODE_REG */
+#define FT6206_DEV_MODE_WORKING 0x00
+#define FT6206_DEV_MODE_FACTORY 0x04
+
+#define FT6206_DEV_MODE_MASK 0x7
+#define FT6206_DEV_MODE_SHIFT 4
+
+ /* Gesture ID register */
+#define FT6206_GEST_ID_REG 0x01
+
+ /* Possible values of FT6206_GEST_ID_REG */
+#define FT6206_GEST_ID_NO_GESTURE 0x00
+#define FT6206_GEST_ID_MOVE_UP 0x10
+#define FT6206_GEST_ID_MOVE_RIGHT 0x14
+#define FT6206_GEST_ID_MOVE_DOWN 0x18
+#define FT6206_GEST_ID_MOVE_LEFT 0x1C
+#define FT6206_GEST_ID_ZOOM_IN 0x48
+#define FT6206_GEST_ID_ZOOM_OUT 0x49
+
+ /* Touch Data Status register : gives number of active touch points (0..2) */
+#define FT6206_TD_STAT_REG 0x02
+
+ /* Values related to FT6206_TD_STAT_REG */
+#define FT6206_TD_STAT_MASK 0x0F
+#define FT6206_TD_STAT_SHIFT 0x00
+
+ /* Values Pn_XH and Pn_YH related */
+#define FT6206_TOUCH_EVT_FLAG_PRESS_DOWN 0x00
+#define FT6206_TOUCH_EVT_FLAG_LIFT_UP 0x01
+#define FT6206_TOUCH_EVT_FLAG_CONTACT 0x02
+#define FT6206_TOUCH_EVT_FLAG_NO_EVENT 0x03
+
+#define FT6206_TOUCH_EVT_FLAG_SHIFT 6
+#define FT6206_TOUCH_EVT_FLAG_MASK (3 << FT6206_TOUCH_EVT_FLAG_SHIFT)
+
+#define FT6206_MSB_MASK 0x0F
+#define FT6206_MSB_SHIFT 0
+
+ /* Values Pn_XL and Pn_YL related */
+#define FT6206_LSB_MASK 0xFF
+#define FT6206_LSB_SHIFT 0
+
+#define FT6206_P1_XH_REG 0x03
+#define FT6206_P1_XL_REG 0x04
+#define FT6206_P1_YH_REG 0x05
+#define FT6206_P1_YL_REG 0x06
+
+ /* Touch Pressure register value (R) */
+#define FT6206_P1_WEIGHT_REG 0x07
+
+ /* Values Pn_WEIGHT related */
+#define FT6206_TOUCH_WEIGHT_MASK 0xFF
+#define FT6206_TOUCH_WEIGHT_SHIFT 0
+
+ /* Touch area register */
+#define FT6206_P1_MISC_REG 0x08
+
+ /* Values related to FT6206_Pn_MISC_REG */
+#define FT6206_TOUCH_AREA_MASK (0x04 << 4)
+#define FT6206_TOUCH_AREA_SHIFT 0x04
+
+#define FT6206_P2_XH_REG 0x09
+#define FT6206_P2_XL_REG 0x0A
+#define FT6206_P2_YH_REG 0x0B
+#define FT6206_P2_YL_REG 0x0C
+#define FT6206_P2_WEIGHT_REG 0x0D
+#define FT6206_P2_MISC_REG 0x0E
+
+ /* Threshold for touch detection */
+#define FT6206_TH_GROUP_REG 0x80
+
+ /* Values FT6206_TH_GROUP_REG : threshold related */
+#define FT6206_THRESHOLD_MASK 0xFF
+#define FT6206_THRESHOLD_SHIFT 0
+
+ /* Filter function coefficients */
+#define FT6206_TH_DIFF_REG 0x85
+
+ /* Control register */
+#define FT6206_CTRL_REG 0x86
+
+ /* Values related to FT6206_CTRL_REG */
+
+ /* Will keep the Active mode when there is no touching */
+#define FT6206_CTRL_KEEP_ACTIVE_MODE 0x00
+
+ /* Switching from Active mode to Monitor mode automatically when there is no touching */
+#define FT6206_CTRL_KEEP_AUTO_SWITCH_MONITOR_MODE 0x01
+
+ /* The time period of switching from Active mode to Monitor mode when there is no touching */
+#define FT6206_TIMEENTERMONITOR_REG 0x87
+
+ /* Report rate in Active mode */
+#define FT6206_PERIODACTIVE_REG 0x88
+
+ /* Report rate in Monitor mode */
+#define FT6206_PERIODMONITOR_REG 0x89
+
+ /* The value of the minimum allowed angle while Rotating gesture mode */
+#define FT6206_RADIAN_VALUE_REG 0x91
+
+ /* Maximum offset while Moving Left and Moving Right gesture */
+#define FT6206_OFFSET_LEFT_RIGHT_REG 0x92
+
+ /* Maximum offset while Moving Up and Moving Down gesture */
+#define FT6206_OFFSET_UP_DOWN_REG 0x93
+
+ /* Minimum distance while Moving Left and Moving Right gesture */
+#define FT6206_DISTANCE_LEFT_RIGHT_REG 0x94
+
+ /* Minimum distance while Moving Up and Moving Down gesture */
+#define FT6206_DISTANCE_UP_DOWN_REG 0x95
+
+ /* Maximum distance while Zoom In and Zoom Out gesture */
+#define FT6206_DISTANCE_ZOOM_REG 0x96
+
+ /* High 8-bit of LIB Version info */
+#define FT6206_LIB_VER_H_REG 0xA1
+
+ /* Low 8-bit of LIB Version info */
+#define FT6206_LIB_VER_L_REG 0xA2
+
+ /* Chip Selecting */
+#define FT6206_CIPHER_REG 0xA3
+
+ /* Interrupt mode register (used when in interrupt mode) */
+#define FT6206_GMODE_REG 0xA4
+
+#define FT6206_G_MODE_INTERRUPT_MASK 0x03
+#define FT6206_G_MODE_INTERRUPT_SHIFT 0x00
+
+ /* Possible values of FT6206_GMODE_REG */
+#define FT6206_G_MODE_INTERRUPT_POLLING 0x00
+#define FT6206_G_MODE_INTERRUPT_TRIGGER 0x01
+
+ /* Current power mode the FT6206 system is in (R) */
+#define FT6206_PWR_MODE_REG 0xA5
+
+ /* FT6206 firmware version */
+#define FT6206_FIRMID_REG 0xA6
+
+ /* FT6206 Chip identification register */
+#define FT6206_CHIP_ID_REG 0xA8
+
+ /* Possible values of FT6206_CHIP_ID_REG */
+#define FT6206_ID_VALUE 0x11
+
+ /* Release code version */
+#define FT6206_RELEASE_CODE_ID_REG 0xAF
+
+ /* Current operating mode the FT6206 system is in (R) */
+#define FT6206_STATE_REG 0xBC
+
+ /**
+ * @}
+ */
+
+ /* Exported macro ------------------------------------------------------------*/
+
+ /** @defgroup ft6x06_Exported_Macros
+ * @{
+ */
+
+ /* Exported functions --------------------------------------------------------*/
+
+ /** @defgroup ft6x06_Exported_Functions
+ * @{
+ */
+
+ /**
+ * @brief ft6x06 Control functions
+ */
+
+
+/**
+ * @brief Initialize the ft6x06 communication bus
+ * from MCU to FT6206 : ie I2C channel initialization (if required).
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval None
+ */
+void ft6x06_Init(uint16_t DeviceAddr);
+
+/**
+ * @brief Software Reset the ft6x06.
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval None
+ */
+void ft6x06_Reset(uint16_t DeviceAddr);
+
+/**
+ * @brief Read the ft6x06 device ID, pre intitalize I2C in case of need to be
+ * able to read the FT6206 device ID, and verify this is a FT6206.
+ * @param DeviceAddr: I2C FT6x06 Slave address.
+ * @retval The Device ID (two bytes).
+ */
+uint16_t ft6x06_ReadID(uint16_t DeviceAddr);
+
+/**
+ * @brief Configures the touch Screen IC device to start detecting touches
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address).
+ * @retval None.
+ */
+void ft6x06_TS_Start(uint16_t DeviceAddr);
+
+/**
+ * @brief Return if there is touches detected or not.
+ * Try to detect new touches and forget the old ones (reset internal global
+ * variables).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval : Number of active touches detected (can be 0, 1 or 2).
+ */
+uint8_t ft6x06_TS_DetectTouch(uint16_t DeviceAddr);
+
+/**
+ * @brief Get the touch screen X and Y positions values
+ * Manage multi touch thanks to touch Index global
+ * variable 'ft6x06_handle.currActiveTouchIdx'.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param X: Pointer to X position value
+ * @param Y: Pointer to Y position value
+ * @retval None.
+ */
+void ft6x06_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y);
+
+/**
+ * @brief Configure the FT6206 device to generate IT on given INT pin
+ * connected to MCU as EXTI.
+ * @param DeviceAddr: Device address on communication Bus (Slave I2C address of FT6206).
+ * @retval None
+ */
+void ft6x06_TS_EnableIT(uint16_t DeviceAddr);
+
+/**
+ * @brief Configure the FT6206 device to stop generating IT on the given INT pin
+ * connected to MCU as EXTI.
+ * @param DeviceAddr: Device address on communication Bus (Slave I2C address of FT6206).
+ * @retval None
+ */
+void ft6x06_TS_DisableIT(uint16_t DeviceAddr);
+
+/**
+ * @brief Get IT status from FT6206 interrupt status registers
+ * Should be called Following an EXTI coming to the MCU to know the detailed
+ * reason of the interrupt.
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval TS interrupts status
+ */
+uint8_t ft6x06_TS_ITStatus (uint16_t DeviceAddr);
+
+/**
+ * @brief Clear IT status in FT6206 interrupt status clear registers
+ * Should be called Following an EXTI coming to the MCU.
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206).
+ * @retval TS interrupts status
+ */
+void ft6x06_TS_ClearIT (uint16_t DeviceAddr);
+
+/**** NEW FEATURES enabled when Multi-touch support is enabled ****/
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+
+/**
+ * @brief Get the last touch gesture identification (zoom, move up/down...).
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6x06).
+ * @param pGestureId : Pointer to get last touch gesture Identification.
+ * @retval None.
+ */
+void ft6x06_TS_GetGestureID(uint16_t DeviceAddr, uint32_t * pGestureId);
+
+/**
+ * @brief Get the touch detailed informations on touch number 'touchIdx' (0..1)
+ * This touch detailed information contains :
+ * - weight that was applied to this touch
+ * - sub-area of the touch in the touch panel
+ * - event of linked to the touch (press down, lift up, ...)
+ * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6x06).
+ * @param touchIdx : Passed index of the touch (0..1) on which we want to get the
+ * detailed information.
+ * @param pWeight : Pointer to to get the weight information of 'touchIdx'.
+ * @param pArea : Pointer to to get the sub-area information of 'touchIdx'.
+ * @param pEvent : Pointer to to get the event information of 'touchIdx'.
+
+ * @retval None.
+ */
+void ft6x06_TS_GetTouchInfo(uint16_t DeviceAddr,
+ uint32_t touchIdx,
+ uint32_t * pWeight,
+ uint32_t * pArea,
+ uint32_t * pEvent);
+
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+/* Imported TS IO functions --------------------------------------------------------*/
+
+/** @defgroup ft6x06_Imported_Functions
+ * @{
+ */
+
+/* TouchScreen (TS) external IO functions */
+extern void TS_IO_Init(void);
+extern void TS_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value);
+extern uint8_t TS_IO_Read(uint8_t Addr, uint8_t Reg);
+extern uint16_t TS_IO_ReadMultiple(uint8_t Addr, uint8_t Reg, uint8_t *Buffer, uint16_t Length);
+extern void TS_IO_Delay(uint32_t Delay);
+
+ /**
+ * @}
+ */
+
+ /* Imported global variables --------------------------------------------------------*/
+
+ /** @defgroup ft6x06_Imported_Globals
+ * @{
+ */
+
+
+/* Touch screen driver structure */
+extern TS_DrvTypeDef ft6x06_ts_drv;
+
+ /**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __FT6X06_H */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/mt25tl01g/mt25tl01g.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,265 @@
+/**
+ ******************************************************************************
+ * @file MT25TL01G.h
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 08-August-2016
+ * @brief This file contains all the description of the MT25TL01G QSPI memory.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MT25TL01G_H
+#define __MT25TL01G_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup MT25TL01G
+ * @{
+ */
+
+/** @defgroup MT25TL01G_Exported_Types
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup MT25TL01G_Exported_Constants
+ * @{
+ */
+
+/**
+ * @brief MT25TL01G Configuration
+ */
+#define MT25TL01G_FLASH_SIZE 0x8000000 /* 2 * 512 MBits => 2 * 64MBytes => 128MBytes*/
+#define MT25TL01G_SECTOR_SIZE 0x10000 /* 2 * 1024 sectors of 64KBytes */
+#define MT25TL01G_SUBSECTOR_SIZE 0x1000 /* 2 * 16384 subsectors of 4kBytes */
+#define MT25TL01G_PAGE_SIZE 0x100 /* 2 * 262144 pages of 256 bytes */
+
+#define MT25TL01G_DUMMY_CYCLES_READ_QUAD 8
+#define MT25TL01G_DUMMY_CYCLES_READ 8
+#define MT25TL01G_DUMMY_CYCLES_READ_DTR 6
+#define MT25TL01G_DUMMY_CYCLES_READ_QUAD_DTR 6
+
+#define MT25TL01G_DIE_ERASE_MAX_TIME 460000
+#define MT25TL01G_SECTOR_ERASE_MAX_TIME 1000
+#define MT25TL01G_SUBSECTOR_ERASE_MAX_TIME 400
+
+/**
+ * @brief MT25TL01G Commands
+ */
+/* Reset Operations */
+#define RESET_ENABLE_CMD 0x66
+#define RESET_MEMORY_CMD 0x99
+
+/* Identification Operations */
+#define READ_ID_CMD 0x9E
+#define READ_ID_CMD2 0x9F
+#define MULTIPLE_IO_READ_ID_CMD 0xAF
+#define READ_SERIAL_FLASH_DISCO_PARAM_CMD 0x5A
+
+/* Read Operations */
+#define READ_CMD 0x03
+#define READ_4_BYTE_ADDR_CMD 0x13
+
+#define FAST_READ_CMD 0x0B
+#define FAST_READ_DTR_CMD 0x0D
+#define FAST_READ_4_BYTE_ADDR_CMD 0x0C
+
+#define DUAL_OUT_FAST_READ_CMD 0x3B
+#define DUAL_OUT_FAST_READ_DTR_CMD 0x3D
+#define DUAL_OUT_FAST_READ_4_BYTE_ADDR_CMD 0x3C
+
+#define DUAL_INOUT_FAST_READ_CMD 0xBB
+#define DUAL_INOUT_FAST_READ_DTR_CMD 0xBD
+#define DUAL_INOUT_FAST_READ_4_BYTE_ADDR_CMD 0xBC
+
+#define QUAD_OUT_FAST_READ_CMD 0x6B
+#define QUAD_OUT_FAST_READ_DTR_CMD 0x6D
+#define QUAD_OUT_FAST_READ_4_BYTE_ADDR_CMD 0x6C
+
+#define QUAD_INOUT_FAST_READ_CMD 0xEB
+#define QUAD_INOUT_FAST_READ_DTR_CMD 0xED
+#define QUAD_INOUT_FAST_READ_4_BYTE_ADDR_CMD 0xEC
+
+/* Write Operations */
+#define WRITE_ENABLE_CMD 0x06
+#define WRITE_DISABLE_CMD 0x04
+
+/* Register Operations */
+#define READ_STATUS_REG_CMD 0x05
+#define WRITE_STATUS_REG_CMD 0x01
+
+#define READ_LOCK_REG_CMD 0xE8
+#define WRITE_LOCK_REG_CMD 0xE5
+
+#define READ_FLAG_STATUS_REG_CMD 0x70
+#define CLEAR_FLAG_STATUS_REG_CMD 0x50
+
+#define READ_NONVOL_CFG_REG_CMD 0xB5
+#define WRITE_NONVOL_CFG_REG_CMD 0xB1
+
+#define READ_VOL_CFG_REG_CMD 0x85
+#define WRITE_VOL_CFG_REG_CMD 0x81
+
+#define READ_ENHANCED_VOL_CFG_REG_CMD 0x65
+#define WRITE_ENHANCED_VOL_CFG_REG_CMD 0x61
+
+#define READ_EXT_ADDR_REG_CMD 0xC8
+#define WRITE_EXT_ADDR_REG_CMD 0xC5
+
+/* Program Operations */
+#define PAGE_PROG_CMD 0x02
+#define PAGE_PROG_4_BYTE_ADDR_CMD 0x12
+
+#define DUAL_IN_FAST_PROG_CMD 0xA2
+#define EXT_DUAL_IN_FAST_PROG_CMD 0xD2
+
+#define QUAD_IN_FAST_PROG_CMD 0x32
+#define EXT_QUAD_IN_FAST_PROG_CMD 0x38
+#define QUAD_IN_FAST_PROG_4_BYTE_ADDR_CMD 0x34
+
+/* Erase Operations */
+#define SUBSECTOR_ERASE_CMD 0x20
+#define SUBSECTOR_ERASE_4_BYTE_ADDR_CMD 0x21
+
+#define SECTOR_ERASE_CMD 0xD8
+#define SECTOR_ERASE_4_BYTE_ADDR_CMD 0xDC
+
+#define DIE_ERASE_CMD 0xC4
+
+#define PROG_ERASE_RESUME_CMD 0x7A
+#define PROG_ERASE_SUSPEND_CMD 0x75
+
+/* One-Time Programmable Operations */
+#define READ_OTP_ARRAY_CMD 0x4B
+#define PROG_OTP_ARRAY_CMD 0x42
+
+/* 4-byte Address Mode Operations */
+#define ENTER_4_BYTE_ADDR_MODE_CMD 0xB7
+#define EXIT_4_BYTE_ADDR_MODE_CMD 0xE9
+
+/* Quad Operations */
+#define ENTER_QUAD_CMD 0x35
+#define EXIT_QUAD_CMD 0xF5
+
+/**
+ * @brief MT25TL01G Registers
+ */
+/* Status Register */
+#define MT25TL01G_SR_WIP ((uint8_t)0x01) /*!< Write in progress */
+#define MT25TL01G_SR_WREN ((uint8_t)0x02) /*!< Write enable latch */
+#define MT25TL01G_SR_BLOCKPR ((uint8_t)0x5C) /*!< Block protected against program and erase operations */
+#define MT25TL01G_SR_PRBOTTOM ((uint8_t)0x20) /*!< Protected memory area defined by BLOCKPR starts from top or bottom */
+#define MT25TL01G_SR_SRWREN ((uint8_t)0x80) /*!< Status register write enable/disable */
+
+/* Non volatile Configuration Register */
+#define MT25TL01G_NVCR_NBADDR ((uint16_t)0x0001) /*!< 3-bytes or 4-bytes addressing */
+#define MT25TL01G_NVCR_SEGMENT ((uint16_t)0x0002) /*!< Upper or lower 128Mb segment selected by default */
+#define MT25TL01G_NVCR_DUAL ((uint16_t)0x0004) /*!< Dual I/O protocol */
+#define MT25TL01G_NVCR_QUAB ((uint16_t)0x0008) /*!< Quad I/O protocol */
+#define MT25TL01G_NVCR_RH ((uint16_t)0x0010) /*!< Reset/hold */
+#define MT25TL01G_NVCR_DTRP ((uint16_t)0x0020) /*!< Double transfer rate protocol */
+#define MT25TL01G_NVCR_ODS ((uint16_t)0x01C0) /*!< Output driver strength */
+#define MT25TL01G_NVCR_XIP ((uint16_t)0x0E00) /*!< XIP mode at power-on reset */
+#define MT25TL01G_NVCR_NB_DUMMY ((uint16_t)0xF000) /*!< Number of dummy clock cycles */
+
+/* Volatile Configuration Register */
+#define MT25TL01G_VCR_WRAP ((uint8_t)0x03) /*!< Wrap */
+#define MT25TL01G_VCR_XIP ((uint8_t)0x08) /*!< XIP */
+#define MT25TL01G_VCR_NB_DUMMY ((uint8_t)0xF0) /*!< Number of dummy clock cycles */
+
+/* Extended Address Register */
+#define MT25TL01G_EAR_HIGHEST_SE ((uint8_t)0x03) /*!< Select the Highest 128Mb segment */
+#define MT25TL01G_EAR_THIRD_SEG ((uint8_t)0x02) /*!< Select the Third 128Mb segment */
+#define MT25TL01G_EAR_SECOND_SEG ((uint8_t)0x01) /*!< Select the Second 128Mb segment */
+#define MT25TL01G_EAR_LOWEST_SEG ((uint8_t)0x00) /*!< Select the Lowest 128Mb segment (default) */
+
+/* Enhanced Volatile Configuration Register */
+#define MT25TL01G_EVCR_ODS ((uint8_t)0x07) /*!< Output driver strength */
+#define MT25TL01G_EVCR_RH ((uint8_t)0x10) /*!< Reset/hold */
+#define MT25TL01G_EVCR_DTRP ((uint8_t)0x20) /*!< Double transfer rate protocol */
+#define MT25TL01G_EVCR_DUAL ((uint8_t)0x40) /*!< Dual I/O protocol */
+#define MT25TL01G_EVCR_QUAD ((uint8_t)0x80) /*!< Quad I/O protocol */
+
+/* Flag Status Register */
+#define MT25TL01G_FSR_NBADDR ((uint8_t)0x01) /*!< 3-bytes or 4-bytes addressing */
+#define MT25TL01G_FSR_PRERR ((uint8_t)0x02) /*!< Protection error */
+#define MT25TL01G_FSR_PGSUS ((uint8_t)0x04) /*!< Program operation suspended */
+#define MT25TL01G_FSR_PGERR ((uint8_t)0x10) /*!< Program error */
+#define MT25TL01G_FSR_ERERR ((uint8_t)0x20) /*!< Erase error */
+#define MT25TL01G_FSR_ERSUS ((uint8_t)0x40) /*!< Erase operation suspended */
+#define MT25TL01G_FSR_READY ((uint8_t)0x80) /*!< Ready or command in progress */
+
+
+/**
+ * @}
+ */
+
+/** @defgroup MT25TL01G_Exported_Functions
+ * @{
+ */
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MT25TL01G_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/otm8009a/otm8009a.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,454 @@
+/**
+ ******************************************************************************
+ * @file otm8009a.c
+ * @author MCD Application Team
+ * @version V1.0.2
+ * @date 27-January-2017
+ * @brief This file provides the LCD Driver for KoD KM-040TMP-02-0621 (WVGA)
+ * DSI LCD Display OTM8009A.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "otm8009a.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @defgroup OTM8009A OTM8009A
+ * @brief This file provides a set of functions needed to drive the
+ * otm8009a IC display driver.
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup OTM8009A_Private_Constants OTM8009A Private Constants
+ * @{
+ */
+
+/*
+ * @brief Constant tables of register settings used to transmit DSI
+ * command packets as power up initialization sequence of the KoD LCD (OTM8009A LCD Driver)
+ */
+const uint8_t lcdRegData1[] = {0x80,0x09,0x01,0xFF};
+const uint8_t lcdRegData2[] = {0x80,0x09,0xFF};
+const uint8_t lcdRegData3[] = {0x00,0x09,0x0F,0x0E,0x07,0x10,0x0B,0x0A,0x04,0x07,0x0B,0x08,0x0F,0x10,0x0A,0x01,0xE1};
+const uint8_t lcdRegData4[] = {0x00,0x09,0x0F,0x0E,0x07,0x10,0x0B,0x0A,0x04,0x07,0x0B,0x08,0x0F,0x10,0x0A,0x01,0xE2};
+const uint8_t lcdRegData5[] = {0x79,0x79,0xD8};
+const uint8_t lcdRegData6[] = {0x00,0x01,0xB3};
+const uint8_t lcdRegData7[] = {0x85,0x01,0x00,0x84,0x01,0x00,0xCE};
+const uint8_t lcdRegData8[] = {0x18,0x04,0x03,0x39,0x00,0x00,0x00,0x18,0x03,0x03,0x3A,0x00,0x00,0x00,0xCE};
+const uint8_t lcdRegData9[] = {0x18,0x02,0x03,0x3B,0x00,0x00,0x00,0x18,0x01,0x03,0x3C,0x00,0x00,0x00,0xCE};
+const uint8_t lcdRegData10[] = {0x01,0x01,0x20,0x20,0x00,0x00,0x01,0x02,0x00,0x00,0xCF};
+const uint8_t lcdRegData11[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
+const uint8_t lcdRegData12[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
+const uint8_t lcdRegData13[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
+const uint8_t lcdRegData14[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
+const uint8_t lcdRegData15[] = {0x00,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
+const uint8_t lcdRegData16[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x00,0x00,0xCB};
+const uint8_t lcdRegData17[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB};
+const uint8_t lcdRegData18[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCB};
+const uint8_t lcdRegData19[] = {0x00,0x26,0x09,0x0B,0x01,0x25,0x00,0x00,0x00,0x00,0xCC};
+const uint8_t lcdRegData20[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x26,0x0A,0x0C,0x02,0xCC};
+const uint8_t lcdRegData21[] = {0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC};
+const uint8_t lcdRegData22[] = {0x00,0x25,0x0C,0x0A,0x02,0x26,0x00,0x00,0x00,0x00,0xCC};
+const uint8_t lcdRegData23[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x0B,0x09,0x01,0xCC};
+const uint8_t lcdRegData24[] = {0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC};
+const uint8_t lcdRegData25[] = {0xFF,0xFF,0xFF,0xFF};
+/*
+ * CASET value (Column Address Set) : X direction LCD GRAM boundaries
+ * depending on LCD orientation mode and PASET value (Page Address Set) : Y direction
+ * LCD GRAM boundaries depending on LCD orientation mode
+ * XS[15:0] = 0x000 = 0, XE[15:0] = 0x31F = 799 for landscape mode : apply to CASET
+ * YS[15:0] = 0x000 = 0, YE[15:0] = 0x31F = 799 for portrait mode : : apply to PASET
+ */
+const uint8_t lcdRegData27[] = {0x00, 0x00, 0x03, 0x1F, OTM8009A_CMD_CASET};
+/*
+ * XS[15:0] = 0x000 = 0, XE[15:0] = 0x1DF = 479 for portrait mode : apply to CASET
+ * YS[15:0] = 0x000 = 0, YE[15:0] = 0x1DF = 479 for landscape mode : apply to PASET
+ */
+const uint8_t lcdRegData28[] = {0x00, 0x00, 0x01, 0xDF, OTM8009A_CMD_PASET};
+
+
+const uint8_t ShortRegData1[] = {OTM8009A_CMD_NOP, 0x00};
+const uint8_t ShortRegData2[] = {OTM8009A_CMD_NOP, 0x80};
+const uint8_t ShortRegData3[] = {0xC4, 0x30};
+const uint8_t ShortRegData4[] = {OTM8009A_CMD_NOP, 0x8A};
+const uint8_t ShortRegData5[] = {0xC4, 0x40};
+const uint8_t ShortRegData6[] = {OTM8009A_CMD_NOP, 0xB1};
+const uint8_t ShortRegData7[] = {0xC5, 0xA9};
+const uint8_t ShortRegData8[] = {OTM8009A_CMD_NOP, 0x91};
+const uint8_t ShortRegData9[] = {0xC5, 0x34};
+const uint8_t ShortRegData10[] = {OTM8009A_CMD_NOP, 0xB4};
+const uint8_t ShortRegData11[] = {0xC0, 0x50};
+const uint8_t ShortRegData12[] = {0xD9, 0x4E};
+const uint8_t ShortRegData13[] = {OTM8009A_CMD_NOP, 0x81};
+const uint8_t ShortRegData14[] = {0xC1, 0x66};
+const uint8_t ShortRegData15[] = {OTM8009A_CMD_NOP, 0xA1};
+const uint8_t ShortRegData16[] = {0xC1, 0x08};
+const uint8_t ShortRegData17[] = {OTM8009A_CMD_NOP, 0x92};
+const uint8_t ShortRegData18[] = {0xC5, 0x01};
+const uint8_t ShortRegData19[] = {OTM8009A_CMD_NOP, 0x95};
+const uint8_t ShortRegData20[] = {OTM8009A_CMD_NOP, 0x94};
+const uint8_t ShortRegData21[] = {0xC5, 0x33};
+const uint8_t ShortRegData22[] = {OTM8009A_CMD_NOP, 0xA3};
+const uint8_t ShortRegData23[] = {0xC0, 0x1B};
+const uint8_t ShortRegData24[] = {OTM8009A_CMD_NOP, 0x82};
+const uint8_t ShortRegData25[] = {0xC5, 0x83};
+const uint8_t ShortRegData26[] = {0xC4, 0x83};
+const uint8_t ShortRegData27[] = {0xC1, 0x0E};
+const uint8_t ShortRegData28[] = {OTM8009A_CMD_NOP, 0xA6};
+const uint8_t ShortRegData29[] = {OTM8009A_CMD_NOP, 0xA0};
+const uint8_t ShortRegData30[] = {OTM8009A_CMD_NOP, 0xB0};
+const uint8_t ShortRegData31[] = {OTM8009A_CMD_NOP, 0xC0};
+const uint8_t ShortRegData32[] = {OTM8009A_CMD_NOP, 0xD0};
+const uint8_t ShortRegData33[] = {OTM8009A_CMD_NOP, 0x90};
+const uint8_t ShortRegData34[] = {OTM8009A_CMD_NOP, 0xE0};
+const uint8_t ShortRegData35[] = {OTM8009A_CMD_NOP, 0xF0};
+const uint8_t ShortRegData36[] = {OTM8009A_CMD_SLPOUT, 0x00};
+const uint8_t ShortRegData37[] = {OTM8009A_CMD_COLMOD, OTM8009A_COLMOD_RGB565};
+const uint8_t ShortRegData38[] = {OTM8009A_CMD_COLMOD, OTM8009A_COLMOD_RGB888};
+const uint8_t ShortRegData39[] = {OTM8009A_CMD_MADCTR, OTM8009A_MADCTR_MODE_LANDSCAPE};
+const uint8_t ShortRegData40[] = {OTM8009A_CMD_WRDISBV, 0x7F};
+const uint8_t ShortRegData41[] = {OTM8009A_CMD_WRCTRLD, 0x2C};
+const uint8_t ShortRegData42[] = {OTM8009A_CMD_WRCABC, 0x02};
+const uint8_t ShortRegData43[] = {OTM8009A_CMD_WRCABCMB, 0xFF};
+const uint8_t ShortRegData44[] = {OTM8009A_CMD_DISPON, 0x00};
+const uint8_t ShortRegData45[] = {OTM8009A_CMD_RAMWR, 0x00};
+const uint8_t ShortRegData46[] = {0xCF, 0x00};
+const uint8_t ShortRegData47[] = {0xC5, 0x66};
+const uint8_t ShortRegData48[] = {OTM8009A_CMD_NOP, 0xB6};
+const uint8_t ShortRegData49[] = {0xF5, 0x06};
+const uint8_t ShortRegData50[] = {OTM8009A_CMD_NOP, 0xB1};
+const uint8_t ShortRegData51[] = {0xC6, 0x06};
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup OTM8009A_Exported_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+/** @defgroup OTM8009A_Exported_Functions OTM8009A Exported Functions
+ * @{
+ */
+
+/**
+ * @brief DSI IO write short/long command.
+ * @note : Can be surcharged by application code implementation of the function.
+ */
+__weak void DSI_IO_WriteCmd(uint32_t NbrParams, uint8_t *pParams)
+{
+ /* NOTE : This function Should not be modified, when it is needed,
+ the DSI_IO_WriteCmd could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Initializes the LCD KoD display part by communication in DSI mode in Video Mode
+ * with IC Display Driver OTM8009A (see IC Driver specification for more information).
+ * @param hdsi_eval : pointer on DSI configuration structure
+ * @param hdsivideo_handle : pointer on DSI video mode configuration structure
+ * @retval Status
+ */
+uint8_t OTM8009A_Init(uint32_t ColorCoding, uint32_t orientation)
+{
+ /* Enable CMD2 to access vendor specific commands */
+ /* Enter in command 2 mode and set EXTC to enable address shift function (0x00) */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData1);
+ DSI_IO_WriteCmd( 3, (uint8_t *)lcdRegData1);
+
+ /* Enter ORISE Command 2 */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData2); /* Shift address to 0x80 */
+ DSI_IO_WriteCmd( 2, (uint8_t *)lcdRegData2);
+
+ /////////////////////////////////////////////////////////////////////
+ /* SD_PCH_CTRL - 0xC480h - 129th parameter - Default 0x00 */
+ /* Set SD_PT */
+ /* -> Source output level during porch and non-display area to GND */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData2);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData3);
+ OTM8009A_IO_Delay(10);
+ /* Not documented */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData4);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData5);
+ OTM8009A_IO_Delay(10);
+ /////////////////////////////////////////////////////////////////////
+
+ /* PWR_CTRL4 - 0xC4B0h - 178th parameter - Default 0xA8 */
+ /* Set gvdd_en_test */
+ /* -> enable GVDD test mode !!! */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData6);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData7);
+
+ /* PWR_CTRL2 - 0xC590h - 146th parameter - Default 0x79 */
+ /* Set pump 4 vgh voltage */
+ /* -> from 15.0v down to 13.0v */
+ /* Set pump 5 vgh voltage */
+ /* -> from -12.0v downto -9.0v */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData8);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData9);
+
+ /* P_DRV_M - 0xC0B4h - 181th parameter - Default 0x00 */
+ /* -> Column inversion */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData10);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData11);
+
+ /* VCOMDC - 0xD900h - 1st parameter - Default 0x39h */
+ /* VCOM Voltage settings */
+ /* -> from -1.0000v downto -1.2625v */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData1);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData12);
+
+ /* Oscillator adjustment for Idle/Normal mode (LPDT only) set to 65Hz (default is 60Hz) */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData13);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData14);
+
+ /* Video mode internal */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData15);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData16);
+
+ /* PWR_CTRL2 - 0xC590h - 147h parameter - Default 0x00 */
+ /* Set pump 4&5 x6 */
+ /* -> ONLY VALID when PUMP4_EN_ASDM_HV = "0" */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData17);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData18);
+
+ /* PWR_CTRL2 - 0xC590h - 150th parameter - Default 0x33h */
+ /* Change pump4 clock ratio */
+ /* -> from 1 line to 1/2 line */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData19);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData9);
+
+ /* GVDD/NGVDD settings */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData1);
+ DSI_IO_WriteCmd( 2, (uint8_t *)lcdRegData5);
+
+ /* PWR_CTRL2 - 0xC590h - 149th parameter - Default 0x33h */
+ /* Rewrite the default value ! */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData20);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData21);
+
+ /* Panel display timing Setting 3 */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData22);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData23);
+
+ /* Power control 1 */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData24);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData25);
+
+ /* Source driver precharge */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData13);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData26);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData15);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData27);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData28);
+ DSI_IO_WriteCmd( 2, (uint8_t *)lcdRegData6);
+
+ /* GOAVST */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData2);
+ DSI_IO_WriteCmd( 6, (uint8_t *)lcdRegData7);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData29);
+ DSI_IO_WriteCmd( 14, (uint8_t *)lcdRegData8);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData30);
+ DSI_IO_WriteCmd( 14, (uint8_t *)lcdRegData9);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData31);
+ DSI_IO_WriteCmd( 10, (uint8_t *)lcdRegData10);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData32);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData46);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData2);
+ DSI_IO_WriteCmd( 10, (uint8_t *)lcdRegData11);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData33);
+ DSI_IO_WriteCmd( 15, (uint8_t *)lcdRegData12);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData29);
+ DSI_IO_WriteCmd( 15, (uint8_t *)lcdRegData13);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData30);
+ DSI_IO_WriteCmd( 10, (uint8_t *)lcdRegData14);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData31);
+ DSI_IO_WriteCmd( 15, (uint8_t *)lcdRegData15);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData32);
+ DSI_IO_WriteCmd( 15, (uint8_t *)lcdRegData16);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData34);
+ DSI_IO_WriteCmd( 10, (uint8_t *)lcdRegData17);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData35);
+ DSI_IO_WriteCmd( 10, (uint8_t *)lcdRegData18);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData2);
+ DSI_IO_WriteCmd( 10, (uint8_t *)lcdRegData19);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData33);
+ DSI_IO_WriteCmd( 15, (uint8_t *)lcdRegData20);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData29);
+ DSI_IO_WriteCmd( 15, (uint8_t *)lcdRegData21);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData30);
+ DSI_IO_WriteCmd( 10, (uint8_t *)lcdRegData22);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData31);
+ DSI_IO_WriteCmd( 15, (uint8_t *)lcdRegData23);
+
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData32);
+ DSI_IO_WriteCmd( 15, (uint8_t *)lcdRegData24);
+
+ /////////////////////////////////////////////////////////////////////////////
+ /* PWR_CTRL1 - 0xc580h - 130th parameter - default 0x00 */
+ /* Pump 1 min and max DM */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData13);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData47);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData48);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData49);
+ /////////////////////////////////////////////////////////////////////////////
+
+ /* CABC LEDPWM frequency adjusted to 19,5kHz */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData50);
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData51);
+
+ /* Exit CMD2 mode */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData1);
+ DSI_IO_WriteCmd( 3, (uint8_t *)lcdRegData25);
+
+ /*************************************************************************** */
+ /* Standard DCS Initialization TO KEEP CAN BE DONE IN HSDT */
+ /*************************************************************************** */
+
+ /* NOP - goes back to DCS std command ? */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData1);
+
+ /* Gamma correction 2.2+ table (HSDT possible) */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData1);
+ DSI_IO_WriteCmd( 16, (uint8_t *)lcdRegData3);
+
+ /* Gamma correction 2.2- table (HSDT possible) */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData1);
+ DSI_IO_WriteCmd( 16, (uint8_t *)lcdRegData4);
+
+ /* Send Sleep Out command to display : no parameter */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData36);
+
+ /* Wait for sleep out exit */
+ OTM8009A_IO_Delay(120);
+
+ switch(ColorCoding)
+ {
+ case OTM8009A_FORMAT_RBG565 :
+ /* Set Pixel color format to RGB565 */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData37);
+ break;
+ case OTM8009A_FORMAT_RGB888 :
+ /* Set Pixel color format to RGB888 */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData38);
+ break;
+ default :
+ break;
+ }
+
+ /* Send command to configure display in landscape orientation mode. By default
+ the orientation mode is portrait */
+ if(orientation == OTM8009A_ORIENTATION_LANDSCAPE)
+ {
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData39);
+ DSI_IO_WriteCmd( 4, (uint8_t *)lcdRegData27);
+ DSI_IO_WriteCmd( 4, (uint8_t *)lcdRegData28);
+ }
+
+ /** CABC : Content Adaptive Backlight Control section start >> */
+ /* Note : defaut is 0 (lowest Brightness), 0xFF is highest Brightness, try 0x7F : intermediate value */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData40);
+
+ /* defaut is 0, try 0x2C - Brightness Control Block, Display Dimming & BackLight on */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData41);
+
+ /* defaut is 0, try 0x02 - image Content based Adaptive Brightness [Still Picture] */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData42);
+
+ /* defaut is 0 (lowest Brightness), 0xFF is highest Brightness */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData43);
+
+ /** CABC : Content Adaptive Backlight Control section end << */
+
+ /* Send Command Display On */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData44);
+
+ /* NOP command */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData1);
+
+ /* Send Command GRAM memory write (no parameters) : this initiates frame write via other DSI commands sent by */
+ /* DSI host from LTDC incoming pixels in video mode */
+ DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData45);
+
+ return 0;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/otm8009a/otm8009a.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,224 @@
+/**
+ ******************************************************************************
+ * @file otm8009a.h
+ * @author MCD Application Team
+ * @version V1.0.2
+ * @date 27-January-2017
+ * @brief This file contains all the constants parameters for the OTM8009A
+ * which is the LCD Driver for KoD KM-040TMP-02-0621 (WVGA)
+ * DSI LCD Display.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __OTM8009A_H
+#define __OTM8009A_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup otm8009a
+ * @{
+ */
+
+/** @addtogroup OTM8009A_Exported_Variables
+ * @{
+ */
+
+#if defined ( __GNUC__ )
+#ifndef __weak
+#define __weak __attribute__((weak))
+#endif /* __weak */
+#endif /* __GNUC__ */
+
+/**
+ * @brief LCD_OrientationTypeDef
+ * Possible values of Display Orientation
+ */
+#define OTM8009A_ORIENTATION_PORTRAIT ((uint32_t)0x00) /* Portrait orientation choice of LCD screen */
+#define OTM8009A_ORIENTATION_LANDSCAPE ((uint32_t)0x01) /* Landscape orientation choice of LCD screen */
+
+/**
+ * @brief Possible values of
+ * pixel data format (ie color coding) transmitted on DSI Data lane in DSI packets
+ */
+#define OTM8009A_FORMAT_RGB888 ((uint32_t)0x00) /* Pixel format chosen is RGB888 : 24 bpp */
+#define OTM8009A_FORMAT_RBG565 ((uint32_t)0x02) /* Pixel format chosen is RGB565 : 16 bpp */
+
+/**
+ * @brief otm8009a_480x800 Size
+ */
+
+/* Width and Height in Portrait mode */
+#define OTM8009A_480X800_WIDTH ((uint16_t)480) /* LCD PIXEL WIDTH */
+#define OTM8009A_480X800_HEIGHT ((uint16_t)800) /* LCD PIXEL HEIGHT */
+
+/* Width and Height in Landscape mode */
+#define OTM8009A_800X480_WIDTH ((uint16_t)800) /* LCD PIXEL WIDTH */
+#define OTM8009A_800X480_HEIGHT ((uint16_t)480) /* LCD PIXEL HEIGHT */
+
+/**
+ * @brief OTM8009A_480X800 Timing parameters for Portrait orientation mode
+ */
+#define OTM8009A_480X800_HSYNC ((uint16_t)2) /* Horizontal synchronization */
+#define OTM8009A_480X800_HBP ((uint16_t)34) /* Horizontal back porch */
+#define OTM8009A_480X800_HFP ((uint16_t)34) /* Horizontal front porch */
+#define OTM8009A_480X800_VSYNC ((uint16_t)1) /* Vertical synchronization */
+#define OTM8009A_480X800_VBP ((uint16_t)15) /* Vertical back porch */
+#define OTM8009A_480X800_VFP ((uint16_t)16) /* Vertical front porch */
+
+/**
+ * @brief OTM8009A_800X480 Timing parameters for Landscape orientation mode
+ * Same values as for Portrait mode in fact.
+ */
+#define OTM8009A_800X480_HSYNC OTM8009A_480X800_VSYNC /* Horizontal synchronization */
+#define OTM8009A_800X480_HBP OTM8009A_480X800_VBP /* Horizontal back porch */
+#define OTM8009A_800X480_HFP OTM8009A_480X800_VFP /* Horizontal front porch */
+#define OTM8009A_800X480_VSYNC OTM8009A_480X800_HSYNC /* Vertical synchronization */
+#define OTM8009A_800X480_VBP OTM8009A_480X800_HBP /* Vertical back porch */
+#define OTM8009A_800X480_VFP OTM8009A_480X800_HFP /* Vertical front porch */
+
+
+/* List of OTM8009A used commands */
+/* Detailed in OTM8009A Data Sheet 'DATA_SHEET_OTM8009A_V0 92.pdf' */
+/* Version of 14 June 2012 */
+#define OTM8009A_CMD_NOP 0x00 /* NOP command */
+#define OTM8009A_CMD_SWRESET 0x01 /* Sw reset command */
+#define OTM8009A_CMD_RDDMADCTL 0x0B /* Read Display MADCTR command : read memory display access ctrl */
+#define OTM8009A_CMD_RDDCOLMOD 0x0C /* Read Display pixel format */
+#define OTM8009A_CMD_SLPIN 0x10 /* Sleep In command */
+#define OTM8009A_CMD_SLPOUT 0x11 /* Sleep Out command */
+#define OTM8009A_CMD_PTLON 0x12 /* Partial mode On command */
+
+#define OTM8009A_CMD_DISPOFF 0x28 /* Display Off command */
+#define OTM8009A_CMD_DISPON 0x29 /* Display On command */
+
+#define OTM8009A_CMD_CASET 0x2A /* Column address set command */
+#define OTM8009A_CMD_PASET 0x2B /* Page address set command */
+
+#define OTM8009A_CMD_RAMWR 0x2C /* Memory (GRAM) write command */
+#define OTM8009A_CMD_RAMRD 0x2E /* Memory (GRAM) read command */
+
+#define OTM8009A_CMD_PLTAR 0x30 /* Partial area command (4 parameters) */
+
+#define OTM8009A_CMD_TEOFF 0x34 /* Tearing Effect Line Off command : command with no parameter */
+
+#define OTM8009A_CMD_TEEON 0x35 /* Tearing Effect Line On command : command with 1 parameter 'TELOM' */
+
+/* Parameter TELOM : Tearing Effect Line Output Mode : possible values */
+#define OTM8009A_TEEON_TELOM_VBLANKING_INFO_ONLY 0x00
+#define OTM8009A_TEEON_TELOM_VBLANKING_AND_HBLANKING_INFO 0x01
+
+#define OTM8009A_CMD_MADCTR 0x36 /* Memory Access write control command */
+
+/* Possible used values of MADCTR */
+#define OTM8009A_MADCTR_MODE_PORTRAIT 0x00
+#define OTM8009A_MADCTR_MODE_LANDSCAPE 0x60 /* MY = 0, MX = 1, MV = 1, ML = 0, RGB = 0 */
+
+#define OTM8009A_CMD_IDMOFF 0x38 /* Idle mode Off command */
+#define OTM8009A_CMD_IDMON 0x39 /* Idle mode On command */
+
+#define OTM8009A_CMD_COLMOD 0x3A /* Interface Pixel format command */
+
+/* Possible values of COLMOD parameter corresponding to used pixel formats */
+#define OTM8009A_COLMOD_RGB565 0x55
+#define OTM8009A_COLMOD_RGB888 0x77
+
+#define OTM8009A_CMD_RAMWRC 0x3C /* Memory write continue command */
+#define OTM8009A_CMD_RAMRDC 0x3E /* Memory read continue command */
+
+#define OTM8009A_CMD_WRTESCN 0x44 /* Write Tearing Effect Scan line command */
+#define OTM8009A_CMD_RDSCNL 0x45 /* Read Tearing Effect Scan line command */
+
+/* CABC Management : ie : Content Adaptive Back light Control in IC OTM8009a */
+#define OTM8009A_CMD_WRDISBV 0x51 /* Write Display Brightness command */
+#define OTM8009A_CMD_WRCTRLD 0x53 /* Write CTRL Display command */
+#define OTM8009A_CMD_WRCABC 0x55 /* Write Content Adaptive Brightness command */
+#define OTM8009A_CMD_WRCABCMB 0x5E /* Write CABC Minimum Brightness command */
+
+/**
+ * @brief OTM8009A_480X800 frequency divider
+ */
+#define OTM8009A_480X800_FREQUENCY_DIVIDER 2 /* LCD Frequency divider */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+
+/** @defgroup OTM8009A_Exported_Macros OTM8009A Exported Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @addtogroup OTM8009A_Exported_Functions
+ * @{
+ */
+void DSI_IO_WriteCmd(uint32_t NbrParams, uint8_t *pParams);
+uint8_t OTM8009A_Init(uint32_t ColorCoding, uint32_t orientation);
+void OTM8009A_IO_Delay(uint32_t Delay);
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __OTM8009A_480X800_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/ov9655/ov9655.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,861 @@
+/**
+ ******************************************************************************
+ * @file ov9655.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 25-June-2015
+ * @brief This file provides the OV9655 camera driver
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "ov9655.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup OV9655
+ * @brief This file provides a set of functions needed to drive the
+ * OV9655 Camera module.
+ * @{
+ */
+
+/** @defgroup OV9655_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup OV9655_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup OV9655_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup OV9655_Private_FunctionPrototypes
+ * @{
+ */
+static uint64_t ov9655_ConvertValue(uint32_t feature, uint32_t value);
+/**
+ * @}
+ */
+
+/** @defgroup OV9655_Private_Variables
+ * @{
+ */
+
+CAMERA_DrvTypeDef ov9655_drv =
+{
+ ov9655_Init,
+ ov9655_ReadID,
+ ov9655_Config,
+};
+
+/* Initialization sequence for VGA resolution (640x480)*/
+const unsigned char OV9655_VGA[][2]=
+{
+ {0x00, 0x00},
+ {0x01, 0x80},
+ {0x02, 0x80},
+ {0xb5, 0x00},
+ {0x35, 0x00},
+ {0xa8, 0xc1},
+ {0x3a, 0xcc},
+ {0x3d, 0x99},
+ {0x77, 0x02},
+ {0x13, 0xe7},
+ {0x26, 0x72},
+ {0x27, 0x08},
+ {0x28, 0x08},
+ {0x2c, 0x08},
+ {0xab, 0x04},
+ {0x6e, 0x00},
+ {0x6d, 0x55},
+ {0x00, 0x11},
+ {0x10, 0x7b},
+ {0xbb, 0xae},
+ {0x11, 0x03},
+ {0x72, 0x00},
+ {0x3e, 0x0c},
+ {0x74, 0x3a},
+ {0x76, 0x01},
+ {0x75, 0x35},
+ {0x73, 0x00},
+ {0xc7, 0x80},
+ {0x62, 0x00},
+ {0x63, 0x00},
+ {0x64, 0x02},
+ {0x65, 0x20},
+ {0x66, 0x01},
+ {0xc3, 0x4e},
+ {0x33, 0x00},
+ {0xa4, 0x50},
+ {0xaa, 0x92},
+ {0xc2, 0x01},
+ {0xc1, 0xc8},
+ {0x1e, 0x04},
+ {0xa9, 0xef},
+ {0x0e, 0x61},
+ {0x39, 0x57},
+ {0x0f, 0x48},
+ {0x24, 0x3c},
+ {0x25, 0x36},
+ {0x12, 0x63},
+ {0x03, 0x12},
+ {0x32, 0xff},
+ {0x17, 0x16},
+ {0x18, 0x02},
+ {0x19, 0x01},
+ {0x1a, 0x3d},
+ {0x36, 0xfa},
+ {0x69, 0x0a},
+ {0x8c, 0x8d},
+ {0xc0, 0xaa},
+ {0x40, 0xd0},
+ {0x43, 0x14},
+ {0x44, 0xf0},
+ {0x45, 0x46},
+ {0x46, 0x62},
+ {0x47, 0x2a},
+ {0x48, 0x3c},
+ {0x59, 0x85},
+ {0x5a, 0xa9},
+ {0x5b, 0x64},
+ {0x5c, 0x84},
+ {0x5d, 0x53},
+ {0x5e, 0x0e},
+ {0x6c, 0x0c},
+ {0xc6, 0x85},
+ {0xcb, 0xf0},
+ {0xcc, 0xd8},
+ {0x71, 0x78},
+ {0xa5, 0x68},
+ {0x6f, 0x9e},
+ {0x42, 0xc0},
+ {0x3f, 0x82},
+ {0x8a, 0x23},
+ {0x14, 0x3a},
+ {0x3b, 0xcc},
+ {0x34, 0x3d},
+ {0x41, 0x40},
+ {0xc9, 0xe0},
+ {0xca, 0xe8},
+ {0xcd, 0x93},
+ {0x7a, 0x20},
+ {0x7b, 0x1c},
+ {0x7c, 0x28},
+ {0x7d, 0x3c},
+ {0x7e, 0x5a},
+ {0x7f, 0x68},
+ {0x80, 0x76},
+ {0x81, 0x80},
+ {0x82, 0x88},
+ {0x83, 0x8f},
+ {0x84, 0x96},
+ {0x85, 0xa3},
+ {0x86, 0xaf},
+ {0x87, 0xc4},
+ {0x88, 0xd7},
+ {0x89, 0xe8},
+ {0x4f, 0x98},
+ {0x50, 0x98},
+ {0x51, 0x00},
+ {0x52, 0x28},
+ {0x53, 0x70},
+ {0x54, 0x98},
+ {0x58, 0x1a},
+ {0x6b, 0x5a},
+ {0x90, 0x92},
+ {0x91, 0x92},
+ {0x9f, 0x90},
+ {0xa0, 0x90},
+ {0x16, 0x24},
+ {0x2a, 0x00},
+ {0x2b, 0x00},
+ {0xac, 0x80},
+ {0xad, 0x80},
+ {0xae, 0x80},
+ {0xaf, 0x80},
+ {0xb2, 0xf2},
+ {0xb3, 0x20},
+ {0xb4, 0x20},
+ {0xb6, 0xaf},
+ {0x29, 0x15},
+ {0x9d, 0x02},
+ {0x9e, 0x02},
+ {0x9e, 0x02},
+ {0x04, 0x03},
+ {0x05, 0x2e},
+ {0x06, 0x2e},
+ {0x07, 0x2e},
+ {0x08, 0x2e},
+ {0x2f, 0x2e},
+ {0x4a, 0xe9},
+ {0x4b, 0xdd},
+ {0x4c, 0xdd},
+ {0x4d, 0xdd},
+ {0x4e, 0xdd},
+ {0x70, 0x06},
+ {0xa6, 0x40},
+ {0xbc, 0x02},
+ {0xbd, 0x01},
+ {0xbe, 0x02},
+ {0xbf, 0x01},
+};
+
+/* Initialization sequence for QVGA resolution (320x240) */
+const unsigned char OV9655_QVGA[][2]=
+{
+ {0x00, 0x00},
+ {0x01, 0x80},
+ {0x02, 0x80},
+ {0x03, 0x02},
+ {0x04, 0x03},
+ {0x09, 0x01},
+ {0x0b, 0x57},
+ {0x0e, 0x61},
+ {0x0f, 0x40},
+ {0x11, 0x01},
+ {0x12, 0x62},
+ {0x13, 0xc7},
+ {0x14, 0x3a},
+ {0x16, 0x24},
+ {0x17, 0x18},
+ {0x18, 0x04},
+ {0x19, 0x01},
+ {0x1a, 0x81},
+ {0x1e, 0x00},
+ {0x24, 0x3c},
+ {0x25, 0x36},
+ {0x26, 0x72},
+ {0x27, 0x08},
+ {0x28, 0x08},
+ {0x29, 0x15},
+ {0x2a, 0x00},
+ {0x2b, 0x00},
+ {0x2c, 0x08},
+ {0x32, 0x12},
+ {0x33, 0x00},
+ {0x34, 0x3f},
+ {0x35, 0x00},
+ {0x36, 0x3a},
+ {0x38, 0x72},
+ {0x39, 0x57},
+ {0x3a, 0xcc},
+ {0x3b, 0x04},
+ {0x3d, 0x99},
+ {0x3e, 0x02},
+ {0x3f, 0xc1},
+ {0x40, 0xc0},
+ {0x41, 0x41},
+ {0x42, 0xc0},
+ {0x43, 0x0a},
+ {0x44, 0xf0},
+ {0x45, 0x46},
+ {0x46, 0x62},
+ {0x47, 0x2a},
+ {0x48, 0x3c},
+ {0x4a, 0xfc},
+ {0x4b, 0xfc},
+ {0x4c, 0x7f},
+ {0x4d, 0x7f},
+ {0x4e, 0x7f},
+ {0x4f, 0x98},
+ {0x50, 0x98},
+ {0x51, 0x00},
+ {0x52, 0x28},
+ {0x53, 0x70},
+ {0x54, 0x98},
+ {0x58, 0x1a},
+ {0x59, 0x85},
+ {0x5a, 0xa9},
+ {0x5b, 0x64},
+ {0x5c, 0x84},
+ {0x5d, 0x53},
+ {0x5e, 0x0e},
+ {0x5f, 0xf0},
+ {0x60, 0xf0},
+ {0x61, 0xf0},
+ {0x62, 0x00},
+ {0x63, 0x00},
+ {0x64, 0x02},
+ {0x65, 0x20},
+ {0x66, 0x00},
+ {0x69, 0x0a},
+ {0x6b, 0x5a},
+ {0x6c, 0x04},
+ {0x6d, 0x55},
+ {0x6e, 0x00},
+ {0x6f, 0x9d},
+ {0x70, 0x21},
+ {0x71, 0x78},
+ {0x72, 0x11},
+ {0x73, 0x01},
+ {0x74, 0x10},
+ {0x75, 0x10},
+ {0x76, 0x01},
+ {0x77, 0x02},
+ {0x7A, 0x12},
+ {0x7B, 0x08},
+ {0x7C, 0x16},
+ {0x7D, 0x30},
+ {0x7E, 0x5e},
+ {0x7F, 0x72},
+ {0x80, 0x82},
+ {0x81, 0x8e},
+ {0x82, 0x9a},
+ {0x83, 0xa4},
+ {0x84, 0xac},
+ {0x85, 0xb8},
+ {0x86, 0xc3},
+ {0x87, 0xd6},
+ {0x88, 0xe6},
+ {0x89, 0xf2},
+ {0x8a, 0x24},
+ {0x8c, 0x80},
+ {0x90, 0x7d},
+ {0x91, 0x7b},
+ {0x9d, 0x02},
+ {0x9e, 0x02},
+ {0x9f, 0x7a},
+ {0xa0, 0x79},
+ {0xa1, 0x40},
+ {0xa4, 0x50},
+ {0xa5, 0x68},
+ {0xa6, 0x4a},
+ {0xa8, 0xc1},
+ {0xa9, 0xef},
+ {0xaa, 0x92},
+ {0xab, 0x04},
+ {0xac, 0x80},
+ {0xad, 0x80},
+ {0xae, 0x80},
+ {0xaf, 0x80},
+ {0xb2, 0xf2},
+ {0xb3, 0x20},
+ {0xb4, 0x20},
+ {0xb5, 0x00},
+ {0xb6, 0xaf},
+ {0xb6, 0xaf},
+ {0xbb, 0xae},
+ {0xbc, 0x7f},
+ {0xbd, 0x7f},
+ {0xbe, 0x7f},
+ {0xbf, 0x7f},
+ {0xbf, 0x7f},
+ {0xc0, 0xaa},
+ {0xc1, 0xc0},
+ {0xc2, 0x01},
+ {0xc3, 0x4e},
+ {0xc6, 0x05},
+ {0xc7, 0x81},
+ {0xc9, 0xe0},
+ {0xca, 0xe8},
+ {0xcb, 0xf0},
+ {0xcc, 0xd8},
+ {0xcd, 0x93},
+ {0x12, 0x63},
+ {0x40, 0x10},
+};
+
+/* Initialization sequence for QQVGA resolution (160x120) */
+const char OV9655_QQVGA[][2]=
+{
+ {0x00, 0x00},
+ {0x01, 0x80},
+ {0x02, 0x80},
+ {0x03, 0x02},
+ {0x04, 0x03},
+ {0x09, 0x01},
+ {0x0b, 0x57},
+ {0x0e, 0x61},
+ {0x0f, 0x40},
+ {0x11, 0x01},
+ {0x12, 0x62},
+ {0x13, 0xc7},
+ {0x14, 0x3a},
+ {0x16, 0x24},
+ {0x17, 0x18},
+ {0x18, 0x04},
+ {0x19, 0x01},
+ {0x1a, 0x81},
+ {0x1e, 0x00},
+ {0x24, 0x3c},
+ {0x25, 0x36},
+ {0x26, 0x72},
+ {0x27, 0x08},
+ {0x28, 0x08},
+ {0x29, 0x15},
+ {0x2a, 0x00},
+ {0x2b, 0x00},
+ {0x2c, 0x08},
+ {0x32, 0xa4},
+ {0x33, 0x00},
+ {0x34, 0x3f},
+ {0x35, 0x00},
+ {0x36, 0x3a},
+ {0x38, 0x72},
+ {0x39, 0x57},
+ {0x3a, 0xcc},
+ {0x3b, 0x04},
+ {0x3d, 0x99},
+ {0x3e, 0x0e},
+ {0x3f, 0xc1},
+ {0x40, 0xc0},
+ {0x41, 0x41},
+ {0x42, 0xc0},
+ {0x43, 0x0a},
+ {0x44, 0xf0},
+ {0x45, 0x46},
+ {0x46, 0x62},
+ {0x47, 0x2a},
+ {0x48, 0x3c},
+ {0x4a, 0xfc},
+ {0x4b, 0xfc},
+ {0x4c, 0x7f},
+ {0x4d, 0x7f},
+ {0x4e, 0x7f},
+ {0x4f, 0x98},
+ {0x50, 0x98},
+ {0x51, 0x00},
+ {0x52, 0x28},
+ {0x53, 0x70},
+ {0x54, 0x98},
+ {0x58, 0x1a},
+ {0x59, 0x85},
+ {0x5a, 0xa9},
+ {0x5b, 0x64},
+ {0x5c, 0x84},
+ {0x5d, 0x53},
+ {0x5e, 0x0e},
+ {0x5f, 0xf0},
+ {0x60, 0xf0},
+ {0x61, 0xf0},
+ {0x62, 0x00},
+ {0x63, 0x00},
+ {0x64, 0x02},
+ {0x65, 0x20},
+ {0x66, 0x00},
+ {0x69, 0x0a},
+ {0x6b, 0x5a},
+ {0x6c, 0x04},
+ {0x6d, 0x55},
+ {0x6e, 0x00},
+ {0x6f, 0x9d},
+ {0x70, 0x21},
+ {0x71, 0x78},
+ {0x72, 0x22},
+ {0x73, 0x02},
+ {0x74, 0x10},
+ {0x75, 0x10},
+ {0x76, 0x01},
+ {0x77, 0x02},
+ {0x7A, 0x12},
+ {0x7B, 0x08},
+ {0x7C, 0x16},
+ {0x7D, 0x30},
+ {0x7E, 0x5e},
+ {0x7F, 0x72},
+ {0x80, 0x82},
+ {0x81, 0x8e},
+ {0x82, 0x9a},
+ {0x83, 0xa4},
+ {0x84, 0xac},
+ {0x85, 0xb8},
+ {0x86, 0xc3},
+ {0x87, 0xd6},
+ {0x88, 0xe6},
+ {0x89, 0xf2},
+ {0x8a, 0x24},
+ {0x8c, 0x80},
+ {0x90, 0x7d},
+ {0x91, 0x7b},
+ {0x9d, 0x02},
+ {0x9e, 0x02},
+ {0x9f, 0x7a},
+ {0xa0, 0x79},
+ {0xa1, 0x40},
+ {0xa4, 0x50},
+ {0xa5, 0x68},
+ {0xa6, 0x4a},
+ {0xa8, 0xc1},
+ {0xa9, 0xef},
+ {0xaa, 0x92},
+ {0xab, 0x04},
+ {0xac, 0x80},
+ {0xad, 0x80},
+ {0xae, 0x80},
+ {0xaf, 0x80},
+ {0xb2, 0xf2},
+ {0xb3, 0x20},
+ {0xb4, 0x20},
+ {0xb5, 0x00},
+ {0xb6, 0xaf},
+ {0xb6, 0xaf},
+ {0xbb, 0xae},
+ {0xbc, 0x7f},
+ {0xbd, 0x7f},
+ {0xbe, 0x7f},
+ {0xbf, 0x7f},
+ {0xbf, 0x7f},
+ {0xc0, 0xaa},
+ {0xc1, 0xc0},
+ {0xc2, 0x01},
+ {0xc3, 0x4e},
+ {0xc6, 0x05},
+ {0xc7, 0x82},
+ {0xc9, 0xe0},
+ {0xca, 0xe8},
+ {0xcb, 0xf0},
+ {0xcc, 0xd8},
+ {0xcd, 0x93},
+ {0x12, 0x63},
+ {0x40, 0x10},
+};
+
+/**
+ * @}
+ */
+
+/** @defgroup OV9655_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes the OV9655 CAMERA component.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param resolution: Camera resolution
+ * @retval None
+ */
+void ov9655_Init(uint16_t DeviceAddr, uint32_t resolution)
+{
+ uint32_t index;
+
+ /* Initialize I2C */
+ CAMERA_IO_Init();
+
+ /* Prepare the camera to be configured by resetting all its registers */
+ CAMERA_IO_Write(DeviceAddr, OV9655_SENSOR_COM7, 0x80);
+ CAMERA_Delay(200);
+
+ /* Initialize OV9655 */
+ switch (resolution)
+ {
+ case CAMERA_R160x120:
+ {
+ for(index=0; index<(sizeof(OV9655_QQVGA)/2); index++)
+ {
+ CAMERA_IO_Write(DeviceAddr, OV9655_QQVGA[index][0], OV9655_QQVGA[index][1]);
+ CAMERA_Delay(2);
+ }
+ break;
+ }
+ case CAMERA_R320x240:
+ {
+ for(index=0; index<(sizeof(OV9655_QVGA)/2); index++)
+ {
+ CAMERA_IO_Write(DeviceAddr, OV9655_QVGA[index][0], OV9655_QVGA[index][1]);
+ CAMERA_Delay(2);
+ }
+ break;
+ }
+ case CAMERA_R480x272:
+ {
+ /* Not supported resolution */
+ break;
+ }
+ case CAMERA_R640x480:
+ {
+ for(index=0; index<(sizeof(OV9655_VGA)/2); index++)
+ {
+ CAMERA_IO_Write(DeviceAddr, OV9655_VGA[index][0], OV9655_VGA[index][1]);
+ CAMERA_Delay(2);
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+/**
+ * @brief Configures the OV9655 camera feature.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param feature: Camera feature to be configured
+ * @param value: Value to be configured
+ * @param brightness_value: Brightness value to be configured
+ * @retval None
+ */
+void ov9655_Config(uint16_t DeviceAddr, uint32_t feature, uint32_t value, uint32_t brightness_value)
+{
+ uint8_t tslb, mtx1, mtx2, mtx3, mtx4, mtx5, mtx6;
+ uint64_t value_tmp;
+ uint32_t br_value;
+
+ /* Convert the input value into ov9655 parameters */
+ value_tmp = ov9655_ConvertValue(feature, value);
+ br_value = (uint32_t)ov9655_ConvertValue(CAMERA_CONTRAST_BRIGHTNESS, brightness_value);
+
+ switch(feature)
+ {
+ case CAMERA_CONTRAST_BRIGHTNESS:
+ {
+ CAMERA_IO_Write(DeviceAddr, OV9655_SENSOR_BRTN, br_value);
+ CAMERA_IO_Write(DeviceAddr, OV9655_SENSOR_CNST1, value_tmp);
+ break;
+ }
+ case CAMERA_BLACK_WHITE:
+ case CAMERA_COLOR_EFFECT:
+ {
+ tslb = (uint8_t)(value_tmp >> 48);
+ mtx1 = (uint8_t)(value_tmp >> 40);
+ mtx2 = (uint8_t)(value_tmp >> 32);
+ mtx3 = (uint8_t)(value_tmp >> 24);
+ mtx4 = (uint8_t)(value_tmp >> 16);
+ mtx5 = (uint8_t)(value_tmp >> 8);
+ mtx6 = (uint8_t)(value_tmp);
+ CAMERA_IO_Write(DeviceAddr, OV9655_SENSOR_TSLB, tslb);
+ CAMERA_IO_Write(DeviceAddr, OV9655_SENSOR_MTX1, mtx1);
+ CAMERA_IO_Write(DeviceAddr, OV9655_SENSOR_MTX2, mtx2);
+ CAMERA_IO_Write(DeviceAddr, OV9655_SENSOR_MTX3, mtx3);
+ CAMERA_IO_Write(DeviceAddr, OV9655_SENSOR_MTX4, mtx4);
+ CAMERA_IO_Write(DeviceAddr, OV9655_SENSOR_MTX5, mtx5);
+ CAMERA_IO_Write(DeviceAddr, OV9655_SENSOR_MTX6, mtx6);
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+/**
+ * @brief Read the OV9655 Camera identity.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval the OV9655 ID
+ */
+uint16_t ov9655_ReadID(uint16_t DeviceAddr)
+{
+ /* Initialize I2C */
+ CAMERA_IO_Init();
+
+ /* Get the camera ID */
+ return (CAMERA_IO_Read(DeviceAddr, OV9655_SENSOR_PIDH));
+}
+
+/******************************************************************************
+ Static Functions
+*******************************************************************************/
+/**
+ * @brief Convert input values into ov9655 parameters.
+ * @param feature: Camera feature to be configured
+ * @param value: Value to be configured
+ * @retval The converted value
+ */
+static uint64_t ov9655_ConvertValue(uint32_t feature, uint32_t value)
+{
+ uint64_t ret = 0;
+
+ switch(feature)
+ {
+ case CAMERA_BLACK_WHITE:
+ {
+ switch(value)
+ {
+ case CAMERA_BLACK_WHITE_BW:
+ {
+ ret = OV9655_BLACK_WHITE_BW;
+ break;
+ }
+ case CAMERA_BLACK_WHITE_NEGATIVE:
+ {
+ ret = OV9655_BLACK_WHITE_NEGATIVE;
+ break;
+ }
+ case CAMERA_BLACK_WHITE_BW_NEGATIVE:
+ {
+ ret = OV9655_BLACK_WHITE_BW_NEGATIVE;
+ break;
+ }
+ case CAMERA_BLACK_WHITE_NORMAL:
+ {
+ ret = OV9655_BLACK_WHITE_NORMAL;
+ break;
+ }
+ default:
+ {
+ ret = OV9655_BLACK_WHITE_NORMAL;
+ break;
+ }
+ }
+ break;
+ }
+ case CAMERA_CONTRAST_BRIGHTNESS:
+ {
+ switch(value)
+ {
+ case CAMERA_BRIGHTNESS_LEVEL0:
+ {
+ ret = OV9655_BRIGHTNESS_LEVEL0;
+ break;
+ }
+ case CAMERA_BRIGHTNESS_LEVEL1:
+ {
+ ret = OV9655_BRIGHTNESS_LEVEL1;
+ break;
+ }
+ case CAMERA_BRIGHTNESS_LEVEL2:
+ {
+ ret = OV9655_BRIGHTNESS_LEVEL2;
+ break;
+ }
+ case CAMERA_BRIGHTNESS_LEVEL3:
+ {
+ ret = OV9655_BRIGHTNESS_LEVEL3;
+ break;
+ }
+ case CAMERA_BRIGHTNESS_LEVEL4:
+ {
+ ret = OV9655_BRIGHTNESS_LEVEL4;
+ break;
+ }
+ case CAMERA_CONTRAST_LEVEL0:
+ {
+ ret = OV9655_CONTRAST_LEVEL0;
+ break;
+ }
+ case CAMERA_CONTRAST_LEVEL1:
+ {
+ ret = OV9655_CONTRAST_LEVEL1;
+ break;
+ }
+ case CAMERA_CONTRAST_LEVEL2:
+ {
+ ret = OV9655_CONTRAST_LEVEL2;
+ break;
+ }
+ case CAMERA_CONTRAST_LEVEL3:
+ {
+ ret = OV9655_CONTRAST_LEVEL3;
+ break;
+ }
+ case CAMERA_CONTRAST_LEVEL4:
+ {
+ ret = OV9655_CONTRAST_LEVEL4;
+ break;
+ }
+ default:
+ {
+ ret = OV9655_CONTRAST_LEVEL0;
+ break;
+ }
+ }
+ break;
+ }
+ case CAMERA_COLOR_EFFECT:
+ {
+ switch(value)
+ {
+ case CAMERA_COLOR_EFFECT_ANTIQUE:
+ {
+ ret = OV9655_COLOR_EFFECT_ANTIQUE;
+ break;
+ }
+ case CAMERA_COLOR_EFFECT_BLUE:
+ {
+ ret = OV9655_COLOR_EFFECT_BLUE;
+ break;
+ }
+ case CAMERA_COLOR_EFFECT_GREEN:
+ {
+ ret = OV9655_COLOR_EFFECT_GREEN;
+ break;
+ }
+ case CAMERA_COLOR_EFFECT_RED:
+ {
+ ret = OV9655_COLOR_EFFECT_RED;
+ break;
+ }
+ case CAMERA_COLOR_EFFECT_NONE:
+ default:
+ {
+ ret = OV9655_COLOR_EFFECT_NONE;
+ break;
+ }
+ }
+ break;
+ default:
+ {
+ ret = 0;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/ov9655/ov9655.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,159 @@
+/**
+ ******************************************************************************
+ * @file ov9655.h
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 25-June-2015
+ * @brief This file contains all the functions prototypes for the ov9655.c
+ * driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __OV9655_H
+#define __OV9655_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "../Common/camera.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup ov9655
+ * @{
+ */
+
+/** @defgroup OV9655_Exported_Types
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup OV9655_Exported_Constants
+ * @{
+ */
+/**
+ * @brief OV9655 ID
+ */
+#define OV9655_ID 0x96
+/**
+ * @brief OV9655 Registers
+ */
+
+/* OV9655 Registers definition */
+#define OV9655_SENSOR_PIDH 0x0A
+#define OV9655_SENSOR_PIDL 0x0B
+#define OV9655_SENSOR_COM7 0x12
+#define OV9655_SENSOR_TSLB 0x3A
+#define OV9655_SENSOR_MTX1 0x4F
+#define OV9655_SENSOR_MTX2 0x50
+#define OV9655_SENSOR_MTX3 0x51
+#define OV9655_SENSOR_MTX4 0x52
+#define OV9655_SENSOR_MTX5 0x53
+#define OV9655_SENSOR_MTX6 0x54
+#define OV9655_SENSOR_BRTN 0x55
+#define OV9655_SENSOR_CNST1 0x56
+#define OV9655_SENSOR_CNST2 0x57
+
+/**
+ * @brief OV9655 Features Parameters
+ */
+#define OV9655_BRIGHTNESS_LEVEL0 0xB0 /* Brightness level -2 */
+#define OV9655_BRIGHTNESS_LEVEL1 0x98 /* Brightness level -1 */
+#define OV9655_BRIGHTNESS_LEVEL2 0x00 /* Brightness level 0 */
+#define OV9655_BRIGHTNESS_LEVEL3 0x18 /* Brightness level +1 */
+#define OV9655_BRIGHTNESS_LEVEL4 0x30 /* Brightness level +2 */
+
+#define OV9655_BLACK_WHITE_BW 0xCC000000000000 /* Black and white effect */
+#define OV9655_BLACK_WHITE_NEGATIVE 0xEC808000008080 /* Negative effect */
+#define OV9655_BLACK_WHITE_BW_NEGATIVE 0xEC000000000000 /* BW and Negative effect */
+#define OV9655_BLACK_WHITE_NORMAL 0xCC808000008080 /* Normal effect */
+
+#define OV9655_CONTRAST_LEVEL0 0x30 /* Contrast level -2 */
+#define OV9655_CONTRAST_LEVEL1 0x38 /* Contrast level -1 */
+#define OV9655_CONTRAST_LEVEL2 0x40 /* Contrast level 0 */
+#define OV9655_CONTRAST_LEVEL3 0x50 /* Contrast level +1 */
+#define OV9655_CONTRAST_LEVEL4 0x60 /* Contrast level +2 */
+
+#define OV9655_COLOR_EFFECT_NONE 0xCC808000008080 /* No color effect */
+#define OV9655_COLOR_EFFECT_ANTIQUE 0xCC000020F00000 /* Antique effect */
+#define OV9655_COLOR_EFFECT_BLUE 0xCC000000000060 /* Blue effect */
+#define OV9655_COLOR_EFFECT_GREEN 0xCC000000008000 /* Green effect */
+#define OV9655_COLOR_EFFECT_RED 0xCC600000000000 /* Red effect */
+/**
+ * @}
+ */
+
+/** @defgroup OV9655_Exported_Functions
+ * @{
+ */
+void ov9655_Init(uint16_t DeviceAddr, uint32_t resolution);
+void ov9655_Config(uint16_t DeviceAddr, uint32_t feature, uint32_t value, uint32_t BR_value);
+uint16_t ov9655_ReadID(uint16_t DeviceAddr);
+
+void CAMERA_IO_Init(void);
+void CAMERA_IO_Write(uint8_t addr, uint8_t reg, uint8_t value);
+uint8_t CAMERA_IO_Read(uint8_t addr, uint8_t reg);
+void CAMERA_Delay(uint32_t delay);
+
+/* CAMERA driver structure */
+extern CAMERA_DrvTypeDef ov9655_drv;
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __OV9655_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/wm8994/wm8994.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,1041 @@
+/**
+ ******************************************************************************
+ * @file wm8994.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 22-February-2016
+ * @brief This file provides the WM8994 Audio Codec driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "wm8994.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Components
+ * @{
+ */
+
+/** @addtogroup wm8994
+ * @brief This file provides a set of functions needed to drive the
+ * WM8994 audio codec.
+ * @{
+ */
+
+/** @defgroup WM8994_Private_Types
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup WM8994_Private_Defines
+ * @{
+ */
+/* Uncomment this line to enable verifying data sent to codec after each write
+ operation (for debug purpose) */
+#if !defined (VERIFY_WRITTENDATA)
+/*#define VERIFY_WRITTENDATA*/
+#endif /* VERIFY_WRITTENDATA */
+/**
+ * @}
+ */
+
+/** @defgroup WM8994_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup WM8994_Private_Variables
+ * @{
+ */
+
+/* Audio codec driver structure initialization */
+AUDIO_DrvTypeDef wm8994_drv =
+{
+ wm8994_Init,
+ wm8994_DeInit,
+ wm8994_ReadID,
+
+ wm8994_Play,
+ wm8994_Pause,
+ wm8994_Resume,
+ wm8994_Stop,
+
+ wm8994_SetFrequency,
+ wm8994_SetVolume,
+ wm8994_SetMute,
+ wm8994_SetOutputMode,
+
+ wm8994_Reset
+};
+
+static uint32_t outputEnabled = 0;
+static uint32_t inputEnabled = 0;
+/**
+ * @}
+ */
+
+/** @defgroup WM8994_Function_Prototypes
+ * @{
+ */
+static uint8_t CODEC_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value);
+/**
+ * @}
+ */
+
+/** @defgroup WM8994_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes the audio codec and the control interface.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param OutputInputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
+ * OUTPUT_DEVICE_BOTH, OUTPUT_DEVICE_AUTO, INPUT_DEVICE_DIGITAL_MICROPHONE_1,
+ * INPUT_DEVICE_DIGITAL_MICROPHONE_2, INPUT_DEVICE_DIGITAL_MIC1_MIC2,
+ * INPUT_DEVICE_INPUT_LINE_1 or INPUT_DEVICE_INPUT_LINE_2.
+ * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
+ * @param AudioFreq: Audio Frequency
+ * @retval 0 if correct communication, else wrong communication
+ */
+uint32_t wm8994_Init(uint16_t DeviceAddr, uint16_t OutputInputDevice, uint8_t Volume, uint32_t AudioFreq)
+{
+ uint32_t counter = 0;
+ uint16_t output_device = OutputInputDevice & 0xFF;
+ uint16_t input_device = OutputInputDevice & 0xFF00;
+ uint16_t power_mgnt_reg_1 = 0;
+
+ /* Initialize the Control interface of the Audio Codec */
+ AUDIO_IO_Init();
+ /* wm8994 Errata Work-Arounds */
+ counter += CODEC_IO_Write(DeviceAddr, 0x102, 0x0003);
+ counter += CODEC_IO_Write(DeviceAddr, 0x817, 0x0000);
+ counter += CODEC_IO_Write(DeviceAddr, 0x102, 0x0000);
+
+ /* Enable VMID soft start (fast), Start-up Bias Current Enabled */
+ counter += CODEC_IO_Write(DeviceAddr, 0x39, 0x006C);
+
+ /* Enable bias generator, Enable VMID */
+ if (input_device > 0)
+ {
+ counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x0013);
+ }
+ else
+ {
+ counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x0003);
+ }
+
+ /* Add Delay */
+ AUDIO_IO_Delay(50);
+
+ /* Path Configurations for output */
+ if (output_device > 0)
+ {
+ outputEnabled = 1;
+ switch (output_device)
+ {
+ case OUTPUT_DEVICE_SPEAKER:
+ /* Enable DAC1 (Left), Enable DAC1 (Right),
+ Disable DAC2 (Left), Disable DAC2 (Right)*/
+ counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0C0C);
+
+ /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0000);
+
+ /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0000);
+
+ /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
+
+ /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
+ break;
+
+ case OUTPUT_DEVICE_HEADPHONE:
+ /* Disable DAC1 (Left), Disable DAC1 (Right),
+ Enable DAC2 (Left), Enable DAC2 (Right)*/
+ counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
+
+ /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
+
+ /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
+
+ /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
+
+ /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
+ break;
+
+ case OUTPUT_DEVICE_BOTH:
+ if (input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2)
+ {
+ /* Enable DAC1 (Left), Enable DAC1 (Right),
+ also Enable DAC2 (Left), Enable DAC2 (Right)*/
+ counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C);
+
+ /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path
+ Enable the AIF1 Timeslot 1 (Left) to DAC 1 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0003);
+
+ /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path
+ Enable the AIF1 Timeslot 1 (Right) to DAC 1 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0003);
+
+ /* Enable the AIF1 Timeslot 0 (Left) to DAC 2 (Left) mixer path
+ Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0003);
+
+ /* Enable the AIF1 Timeslot 0 (Right) to DAC 2 (Right) mixer path
+ Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0003);
+ }
+ else
+ {
+ /* Enable DAC1 (Left), Enable DAC1 (Right),
+ also Enable DAC2 (Left), Enable DAC2 (Right)*/
+ counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C);
+
+ /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
+
+ /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
+
+ /* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
+
+ /* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
+ }
+ break;
+
+ case OUTPUT_DEVICE_AUTO :
+ default:
+ /* Disable DAC1 (Left), Disable DAC1 (Right),
+ Enable DAC2 (Left), Enable DAC2 (Right)*/
+ counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
+
+ /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
+
+ /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
+
+ /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
+
+ /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
+ break;
+ }
+ }
+ else
+ {
+ outputEnabled = 0;
+ }
+
+ /* Path Configurations for input */
+ if (input_device > 0)
+ {
+ inputEnabled = 1;
+ switch (input_device)
+ {
+ case INPUT_DEVICE_DIGITAL_MICROPHONE_2 :
+ /* Enable AIF1ADC2 (Left), Enable AIF1ADC2 (Right)
+ * Enable DMICDAT2 (Left), Enable DMICDAT2 (Right)
+ * Enable Left ADC, Enable Right ADC */
+ counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0C30);
+
+ /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x450, 0x00DB);
+
+ /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
+ counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6000);
+
+ /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x608, 0x0002);
+
+ /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x609, 0x0002);
+
+ /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC2 signal detect */
+ counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000E);
+ break;
+
+ case INPUT_DEVICE_INPUT_LINE_1 :
+ /* IN1LN_TO_IN1L, IN1LP_TO_VMID, IN1RN_TO_IN1R, IN1RP_TO_VMID */
+ counter += CODEC_IO_Write(DeviceAddr, 0x28, 0x0011);
+
+ /* Disable mute on IN1L_TO_MIXINL and +30dB on IN1L PGA output */
+ counter += CODEC_IO_Write(DeviceAddr, 0x29, 0x0035);
+
+ /* Disable mute on IN1R_TO_MIXINL, Gain = +30dB */
+ counter += CODEC_IO_Write(DeviceAddr, 0x2A, 0x0035);
+
+ /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
+ * Enable Left ADC, Enable Right ADC */
+ counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0303);
+
+ /* Enable AIF1 DRC1 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x440, 0x00DB);
+
+ /* Enable IN1L and IN1R, Disable IN2L and IN2R, Enable Thermal sensor & shutdown */
+ counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6350);
+
+ /* Enable the ADCL(Left) to AIF1 Timeslot 0 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x606, 0x0002);
+
+ /* Enable the ADCR(Right) to AIF1 Timeslot 0 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x607, 0x0002);
+
+ /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
+ counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000D);
+ break;
+
+ case INPUT_DEVICE_DIGITAL_MICROPHONE_1 :
+ /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
+ * Enable DMICDAT1 (Left), Enable DMICDAT1 (Right)
+ * Enable Left ADC, Enable Right ADC */
+ counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x030C);
+
+ /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x440, 0x00DB);
+
+ /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
+ counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6350);
+
+ /* Enable the DMIC2(Left) to AIF1 Timeslot 0 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x606, 0x0002);
+
+ /* Enable the DMIC2(Right) to AIF1 Timeslot 0 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x607, 0x0002);
+
+ /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
+ counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000D);
+ break;
+ case INPUT_DEVICE_DIGITAL_MIC1_MIC2 :
+ /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
+ * Enable DMICDAT1 (Left), Enable DMICDAT1 (Right)
+ * Enable Left ADC, Enable Right ADC */
+ counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0F3C);
+
+ /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x450, 0x00DB);
+
+ /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x440, 0x00DB);
+
+ /* Disable IN1L, IN1R, Enable IN2L, IN2R, Thermal sensor & shutdown */
+ counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x63A0);
+
+ /* Enable the DMIC2(Left) to AIF1 Timeslot 0 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x606, 0x0002);
+
+ /* Enable the DMIC2(Right) to AIF1 Timeslot 0 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x607, 0x0002);
+
+ /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x608, 0x0002);
+
+ /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x609, 0x0002);
+
+ /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
+ counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000D);
+ break;
+ case INPUT_DEVICE_INPUT_LINE_2 :
+ default:
+ /* Actually, no other input devices supported */
+ counter++;
+ break;
+ }
+ }
+ else
+ {
+ inputEnabled = 0;
+ }
+
+ /* Clock Configurations */
+ switch (AudioFreq)
+ {
+ case AUDIO_FREQUENCY_8K:
+ /* AIF1 Sample Rate = 8 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0003);
+ break;
+
+ case AUDIO_FREQUENCY_16K:
+ /* AIF1 Sample Rate = 16 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0033);
+ break;
+
+ case AUDIO_FREQUENCY_32K:
+ /* AIF1 Sample Rate = 32 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0063);
+ break;
+
+ case AUDIO_FREQUENCY_48K:
+ /* AIF1 Sample Rate = 48 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
+ break;
+
+ case AUDIO_FREQUENCY_96K:
+ /* AIF1 Sample Rate = 96 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x00A3);
+ break;
+
+ case AUDIO_FREQUENCY_11K:
+ /* AIF1 Sample Rate = 11.025 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0013);
+ break;
+
+ case AUDIO_FREQUENCY_22K:
+ /* AIF1 Sample Rate = 22.050 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0043);
+ break;
+
+ case AUDIO_FREQUENCY_44K:
+ /* AIF1 Sample Rate = 44.1 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0073);
+ break;
+
+ default:
+ /* AIF1 Sample Rate = 48 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
+ break;
+ }
+
+ if(input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2)
+ {
+ /* AIF1 Word Length = 16-bits, AIF1 Format = DSP mode */
+ counter += CODEC_IO_Write(DeviceAddr, 0x300, 0x4018);
+ }
+ else
+ {
+ /* AIF1 Word Length = 16-bits, AIF1 Format = I2S (Default Register Value) */
+ counter += CODEC_IO_Write(DeviceAddr, 0x300, 0x4010);
+ }
+
+ /* slave mode */
+ counter += CODEC_IO_Write(DeviceAddr, 0x302, 0x0000);
+
+ /* Enable the DSP processing clock for AIF1, Enable the core clock */
+ counter += CODEC_IO_Write(DeviceAddr, 0x208, 0x000A);
+
+ /* Enable AIF1 Clock, AIF1 Clock Source = MCLK1 pin */
+ counter += CODEC_IO_Write(DeviceAddr, 0x200, 0x0001);
+
+ if (output_device > 0) /* Audio output selected */
+ {
+ /* Analog Output Configuration */
+
+ /* Enable SPKRVOL PGA, Enable SPKMIXR, Enable SPKLVOL PGA, Enable SPKMIXL */
+ counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0300);
+
+ /* Left Speaker Mixer Volume = 0dB */
+ counter += CODEC_IO_Write(DeviceAddr, 0x22, 0x0000);
+
+ /* Speaker output mode = Class D, Right Speaker Mixer Volume = 0dB ((0x23, 0x0100) = class AB)*/
+ counter += CODEC_IO_Write(DeviceAddr, 0x23, 0x0000);
+
+ /* Unmute DAC2 (Left) to Left Speaker Mixer (SPKMIXL) path,
+ Unmute DAC2 (Right) to Right Speaker Mixer (SPKMIXR) path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x36, 0x0300);
+
+ /* Enable bias generator, Enable VMID, Enable SPKOUTL, Enable SPKOUTR */
+ counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x3003);
+
+ /* Headphone/Speaker Enable */
+
+ if (input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2)
+ {
+ /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslots 0 and 1 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x51, 0x0205);
+ }
+ else
+ {
+ /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslot 0 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x51, 0x0005);
+ }
+
+ /* Enable bias generator, Enable VMID, Enable HPOUT1 (Left) and Enable HPOUT1 (Right) input stages */
+ /* idem for Speaker */
+ power_mgnt_reg_1 |= 0x0303 | 0x3003;
+ counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);
+
+ /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate stages */
+ counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x0022);
+
+ /* Enable Charge Pump */
+ counter += CODEC_IO_Write(DeviceAddr, 0x4C, 0x9F25);
+
+ /* Add Delay */
+ AUDIO_IO_Delay(15);
+
+ /* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x2D, 0x0001);
+
+ /* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x2E, 0x0001);
+
+ /* Enable Left Output Mixer (MIXOUTL), Enable Right Output Mixer (MIXOUTR) */
+ /* idem for SPKOUTL and SPKOUTR */
+ counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0030 | 0x0300);
+
+ /* Enable DC Servo and trigger start-up mode on left and right channels */
+ counter += CODEC_IO_Write(DeviceAddr, 0x54, 0x0033);
+
+ /* Add Delay */
+ AUDIO_IO_Delay(250);
+
+ /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate and output stages. Remove clamps */
+ counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x00EE);
+
+ /* Unmutes */
+
+ /* Unmute DAC 1 (Left) */
+ counter += CODEC_IO_Write(DeviceAddr, 0x610, 0x00C0);
+
+ /* Unmute DAC 1 (Right) */
+ counter += CODEC_IO_Write(DeviceAddr, 0x611, 0x00C0);
+
+ /* Unmute the AIF1 Timeslot 0 DAC path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0000);
+
+ /* Unmute DAC 2 (Left) */
+ counter += CODEC_IO_Write(DeviceAddr, 0x612, 0x00C0);
+
+ /* Unmute DAC 2 (Right) */
+ counter += CODEC_IO_Write(DeviceAddr, 0x613, 0x00C0);
+
+ /* Unmute the AIF1 Timeslot 1 DAC2 path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0000);
+
+ /* Volume Control */
+ wm8994_SetVolume(DeviceAddr, Volume);
+ }
+
+ if (input_device > 0) /* Audio input selected */
+ {
+ if ((input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_1) || (input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_2))
+ {
+ /* Enable Microphone bias 1 generator, Enable VMID */
+ power_mgnt_reg_1 |= 0x0013;
+ counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);
+
+ /* ADC oversample enable */
+ counter += CODEC_IO_Write(DeviceAddr, 0x620, 0x0002);
+
+ /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
+ counter += CODEC_IO_Write(DeviceAddr, 0x411, 0x3800);
+ }
+ else if(input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2)
+ {
+ /* Enable Microphone bias 1 generator, Enable VMID */
+ power_mgnt_reg_1 |= 0x0013;
+ counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);
+
+ /* ADC oversample enable */
+ counter += CODEC_IO_Write(DeviceAddr, 0x620, 0x0002);
+
+ /* AIF ADC1 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
+ counter += CODEC_IO_Write(DeviceAddr, 0x410, 0x1800);
+
+ /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
+ counter += CODEC_IO_Write(DeviceAddr, 0x411, 0x1800);
+ }
+ else if ((input_device == INPUT_DEVICE_INPUT_LINE_1) || (input_device == INPUT_DEVICE_INPUT_LINE_2))
+ {
+
+ /* Disable mute on IN1L, IN1L Volume = +0dB */
+ counter += CODEC_IO_Write(DeviceAddr, 0x18, 0x000B);
+
+ /* Disable mute on IN1R, IN1R Volume = +0dB */
+ counter += CODEC_IO_Write(DeviceAddr, 0x1A, 0x000B);
+
+ /* AIF ADC1 HPF enable, HPF cut = hifi mode fc=4Hz at fs=48kHz */
+ counter += CODEC_IO_Write(DeviceAddr, 0x410, 0x1800);
+ }
+ /* Volume Control */
+ wm8994_SetVolume(DeviceAddr, Volume);
+ }
+ /* Return communication control value */
+ return counter;
+}
+
+/**
+ * @brief Deinitializes the audio codec.
+ * @param None
+ * @retval None
+ */
+void wm8994_DeInit(void)
+{
+ /* Deinitialize Audio Codec interface */
+ AUDIO_IO_DeInit();
+}
+
+/**
+ * @brief Get the WM8994 ID.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval The WM8994 ID
+ */
+uint32_t wm8994_ReadID(uint16_t DeviceAddr)
+{
+ /* Initialize the Control interface of the Audio Codec */
+ AUDIO_IO_Init();
+
+ return ((uint32_t)AUDIO_IO_Read(DeviceAddr, WM8994_CHIPID_ADDR));
+}
+
+/**
+ * @brief Start the audio Codec play feature.
+ * @note For this codec no Play options are required.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval 0 if correct communication, else wrong communication
+ */
+uint32_t wm8994_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size)
+{
+ uint32_t counter = 0;
+
+ /* Resumes the audio file playing */
+ /* Unmute the output first */
+ counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
+
+ return counter;
+}
+
+/**
+ * @brief Pauses playing on the audio codec.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval 0 if correct communication, else wrong communication
+ */
+uint32_t wm8994_Pause(uint16_t DeviceAddr)
+{
+ uint32_t counter = 0;
+
+ /* Pause the audio file playing */
+ /* Mute the output first */
+ counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON);
+
+ /* Put the Codec in Power save mode */
+ counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x01);
+
+ return counter;
+}
+
+/**
+ * @brief Resumes playing on the audio codec.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval 0 if correct communication, else wrong communication
+ */
+uint32_t wm8994_Resume(uint16_t DeviceAddr)
+{
+ uint32_t counter = 0;
+
+ /* Resumes the audio file playing */
+ /* Unmute the output first */
+ counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
+
+ return counter;
+}
+
+/**
+ * @brief Stops audio Codec playing. It powers down the codec.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param CodecPdwnMode: selects the power down mode.
+ * - CODEC_PDWN_SW: only mutes the audio codec. When resuming from this
+ * mode the codec keeps the previous initialization
+ * (no need to re-Initialize the codec registers).
+ * - CODEC_PDWN_HW: Physically power down the codec. When resuming from this
+ * mode, the codec is set to default configuration
+ * (user should re-Initialize the codec in order to
+ * play again the audio stream).
+ * @retval 0 if correct communication, else wrong communication
+ */
+uint32_t wm8994_Stop(uint16_t DeviceAddr, uint32_t CodecPdwnMode)
+{
+ uint32_t counter = 0;
+
+ if (outputEnabled != 0)
+ {
+ /* Mute the output first */
+ counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON);
+
+ if (CodecPdwnMode == CODEC_PDWN_SW)
+ {
+ /* Only output mute required*/
+ }
+ else /* CODEC_PDWN_HW */
+ {
+ /* Mute the AIF1 Timeslot 0 DAC1 path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0200);
+
+ /* Mute the AIF1 Timeslot 1 DAC2 path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0200);
+
+ /* Disable DAC1L_TO_HPOUT1L */
+ counter += CODEC_IO_Write(DeviceAddr, 0x2D, 0x0000);
+
+ /* Disable DAC1R_TO_HPOUT1R */
+ counter += CODEC_IO_Write(DeviceAddr, 0x2E, 0x0000);
+
+ /* Disable DAC1 and DAC2 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0000);
+
+ /* Reset Codec by writing in 0x0000 address register */
+ counter += CODEC_IO_Write(DeviceAddr, 0x0000, 0x0000);
+
+ outputEnabled = 0;
+ }
+ }
+ return counter;
+}
+
+/**
+ * @brief Sets higher or lower the codec volume level.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Volume: a byte value from 0 to 255 (refer to codec registers
+ * description for more details).
+ * @retval 0 if correct communication, else wrong communication
+ */
+uint32_t wm8994_SetVolume(uint16_t DeviceAddr, uint8_t Volume)
+{
+ uint32_t counter = 0;
+ uint8_t convertedvol = VOLUME_CONVERT(Volume);
+
+ /* Output volume */
+ if (outputEnabled != 0)
+ {
+ if(convertedvol > 0x3E)
+ {
+ /* Unmute audio codec */
+ counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
+
+ /* Left Headphone Volume */
+ counter += CODEC_IO_Write(DeviceAddr, 0x1C, 0x3F | 0x140);
+
+ /* Right Headphone Volume */
+ counter += CODEC_IO_Write(DeviceAddr, 0x1D, 0x3F | 0x140);
+
+ /* Left Speaker Volume */
+ counter += CODEC_IO_Write(DeviceAddr, 0x26, 0x3F | 0x140);
+
+ /* Right Speaker Volume */
+ counter += CODEC_IO_Write(DeviceAddr, 0x27, 0x3F | 0x140);
+ }
+ else if (Volume == 0)
+ {
+ /* Mute audio codec */
+ counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON);
+ }
+ else
+ {
+ /* Unmute audio codec */
+ counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
+
+ /* Left Headphone Volume */
+ counter += CODEC_IO_Write(DeviceAddr, 0x1C, convertedvol | 0x140);
+
+ /* Right Headphone Volume */
+ counter += CODEC_IO_Write(DeviceAddr, 0x1D, convertedvol | 0x140);
+
+ /* Left Speaker Volume */
+ counter += CODEC_IO_Write(DeviceAddr, 0x26, convertedvol | 0x140);
+
+ /* Right Speaker Volume */
+ counter += CODEC_IO_Write(DeviceAddr, 0x27, convertedvol | 0x140);
+ }
+ }
+
+ /* Input volume */
+ if (inputEnabled != 0)
+ {
+ convertedvol = VOLUME_IN_CONVERT(Volume);
+
+ /* Left AIF1 ADC1 volume */
+ counter += CODEC_IO_Write(DeviceAddr, 0x400, convertedvol | 0x100);
+
+ /* Right AIF1 ADC1 volume */
+ counter += CODEC_IO_Write(DeviceAddr, 0x401, convertedvol | 0x100);
+
+ /* Left AIF1 ADC2 volume */
+ counter += CODEC_IO_Write(DeviceAddr, 0x404, convertedvol | 0x100);
+
+ /* Right AIF1 ADC2 volume */
+ counter += CODEC_IO_Write(DeviceAddr, 0x405, convertedvol | 0x100);
+ }
+ return counter;
+}
+
+/**
+ * @brief Enables or disables the mute feature on the audio codec.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Cmd: AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the
+ * mute mode.
+ * @retval 0 if correct communication, else wrong communication
+ */
+uint32_t wm8994_SetMute(uint16_t DeviceAddr, uint32_t Cmd)
+{
+ uint32_t counter = 0;
+
+ if (outputEnabled != 0)
+ {
+ /* Set the Mute mode */
+ if(Cmd == AUDIO_MUTE_ON)
+ {
+ /* Soft Mute the AIF1 Timeslot 0 DAC1 path L&R */
+ counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0200);
+
+ /* Soft Mute the AIF1 Timeslot 1 DAC2 path L&R */
+ counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0200);
+ }
+ else /* AUDIO_MUTE_OFF Disable the Mute */
+ {
+ /* Unmute the AIF1 Timeslot 0 DAC1 path L&R */
+ counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0000);
+
+ /* Unmute the AIF1 Timeslot 1 DAC2 path L&R */
+ counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0000);
+ }
+ }
+ return counter;
+}
+
+/**
+ * @brief Switch dynamically (while audio file is played) the output target
+ * (speaker or headphone).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Output: specifies the audio output target: OUTPUT_DEVICE_SPEAKER,
+ * OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO
+ * @retval 0 if correct communication, else wrong communication
+ */
+uint32_t wm8994_SetOutputMode(uint16_t DeviceAddr, uint8_t Output)
+{
+ uint32_t counter = 0;
+
+ switch (Output)
+ {
+ case OUTPUT_DEVICE_SPEAKER:
+ /* Enable DAC1 (Left), Enable DAC1 (Right),
+ Disable DAC2 (Left), Disable DAC2 (Right)*/
+ counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0C0C);
+
+ /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0000);
+
+ /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0000);
+
+ /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
+
+ /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
+ break;
+
+ case OUTPUT_DEVICE_HEADPHONE:
+ /* Disable DAC1 (Left), Disable DAC1 (Right),
+ Enable DAC2 (Left), Enable DAC2 (Right)*/
+ counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
+
+ /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
+
+ /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
+
+ /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
+
+ /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
+ break;
+
+ case OUTPUT_DEVICE_BOTH:
+ /* Enable DAC1 (Left), Enable DAC1 (Right),
+ also Enable DAC2 (Left), Enable DAC2 (Right)*/
+ counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C);
+
+ /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
+
+ /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
+
+ /* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
+
+ /* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
+ break;
+
+ default:
+ /* Disable DAC1 (Left), Disable DAC1 (Right),
+ Enable DAC2 (Left), Enable DAC2 (Right)*/
+ counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
+
+ /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
+
+ /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
+
+ /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
+
+ /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+ counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
+ break;
+ }
+ return counter;
+}
+
+/**
+ * @brief Sets new frequency.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param AudioFreq: Audio frequency used to play the audio stream.
+ * @retval 0 if correct communication, else wrong communication
+ */
+uint32_t wm8994_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq)
+{
+ uint32_t counter = 0;
+
+ /* Clock Configurations */
+ switch (AudioFreq)
+ {
+ case AUDIO_FREQUENCY_8K:
+ /* AIF1 Sample Rate = 8 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0003);
+ break;
+
+ case AUDIO_FREQUENCY_16K:
+ /* AIF1 Sample Rate = 16 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0033);
+ break;
+
+ case AUDIO_FREQUENCY_48K:
+ /* AIF1 Sample Rate = 48 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
+ break;
+
+ case AUDIO_FREQUENCY_96K:
+ /* AIF1 Sample Rate = 96 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x00A3);
+ break;
+
+ case AUDIO_FREQUENCY_11K:
+ /* AIF1 Sample Rate = 11.025 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0013);
+ break;
+
+ case AUDIO_FREQUENCY_22K:
+ /* AIF1 Sample Rate = 22.050 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0043);
+ break;
+
+ case AUDIO_FREQUENCY_44K:
+ /* AIF1 Sample Rate = 44.1 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0073);
+ break;
+
+ default:
+ /* AIF1 Sample Rate = 48 (KHz), ratio=256 */
+ counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
+ break;
+ }
+ return counter;
+}
+
+/**
+ * @brief Resets wm8994 registers.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval 0 if correct communication, else wrong communication
+ */
+uint32_t wm8994_Reset(uint16_t DeviceAddr)
+{
+ uint32_t counter = 0;
+
+ /* Reset Codec by writing in 0x0000 address register */
+ counter = CODEC_IO_Write(DeviceAddr, 0x0000, 0x0000);
+ outputEnabled = 0;
+ inputEnabled=0;
+
+ return counter;
+}
+
+/**
+ * @brief Writes/Read a single data.
+ * @param Addr: I2C address
+ * @param Reg: Reg address
+ * @param Value: Data to be written
+ * @retval None
+ */
+static uint8_t CODEC_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value)
+{
+ uint32_t result = 0;
+
+ AUDIO_IO_Write(Addr, Reg, Value);
+
+#ifdef VERIFY_WRITTENDATA
+ /* Verify that the data has been correctly written */
+ result = (AUDIO_IO_Read(Addr, Reg) == Value)? 0:1;
+#endif /* VERIFY_WRITTENDATA */
+
+ return result;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Components/wm8994/wm8994.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,188 @@
+/**
+ ******************************************************************************
+ * @file wm8994.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 22-February-2016
+ * @brief This file contains all the functions prototypes for the
+ * wm8994.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __WM8994_H
+#define __WM8994_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "../Common/audio.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Component
+ * @{
+ */
+
+/** @addtogroup WM8994
+ * @{
+ */
+
+/** @defgroup WM8994_Exported_Types
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup WM8994_Exported_Constants
+ * @{
+ */
+
+/******************************************************************************/
+/*************************** Codec User defines ******************************/
+/******************************************************************************/
+/* Codec output DEVICE */
+#define OUTPUT_DEVICE_SPEAKER ((uint16_t)0x0001)
+#define OUTPUT_DEVICE_HEADPHONE ((uint16_t)0x0002)
+#define OUTPUT_DEVICE_BOTH ((uint16_t)0x0003)
+#define OUTPUT_DEVICE_AUTO ((uint16_t)0x0004)
+#define INPUT_DEVICE_DIGITAL_MICROPHONE_1 ((uint16_t)0x0100)
+#define INPUT_DEVICE_DIGITAL_MICROPHONE_2 ((uint16_t)0x0200)
+#define INPUT_DEVICE_INPUT_LINE_1 ((uint16_t)0x0300)
+#define INPUT_DEVICE_INPUT_LINE_2 ((uint16_t)0x0400)
+#define INPUT_DEVICE_DIGITAL_MIC1_MIC2 ((uint16_t)0x0800)
+
+/* Volume Levels values */
+#define DEFAULT_VOLMIN 0x00
+#define DEFAULT_VOLMAX 0xFF
+#define DEFAULT_VOLSTEP 0x04
+
+#define AUDIO_PAUSE 0
+#define AUDIO_RESUME 1
+
+/* Codec POWER DOWN modes */
+#define CODEC_PDWN_HW 1
+#define CODEC_PDWN_SW 2
+
+/* MUTE commands */
+#define AUDIO_MUTE_ON 1
+#define AUDIO_MUTE_OFF 0
+
+/* AUDIO FREQUENCY */
+#define AUDIO_FREQUENCY_192K ((uint32_t)192000)
+#define AUDIO_FREQUENCY_96K ((uint32_t)96000)
+#define AUDIO_FREQUENCY_48K ((uint32_t)48000)
+#define AUDIO_FREQUENCY_44K ((uint32_t)44100)
+#define AUDIO_FREQUENCY_32K ((uint32_t)32000)
+#define AUDIO_FREQUENCY_22K ((uint32_t)22050)
+#define AUDIO_FREQUENCY_16K ((uint32_t)16000)
+#define AUDIO_FREQUENCY_11K ((uint32_t)11025)
+#define AUDIO_FREQUENCY_8K ((uint32_t)8000)
+
+#define VOLUME_CONVERT(Volume) (((Volume) > 100)? 100:((uint8_t)(((Volume) * 63) / 100)))
+#define VOLUME_IN_CONVERT(Volume) (((Volume) >= 100)? 239:((uint8_t)(((Volume) * 240) / 100)))
+
+/******************************************************************************/
+/****************************** REGISTER MAPPING ******************************/
+/******************************************************************************/
+/**
+ * @brief WM8994 ID
+ */
+#define WM8994_ID 0x8994
+
+/**
+ * @brief Device ID Register: Reading from this register will indicate device
+ * family ID 8994h
+ */
+#define WM8994_CHIPID_ADDR 0x00
+
+/**
+ * @}
+ */
+
+/** @defgroup WM8994_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup WM8994_Exported_Functions
+ * @{
+ */
+
+/*------------------------------------------------------------------------------
+ Audio Codec functions
+------------------------------------------------------------------------------*/
+/* High Layer codec functions */
+uint32_t wm8994_Init(uint16_t DeviceAddr, uint16_t OutputInputDevice, uint8_t Volume, uint32_t AudioFreq);
+void wm8994_DeInit(void);
+uint32_t wm8994_ReadID(uint16_t DeviceAddr);
+uint32_t wm8994_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size);
+uint32_t wm8994_Pause(uint16_t DeviceAddr);
+uint32_t wm8994_Resume(uint16_t DeviceAddr);
+uint32_t wm8994_Stop(uint16_t DeviceAddr, uint32_t Cmd);
+uint32_t wm8994_SetVolume(uint16_t DeviceAddr, uint8_t Volume);
+uint32_t wm8994_SetMute(uint16_t DeviceAddr, uint32_t Cmd);
+uint32_t wm8994_SetOutputMode(uint16_t DeviceAddr, uint8_t Output);
+uint32_t wm8994_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq);
+uint32_t wm8994_Reset(uint16_t DeviceAddr);
+
+/* AUDIO IO functions */
+void AUDIO_IO_Init(void);
+void AUDIO_IO_DeInit(void);
+void AUDIO_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value);
+uint8_t AUDIO_IO_Read(uint8_t Addr, uint16_t Reg);
+void AUDIO_IO_Delay(uint32_t Delay);
+
+/* Audio driver structure */
+extern AUDIO_DrvTypeDef wm8994_drv;
+
+#endif /* __WM8994_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Binary file STM32H747I-Discovery/STM32H747I-Discovery_BSP_User_Manual.chm has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/pdm2pcm_glo.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,97 @@
+/**
+ ******************************************************************************
+ * @file pdm2pcm_glo.h
+ * @author MCD Application Team
+ * @version V3.0.0
+ * @date 28-February-2017
+ * @brief Global header for PDM2PCM conversion code
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Image SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_image_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __PDM2PCM_FILTER_H
+#define __PDM2PCM_FILTER_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/* Exported constants --------------------------------------------------------*/
+#define PDM_FILTER_ENDIANNESS_LE ((uint16_t)0x0000)
+#define PDM_FILTER_ENDIANNESS_BE ((uint16_t)0x0001)
+
+#define PDM_FILTER_BIT_ORDER_LSB ((uint16_t)0x0000)
+#define PDM_FILTER_BIT_ORDER_MSB ((uint16_t)0x0001)
+
+#define PDM_FILTER_DEC_FACTOR_48 ((uint16_t)0x0001)
+#define PDM_FILTER_DEC_FACTOR_64 ((uint16_t)0x0002)
+#define PDM_FILTER_DEC_FACTOR_80 ((uint16_t)0x0003)
+#define PDM_FILTER_DEC_FACTOR_128 ((uint16_t)0x0004)
+#define PDM_FILTER_DEC_FACTOR_16 ((uint16_t)0x0005)
+#define PDM_FILTER_DEC_FACTOR_24 ((uint16_t)0x0006)
+#define PDM_FILTER_DEC_FACTOR_32 ((uint16_t)0x0007)
+
+#define PDM_FILTER_INIT_ERROR ((uint16_t)0x0010)
+#define PDM_FILTER_CONFIG_ERROR ((uint16_t)0x0020)
+#define PDM_FILTER_ENDIANNESS_ERROR ((uint16_t)0x0001)
+#define PDM_FILTER_BIT_ORDER_ERROR ((uint16_t)0x0002)
+#define PDM_FILTER_CRC_LOCK_ERROR ((uint16_t)0x0004)
+#define PDM_FILTER_DECIMATION_ERROR ((uint16_t)0x0008)
+#define PDM_FILTER_GAIN_ERROR ((uint16_t)0x0040)
+#define PDM_FILTER_SAMPLES_NUMBER_ERROR ((uint16_t)0x0080)
+#define PDM2PCM_INTERNAL_MEMORY_SIZE 16
+
+/* Exported types ------------------------------------------------------------*/
+typedef struct{
+ uint16_t bit_order;
+ uint16_t endianness;
+ uint32_t high_pass_tap;
+ uint16_t in_ptr_channels;
+ uint16_t out_ptr_channels;
+ uint32_t pInternalMemory[PDM2PCM_INTERNAL_MEMORY_SIZE];
+}PDM_Filter_Handler_t;
+
+typedef struct{
+ uint16_t decimation_factor;
+ uint16_t output_samples_number;
+ int16_t mic_gain;
+}PDM_Filter_Config_t;
+
+/* Exported macros -----------------------------------------------------------*/
+
+/* Exported functions ------------------------------------------------------- */
+uint32_t PDM_Filter_Init(PDM_Filter_Handler_t *pHandler);
+uint32_t PDM_Filter_setConfig(PDM_Filter_Handler_t *pHandler, PDM_Filter_Config_t *pConfig);
+uint32_t PDM_Filter_getConfig(PDM_Filter_Handler_t *pHandler, PDM_Filter_Config_t *pConfig);
+uint32_t PDM_Filter_deInterleave(void *pDataIn, void *pDataOut, PDM_Filter_Handler_t * pHandler);
+uint32_t PDM_Filter(void *pDataIn, void *pDataOut, PDM_Filter_Handler_t *pHandler);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PDM2PCM_FILTER_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,1034 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery.c
+ * @author MCD Application Team
+ * @brief This file provides a set of firmware functions to manage LEDs,
+ * push-buttons, external SDRAM, external QSPI Flash,
+ * available on STM32H747I-Discovery board (MB1248) from
+ * STMicroelectronics.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h747i_discovery.h"
+
+/** @defgroup BSP BSP
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY STM32H747I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LOW_LEVEL STM32H747I_DISCOVERY_LOW_LEVEL
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LOW_LEVEL_Private_Defines Private Defines
+ * @{
+ */
+/**
+ * @brief STM32H747I Discovery BSP Driver version number V1.0.0
+ */
+#define __STM32H747I_DISCOVERY_BSP_VERSION_MAIN (0x01) /*!< [31:24] main version */
+#define __STM32H747I_DISCOVERY_BSP_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */
+#define __STM32H747I_DISCOVERY_BSP_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */
+#define __STM32H747I_DISCOVERY_BSP_VERSION_RC (0x00) /*!< [7:0] release candidate */
+#define __STM32H747I_DISCOVERY_BSP_VERSION ((__STM32H747I_DISCOVERY_BSP_VERSION_MAIN << 24)\
+ |(__STM32H747I_DISCOVERY_BSP_VERSION_SUB1 << 16)\
+ |(__STM32H747I_DISCOVERY_BSP_VERSION_SUB2 << 8 )\
+ |(__STM32H747I_DISCOVERY_BSP_VERSION_RC))
+/**
+ * @}
+ */
+
+
+/** @defgroup STM32H747I_DISCOVERY_LOW_LEVEL_Private_Variables Private Variables
+ * @{
+ */
+
+GPIO_TypeDef* GPIO_PORT[LEDn] = {LED1_GPIO_PORT,
+ LED2_GPIO_PORT,
+ LED3_GPIO_PORT,
+ LED4_GPIO_PORT};
+
+const uint32_t GPIO_PIN[LEDn] = {LED1_PIN,
+ LED2_PIN,
+ LED3_PIN,
+ LED4_PIN};
+
+GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {WAKEUP_BUTTON_GPIO_PORT };
+
+const uint16_t BUTTON_PIN[BUTTONn] = {WAKEUP_BUTTON_PIN };
+
+const uint16_t BUTTON_IRQn[BUTTONn] = {WAKEUP_BUTTON_EXTI_IRQn };
+
+GPIO_TypeDef* JOY_PORT[JOYn] = {SEL_JOY_GPIO_PORT,
+ DOWN_JOY_GPIO_PORT,
+ LEFT_JOY_GPIO_PORT,
+ RIGHT_JOY_GPIO_PORT,
+ UP_JOY_GPIO_PORT};
+
+const uint16_t JOY_PIN[JOYn] = {SEL_JOY_PIN,
+ DOWN_JOY_PIN,
+ LEFT_JOY_PIN,
+ RIGHT_JOY_PIN,
+ UP_JOY_PIN};
+
+const uint8_t JOY_IRQn[JOYn] = {SEL_JOY_EXTI_IRQn,
+ DOWN_JOY_EXTI_IRQn,
+ LEFT_JOY_EXTI_IRQn,
+ RIGHT_JOY_EXTI_IRQn,
+ UP_JOY_EXTI_IRQn};
+
+static I2C_HandleTypeDef heval_I2c = {0};
+
+#if defined(BSP_USE_CMSIS_OS)
+static osSemaphoreId BspI2cSemaphore = 0;
+#endif
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LOW_LEVEL_Private_FunctionPrototypes Private FunctionPrototypes
+ * @{
+ */
+static void I2Cx_MspInit(void);
+static void I2Cx_Init(void);
+static void I2Cx_Write(uint8_t Addr, uint8_t Reg, uint8_t Value);
+static uint8_t I2Cx_Read(uint8_t Addr, uint8_t Reg);
+static HAL_StatusTypeDef I2Cx_ReadMultiple(uint8_t Addr, uint16_t Reg, uint16_t MemAddSize, uint8_t *Buffer, uint16_t Length);
+static HAL_StatusTypeDef I2Cx_WriteMultiple(uint8_t Addr, uint16_t Reg, uint16_t MemAddSize, uint8_t *Buffer, uint16_t Length);
+static HAL_StatusTypeDef I2Cx_IsDeviceReady(uint16_t DevAddress, uint32_t Trials);
+static void I2Cx_Error(uint8_t Addr);
+
+/* HDMI IO functions */
+void HDMI_IO_Init(void);
+void HDMI_IO_Delay(uint32_t Delay);
+void HDMI_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value);
+uint8_t HDMI_IO_Read(uint8_t Addr, uint8_t Reg);
+
+/* AUDIO IO functions */
+void AUDIO_IO_Init(void);
+void AUDIO_IO_DeInit(void);
+void AUDIO_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value);
+uint16_t AUDIO_IO_Read(uint8_t Addr, uint16_t Reg);
+void AUDIO_IO_Delay(uint32_t Delay);
+
+/* CAMERA IO functions */
+void CAMERA_IO_Init(void);
+void CAMERA_Delay(uint32_t Delay);
+void CAMERA_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value);
+uint16_t CAMERA_IO_Read(uint8_t Addr, uint16_t Reg);
+
+/* I2C EEPROM IO function */
+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);
+
+/* TouchScreen (TS) IO functions */
+void TS_IO_Init(void);
+void TS_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value);
+uint8_t TS_IO_Read(uint8_t Addr, uint8_t Reg);
+uint16_t TS_IO_ReadMultiple(uint8_t Addr, uint8_t Reg, uint8_t *Buffer, uint16_t Length);
+void TS_IO_WriteMultiple(uint8_t Addr, uint8_t Reg, uint8_t *Buffer, uint16_t Length);
+void TS_IO_Delay(uint32_t Delay);
+
+/* LCD Display IO functions */
+void OTM8009A_IO_Delay(uint32_t Delay);
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_BSP_Exported_Functions BSP Exported Functions
+ * @{
+ */
+
+/**
+ * @brief BSP Error Notification
+ * @note Defined as a weak function to be overwritten by the application.
+ * @retval None
+ */
+__weak void BSP_ErrorNotify(void)
+{
+}
+
+ /**
+ * @brief This method returns the STM32H747I Discovery BSP Driver revision
+ * @retval version: 0xXYZR (8bits for each decimal, R for RC)
+ */
+uint32_t BSP_GetVersion(void)
+{
+ return __STM32H747I_DISCOVERY_BSP_VERSION;
+}
+
+/**
+ * @brief Configures LED GPIO.
+ * @param Led: LED to be configured.
+ * This parameter can be one of the following values:
+ * @arg DISCO_LED1
+ * @arg DISCO_LED2
+ * @arg DISCO_LED3
+ * @arg DISCO_LED4
+ * @retval None
+ */
+void BSP_LED_Init(Led_TypeDef Led)
+{
+ GPIO_InitTypeDef GPIO_InitStruct;
+
+ /* Enable the GPIO_LED clock */
+ LEDx_GPIO_CLK_ENABLE();
+
+ /* Configure the GPIO_LED pin */
+ GPIO_InitStruct.Pin = GPIO_PIN[Led];
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+
+ HAL_GPIO_Init(GPIO_PORT[Led], &GPIO_InitStruct);
+
+ /* By default, turn off LED */
+ HAL_GPIO_WritePin(GPIO_PORT[Led], GPIO_PIN[Led], GPIO_PIN_SET);
+}
+
+
+/**
+ * @brief DeInit LEDs.
+ * @param Led: LED to be configured.
+ * This parameter can be one of the following values:
+ * @arg DISCO_LED1
+ * @arg DISCO_LED2
+ * @arg DISCO_LED3
+ * @arg DISCO_LED4
+ * @note Led DeInit does not disable the GPIO clock
+ * @retval None
+ */
+void BSP_LED_DeInit(Led_TypeDef Led)
+{
+ /* Turn off LED */
+ HAL_GPIO_WritePin(GPIO_PORT[Led], GPIO_PIN[Led], GPIO_PIN_RESET);
+ /* Configure the GPIO_LED pin */
+ HAL_GPIO_DeInit(GPIO_PORT[Led], GPIO_PIN[Led]);
+}
+
+/**
+ * @brief Turns selected LED On.
+ * @param Led: LED to be set on
+ * This parameter can be one of the following values:
+ * @arg DISCO_LED1
+ * @arg DISCO_LED2
+ * @arg DISCO_LED3
+ * @arg DISCO_LED4
+ * @retval None
+ */
+void BSP_LED_On(Led_TypeDef Led)
+{
+ HAL_GPIO_WritePin(GPIO_PORT[Led], GPIO_PIN[Led], GPIO_PIN_RESET);
+}
+
+/**
+ * @brief Turns selected LED Off.
+ * @param Led: LED to be set off
+ * This parameter can be one of the following values:
+ * @arg DISCO_LED1
+ * @arg DISCO_LED2
+ * @arg DISCO_LED3
+ * @arg DISCO_LED4
+ * @retval None
+ */
+void BSP_LED_Off(Led_TypeDef Led)
+{
+ HAL_GPIO_WritePin(GPIO_PORT[Led], GPIO_PIN[Led], GPIO_PIN_SET);
+}
+
+/**
+ * @brief Toggles the selected LED.
+ * @param Led: LED to be toggled
+ * This parameter can be one of the following values:
+ * @arg DISCO_LED1
+ * @arg DISCO_LED2
+ * @arg DISCO_LED3
+ * @arg DISCO_LED4
+ * @retval None
+ */
+void BSP_LED_Toggle(Led_TypeDef Led)
+{
+ HAL_GPIO_TogglePin(GPIO_PORT[Led], GPIO_PIN[Led]);
+}
+
+/**
+ * @brief Configures button GPIO and EXTI Line.
+ * @param Button: Button to be configured
+ * This parameter can be one of the following values:
+ * @arg BUTTON_WAKEUP: Wakeup Push Button
+ * @arg BUTTON_USER: User Push Button
+ * @param Button_Mode: Button mode
+ * This parameter can be one of the following values:
+ * @arg BUTTON_MODE_GPIO: Button will be used as simple IO
+ * @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line
+ * with interrupt generation capability
+ * @retval None
+ */
+void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef Button_Mode)
+{
+ GPIO_InitTypeDef GPIO_InitStruct;
+
+ /* Enable the BUTTON clock */
+ BUTTON_GPIO_CLK_ENABLE();
+
+ if(Button_Mode == BUTTON_MODE_GPIO)
+ {
+ /* Configure Button pin as input */
+ GPIO_InitStruct.Pin = BUTTON_PIN[Button];
+ GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ HAL_GPIO_Init(BUTTON_PORT[Button], &GPIO_InitStruct);
+ }
+
+ if(Button_Mode == BUTTON_MODE_EXTI)
+ {
+ /* Configure Button pin as input with External interrupt */
+ GPIO_InitStruct.Pin = BUTTON_PIN[Button];
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+
+ GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
+
+ HAL_GPIO_Init(BUTTON_PORT[Button], &GPIO_InitStruct);
+
+ /* Enable and set Button EXTI Interrupt to the lowest priority */
+ HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F, 0x00);
+ HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
+ }
+}
+
+/**
+ * @brief Push Button DeInit.
+ * @param Button: Button to be configured
+ * This parameter can be one of the following values:
+ * @arg BUTTON_WAKEUP: Wakeup Push Button
+ * @arg BUTTON_USER: User Push Button
+ * @note PB DeInit does not disable the GPIO clock
+ * @retval None
+ */
+void BSP_PB_DeInit(Button_TypeDef Button)
+{
+ GPIO_InitTypeDef gpio_init_structure;
+
+ gpio_init_structure.Pin = BUTTON_PIN[Button];
+ HAL_NVIC_DisableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
+ HAL_GPIO_DeInit(BUTTON_PORT[Button], gpio_init_structure.Pin);
+}
+
+
+/**
+ * @brief Returns the selected button state.
+ * @param Button: Button to be checked
+ * This parameter can be one of the following values:
+ * @arg BUTTON_WAKEUP: Wakeup Push Button
+ * @arg BUTTON_USER: User Push Button
+ * @retval The Button GPIO pin value
+ */
+uint32_t BSP_PB_GetState(Button_TypeDef Button)
+{
+ return HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]);
+}
+
+/**
+ * @brief Configures all joystick's buttons in GPIO or EXTI modes.
+ * @param Joy_Mode: Joystick mode.
+ * This parameter can be one of the following values:
+ * @arg JOY_MODE_GPIO: Joystick pins will be used as simple IOs
+ * @arg JOY_MODE_EXTI: Joystick pins will be connected to EXTI line
+ * with interrupt generation capability
+ * @retval HAL_OK: if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_JOY_Init(JOYMode_TypeDef Joy_Mode)
+{
+ JOYState_TypeDef joykey;
+ GPIO_InitTypeDef GPIO_InitStruct;
+
+ /* Initialized the Joystick. */
+ for(joykey = JOY_SEL; joykey < (JOY_SEL + JOYn) ; joykey++)
+ {
+ /* Enable the JOY clock */
+ JOYx_GPIO_CLK_ENABLE(joykey);
+
+ GPIO_InitStruct.Pin = JOY_PIN[joykey];
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+
+ if (Joy_Mode == JOY_MODE_GPIO)
+ {
+ /* Configure Joy pin as input */
+ GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+ HAL_GPIO_Init(JOY_PORT[joykey], &GPIO_InitStruct);
+ }
+ else if (Joy_Mode == JOY_MODE_EXTI)
+ {
+ /* Configure Joy pin as input with External interrupt */
+ GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
+ HAL_GPIO_Init(JOY_PORT[joykey], &GPIO_InitStruct);
+
+ /* Enable and set Joy EXTI Interrupt to the lowest priority */
+ HAL_NVIC_SetPriority((IRQn_Type)(JOY_IRQn[joykey]), 0x0F, 0x00);
+ HAL_NVIC_EnableIRQ((IRQn_Type)(JOY_IRQn[joykey]));
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Un-configures all GPIOs used as joystick's buttons.
+ * @retval None.
+ */
+void BSP_JOY_DeInit(void)
+{
+ JOYState_TypeDef joykey;
+
+ /* Initialized the Joystick. */
+ for(joykey = JOY_SEL; joykey < (JOY_SEL + JOYn) ; joykey++)
+ {
+ /* Enable the JOY clock */
+ JOYx_GPIO_CLK_ENABLE(joykey);
+
+ HAL_GPIO_DeInit(JOY_PORT[joykey], JOY_PIN[joykey]);
+ }
+}
+
+/**
+* @brief Returns the current joystick status.
+* @retval Code of the joystick key pressed
+* This code can be one of the following values:
+* @arg JOY_NONE
+* @arg JOY_SEL
+* @arg JOY_DOWN
+* @arg JOY_LEFT
+* @arg JOY_RIGHT
+* @arg JOY_UP
+*/
+JOYState_TypeDef BSP_JOY_GetState(void)
+{
+ JOYState_TypeDef joykey;
+
+ for (joykey = JOY_SEL; joykey < (JOY_SEL + JOYn) ; joykey++)
+ {
+ if (HAL_GPIO_ReadPin(JOY_PORT[joykey], JOY_PIN[joykey]) == GPIO_PIN_RESET)
+ {
+ /* Return Code Joystick key pressed */
+ return joykey;
+ }
+ }
+
+ /* No Joystick key pressed */
+ return JOY_NONE;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LOW_LEVEL_Private_Functions Private Functions
+ * @{
+ */
+/*******************************************************************************
+ BUS OPERATIONS
+*******************************************************************************/
+
+/******************************* I2C Routines *********************************/
+/**
+ * @brief Initializes I2C MSP.
+ * @retval None
+ */
+static void I2Cx_MspInit(void)
+{
+ GPIO_InitTypeDef gpio_init_structure;
+ RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
+
+ /* Configure the I2C clock source */
+ RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C123;
+ RCC_PeriphClkInit.I2c123ClockSelection = RCC_I2C123CLKSOURCE_D2PCLK1;
+ HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
+
+ /* set STOPWUCK in RCC_CFGR */
+ __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);
+
+ /*** Configure the GPIOs ***/
+ /* Enable GPIO clock */
+ DISCOVERY_I2Cx_SCL_SDA_GPIO_CLK_ENABLE();
+
+ /* Configure I2C Tx as alternate function */
+ gpio_init_structure.Pin = DISCOVERY_I2Cx_SCL_PIN;
+ gpio_init_structure.Mode = GPIO_MODE_AF_OD;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ gpio_init_structure.Alternate = DISCOVERY_I2Cx_SCL_SDA_AF;
+ HAL_GPIO_Init(DISCOVERY_I2Cx_SCL_SDA_GPIO_PORT, &gpio_init_structure);
+
+ /* Configure I2C Rx as alternate function */
+ gpio_init_structure.Pin = DISCOVERY_I2Cx_SDA_PIN;
+ HAL_GPIO_Init(DISCOVERY_I2Cx_SCL_SDA_GPIO_PORT, &gpio_init_structure);
+
+ /*** Configure the I2C peripheral ***/
+ /* Enable I2C clock */
+ DISCOVERY_I2Cx_CLK_ENABLE();
+
+ /* Force the I2C peripheral clock reset */
+ DISCOVERY_I2Cx_FORCE_RESET();
+
+ /* Release the I2C peripheral clock reset */
+ DISCOVERY_I2Cx_RELEASE_RESET();
+
+ /* Enable and set I2Cx Interrupt to a lower priority */
+ HAL_NVIC_SetPriority(DISCOVERY_I2Cx_EV_IRQn, 0x0F, 0);
+ HAL_NVIC_EnableIRQ(DISCOVERY_I2Cx_EV_IRQn);
+
+ /* Enable and set I2Cx Interrupt to a lower priority */
+ HAL_NVIC_SetPriority(DISCOVERY_I2Cx_ER_IRQn, 0x0F, 0);
+ HAL_NVIC_EnableIRQ(DISCOVERY_I2Cx_ER_IRQn);
+}
+
+/**
+ * @brief Initializes I2C HAL.
+ * @retval None
+ */
+static void I2Cx_Init(void)
+{
+ if(HAL_I2C_GetState(&heval_I2c) == HAL_I2C_STATE_RESET)
+ {
+#if defined(BSP_USE_CMSIS_OS)
+ if(BspI2cSemaphore == NULL)
+ {
+ /* Create semaphore to prevent multiple I2C access */
+ osSemaphoreDef(BSP_I2C_SEM);
+ BspI2cSemaphore = osSemaphoreCreate(osSemaphore(BSP_I2C_SEM), 1);
+ }
+#endif
+
+ heval_I2c.Instance = DISCOVERY_I2Cx;
+ heval_I2c.Init.Timing = DISCOVERY_I2Cx_TIMING;
+ heval_I2c.Init.OwnAddress1 = 0x72;
+ heval_I2c.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
+ heval_I2c.Init.DualAddressMode = I2C_DUALADDRESS_ENABLE;
+ heval_I2c.Init.OwnAddress2 = 0;
+ heval_I2c.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
+ heval_I2c.Init.GeneralCallMode = I2C_GENERALCALL_ENABLE;
+ heval_I2c.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
+
+ /* Init the I2C */
+ I2Cx_MspInit();
+ HAL_I2C_Init(&heval_I2c);
+ }
+}
+
+/**
+ * @brief Writes a single data.
+ * @param Addr: I2C address
+ * @param Reg: Register address
+ * @param Value: Data to be written
+ * @retval None
+ */
+static void I2Cx_Write(uint8_t Addr, uint8_t Reg, uint8_t Value)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+#if defined(BSP_USE_CMSIS_OS)
+ /* Get semaphore to prevent multiple I2C access */
+ osSemaphoreWait(BspI2cSemaphore, osWaitForever);
+#endif
+
+ status = HAL_I2C_Mem_Write(&heval_I2c, Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, &Value, 1, 100);
+
+#if defined(BSP_USE_CMSIS_OS)
+ /* Release semaphore to prevent multiple I2C access */
+ osSemaphoreRelease(BspI2cSemaphore);
+#endif
+
+ /* Check the communication status */
+ if(status != HAL_OK)
+ {
+ /* Execute user timeout callback */
+ I2Cx_Error(Addr);
+ }
+}
+
+/**
+ * @brief Reads a single data.
+ * @param Addr: I2C address
+ * @param Reg: Register address
+ * @retval Read data
+ */
+static uint8_t I2Cx_Read(uint8_t Addr, uint8_t Reg)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ uint8_t Value = 0;
+
+#if defined(BSP_USE_CMSIS_OS)
+ /* Get semaphore to prevent multiple I2C access */
+ osSemaphoreWait(BspI2cSemaphore, osWaitForever);
+#endif
+
+ status = HAL_I2C_Mem_Read(&heval_I2c, Addr, Reg, I2C_MEMADD_SIZE_8BIT, &Value, 1, 1000);
+
+#if defined(BSP_USE_CMSIS_OS)
+ /* Release semaphore to prevent multiple I2C access */
+ osSemaphoreRelease(BspI2cSemaphore);
+#endif
+
+ /* Check the communication status */
+ if(status != HAL_OK)
+ {
+ /* Execute user timeout callback */
+ I2Cx_Error(Addr);
+ }
+ return Value;
+}
+
+/**
+ * @brief Reads multiple data.
+ * @param Addr: I2C address
+ * @param Reg: Reg address
+ * @param MemAddress: memory address
+ * @param Buffer: Pointer to data buffer
+ * @param Length: Length of the data
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2Cx_ReadMultiple(uint8_t Addr, uint16_t Reg, uint16_t MemAddress, uint8_t *Buffer, uint16_t Length)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+#if defined(BSP_USE_CMSIS_OS)
+ /* Get semaphore to prevent multiple I2C access */
+ osSemaphoreWait(BspI2cSemaphore, osWaitForever);
+#endif
+
+ status = HAL_I2C_Mem_Read(&heval_I2c, Addr, (uint16_t)Reg, MemAddress, Buffer, Length, 1000);
+
+#if defined(BSP_USE_CMSIS_OS)
+ /* Release semaphore to prevent multiple I2C access */
+ osSemaphoreRelease(BspI2cSemaphore);
+#endif
+
+ /* Check the communication status */
+ if(status != HAL_OK)
+ {
+ /* I2C error occurred */
+ I2Cx_Error(Addr);
+ }
+ return status;
+}
+
+/**
+ * @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 MemAddress: memory address
+ * @param Buffer: The target register value to be written
+ * @param Length: buffer size to be written
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2Cx_WriteMultiple(uint8_t Addr, uint16_t Reg, uint16_t MemAddress, uint8_t *Buffer, uint16_t Length)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+#if defined(BSP_USE_CMSIS_OS)
+ /* Get semaphore to prevent multiple I2C access */
+ osSemaphoreWait(BspI2cSemaphore, osWaitForever);
+#endif
+
+ status = HAL_I2C_Mem_Write(&heval_I2c, Addr, (uint16_t)Reg, MemAddress, Buffer, Length, 1000);
+
+#if defined(BSP_USE_CMSIS_OS)
+ /* Release semaphore to prevent multiple I2C access */
+ osSemaphoreRelease(BspI2cSemaphore);
+#endif
+
+ /* Check the communication status */
+ if(status != HAL_OK)
+ {
+ /* Re-Initiaize the I2C Bus */
+ I2Cx_Error(Addr);
+ }
+ 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)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+#if defined(BSP_USE_CMSIS_OS)
+ /* Get semaphore to prevent multiple I2C access */
+ osSemaphoreWait(BspI2cSemaphore, osWaitForever);
+#endif
+
+ status = HAL_I2C_IsDeviceReady(&heval_I2c, DevAddress, Trials, 1000);
+
+#if defined(BSP_USE_CMSIS_OS)
+ /* Release semaphore to prevent multiple I2C access */
+ osSemaphoreRelease(BspI2cSemaphore);
+#endif
+
+ return status;
+}
+
+/**
+ * @brief Manages error callback by re-initializing I2C.
+ * @param Addr: I2C Address
+ * @retval None
+ */
+static void I2Cx_Error(uint8_t Addr)
+{
+ BSP_ErrorNotify();
+
+ /* De-initialize the I2C comunication bus */
+ HAL_I2C_DeInit(&heval_I2c);
+
+ /* Re-Initialize the I2C communication bus */
+ I2Cx_Init();
+
+#if defined(BSP_USE_CMSIS_OS)
+ /* Release semaphore to prevent multiple I2C access */
+ osSemaphoreRelease(BspI2cSemaphore);
+#endif
+}
+
+/*******************************************************************************
+ LINK OPERATIONS
+*******************************************************************************/
+
+/********************************* LINK AUDIO *********************************/
+
+/**
+ * @brief Initializes Audio low level.
+ * @retval None
+ */
+void AUDIO_IO_Init(void)
+{
+ I2Cx_Init();
+}
+
+/**
+ * @brief De-Initializes Audio low level.
+ * @retval None
+ */
+void AUDIO_IO_DeInit(void)
+{
+}
+
+/**
+ * @brief Writes a single data.
+ * @param Addr: I2C address
+ * @param Reg: Reg address
+ * @param Value: Data to be written
+ * @retval None
+ */
+void AUDIO_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value)
+{
+ uint16_t tmp = Value;
+
+ Value = ((uint16_t)(tmp >> 8) & 0x00FF);
+
+ Value |= ((uint16_t)(tmp << 8)& 0xFF00);
+
+ I2Cx_WriteMultiple(Addr, Reg, I2C_MEMADD_SIZE_16BIT,(uint8_t*)&Value, 2);
+}
+
+/**
+ * @brief Reads a single data.
+ * @param Addr: I2C address
+ * @param Reg: Reg address
+ * @retval Data to be read
+ */
+uint16_t AUDIO_IO_Read(uint8_t Addr, uint16_t Reg)
+{
+ uint16_t read_value = 0, tmp = 0;
+
+ I2Cx_ReadMultiple(Addr, Reg, I2C_MEMADD_SIZE_16BIT, (uint8_t*)&read_value, 2);
+
+ tmp = ((uint16_t)(read_value >> 8) & 0x00FF);
+
+ tmp |= ((uint16_t)(read_value << 8)& 0xFF00);
+
+ read_value = tmp;
+
+ return read_value;
+}
+
+/**
+ * @brief AUDIO Codec delay
+ * @param Delay: Delay in ms
+ * @retval None
+ */
+void AUDIO_IO_Delay(uint32_t Delay)
+{
+ HAL_Delay(Delay);
+}
+
+/********************************* LINK CAMERA ********************************/
+
+/**
+ * @brief Initializes Camera low level.
+ * @retval None
+ */
+void CAMERA_IO_Init(void)
+{
+ I2Cx_Init();
+}
+
+/**
+ * @brief Camera writes single data.
+ * @param Addr: I2C address
+ * @param Reg: Register address
+ * @param Value: Data to be written
+ * @retval None
+ */
+void CAMERA_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value)
+{
+
+ I2Cx_WriteMultiple(Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT,(uint8_t*)&Value, 1);
+
+}
+
+/**
+ * @brief Camera reads single data.
+ * @param Addr: I2C address
+ * @param Reg: Register address
+ * @retval Read data
+ */
+uint16_t CAMERA_IO_Read(uint8_t Addr, uint16_t Reg)
+{
+
+ uint16_t Read_Value = 0;
+
+ I2Cx_ReadMultiple(Addr, Reg, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&Read_Value, 1);
+
+ return Read_Value;
+
+}
+
+/**
+ * @brief Camera delay
+ * @param Delay: Delay in ms
+ * @retval None
+ */
+void CAMERA_Delay(uint32_t Delay)
+{
+ HAL_Delay(Delay);
+}
+
+/******************************** LINK I2C EEPROM *****************************/
+
+/**
+ * @brief Initializes peripherals used by the I2C EEPROM driver.
+ * @retval None
+ */
+void EEPROM_IO_Init(void)
+{
+ I2Cx_Init();
+}
+
+/**
+ * @brief Write 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_WriteMultiple(DevAddress, MemAddress, I2C_MEMADD_SIZE_16BIT, pBuffer, BufferSize));
+}
+
+/**
+ * @brief Read 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_ReadMultiple(DevAddress, MemAddress, I2C_MEMADD_SIZE_16BIT, 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));
+}
+
+/******************************** LINK TS (TouchScreen) *****************************/
+
+/**
+ * @brief Initialize I2C communication
+ * channel from MCU to TouchScreen (TS).
+ */
+void TS_IO_Init(void)
+{
+ I2Cx_Init();
+}
+
+/**
+ * @brief Writes single data with I2C communication
+ * channel from MCU to TouchScreen.
+ * @param Addr: I2C address
+ * @param Reg: Register address
+ * @param Value: Data to be written
+ */
+void TS_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value)
+{
+ I2Cx_Write(Addr, Reg, Value);
+}
+
+/**
+ * @brief Reads single data with I2C communication
+ * channel from TouchScreen.
+ * @param Addr: I2C address
+ * @param Reg: Register address
+ * @retval Read data
+ */
+uint8_t TS_IO_Read(uint8_t Addr, uint8_t Reg)
+{
+ return I2Cx_Read(Addr, Reg);
+}
+
+/**
+ * @brief Reads multiple data with I2C communication
+ * channel from TouchScreen.
+ * @param Addr: I2C address
+ * @param Reg: Register address
+ * @param Buffer: Pointer to data buffer
+ * @param Length: Length of the data
+ * @retval Number of read data
+ */
+uint16_t TS_IO_ReadMultiple(uint8_t Addr, uint8_t Reg, uint8_t *Buffer, uint16_t Length)
+{
+ return I2Cx_ReadMultiple(Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, Buffer, Length);
+}
+
+/**
+ * @brief Writes multiple data with I2C communication
+ * channel from MCU to TouchScreen.
+ * @param Addr: I2C address
+ * @param Reg: Register address
+ * @param Buffer: Pointer to data buffer
+ * @param Length: Length of the data
+ * @retval None
+ */
+void TS_IO_WriteMultiple(uint8_t Addr, uint8_t Reg, uint8_t *Buffer, uint16_t Length)
+{
+ I2Cx_WriteMultiple(Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, Buffer, Length);
+}
+
+/**
+ * @brief Delay function used in TouchScreen low level driver.
+ * @param Delay: Delay in ms
+ * @retval None
+ */
+void TS_IO_Delay(uint32_t Delay)
+{
+ HAL_Delay(Delay);
+}
+
+/**************************** LINK OTM8009A (Display driver) ******************/
+/**
+ * @brief OTM8009A delay
+ * @param Delay: Delay in ms
+ */
+void OTM8009A_IO_Delay(uint32_t Delay)
+{
+ HAL_Delay(Delay);
+}
+
+#if defined(USE_LCD_HDMI)
+/**************************** LINK ADV7533 DSI-HDMI (Display driver) **********/
+/**
+ * @brief Initializes HDMI IO low level.
+ * @retval None
+ */
+void HDMI_IO_Init(void)
+{
+ I2Cx_Init();
+}
+
+/**
+ * @brief HDMI writes single data.
+ * @param Addr: I2C address
+ * @param Reg: Register address
+ * @param Value: Data to be written
+ * @retval None
+ */
+void HDMI_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value)
+{
+ I2Cx_Write(Addr, Reg, Value);
+}
+
+/**
+ * @brief Reads single data with I2C communication
+ * channel from HDMI bridge.
+ * @param Addr: I2C address
+ * @param Reg: Register address
+ * @retval Read data
+ */
+uint8_t HDMI_IO_Read(uint8_t Addr, uint8_t Reg)
+{
+ return I2Cx_Read(Addr, Reg);
+}
+
+/**
+ * @brief HDMI delay
+ * @param Delay: Delay in ms
+ * @retval None
+ */
+void HDMI_IO_Delay(uint32_t Delay)
+{
+ HAL_Delay(Delay);
+}
+#endif /* USE_LCD_HDMI */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,361 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery.h
+ * @author MCD Application Team
+ * @brief This file contains definitions for STM32H747I-Discovery LEDs,
+ * push-buttons hardware resources.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32H747I_DISCOVERY_H
+#define __STM32H747I_DISCOVERY_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+#if defined(BSP_USE_CMSIS_OS)
+#include "cmsis_os.h"
+#endif
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY_LOW_LEVEL
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LOW_LEVEL_Exported_Types Exported Types
+ * @{
+ */
+
+/** @brief Led_TypeDef
+ * STM32H747I_DISCOVERY board leds definitions.
+ */
+typedef enum
+{
+ DISCO_LED1 = 0,
+ LED_GREEN = DISCO_LED1,
+ DISCO_LED2 = 1,
+ LED_ORANGE = DISCO_LED2,
+ DISCO_LED3 = 2,
+ LED_RED = DISCO_LED3,
+ DISCO_LED4 = 3,
+ LED_BLUE = DISCO_LED4
+} Led_TypeDef;
+
+/** @brief Button_TypeDef
+ * STM32H747I_DISCOVERY board Buttons definitions.
+ */
+typedef enum
+{
+ BUTTON_WAKEUP = 0,
+} Button_TypeDef;
+
+#define BUTTON_USER BUTTON_WAKEUP
+
+/** @brief ButtonMode_TypeDef
+ * STM32H747I_DISCOVERY board Buttons Modes definitions.
+ */
+typedef enum
+{
+ BUTTON_MODE_GPIO = 0,
+ BUTTON_MODE_EXTI = 1
+} ButtonMode_TypeDef;
+
+
+typedef enum
+{
+ PB_SET = 0,
+ PB_RESET = !PB_SET
+} ButtonValue_TypeDef;
+
+typedef enum
+{
+ JOY_MODE_GPIO = 0,
+ JOY_MODE_EXTI = 1
+} JOYMode_TypeDef;
+
+typedef enum
+{
+ JOY_SEL = 0,
+ JOY_DOWN = 1,
+ JOY_LEFT = 2,
+ JOY_RIGHT = 3,
+ JOY_UP = 4,
+ JOY_NONE = 5
+} JOYState_TypeDef;
+
+/** @brief DISCO_Status_TypeDef
+ * STM32H747I_DISCO board Status return possible values.
+ */
+typedef enum
+{
+ DISCO_OK = 0,
+ DISCO_ERROR = 1
+} DISCO_Status_TypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LOW_LEVEL_Exported_Constants Exported Constants
+ * @{
+ */
+
+/**
+ * @brief Define for STM32H747I_DISCOVERY board
+ */
+#if !defined (USE_STM32H747I_DISCO)
+ #define USE_STM32H747I_DISCO
+#endif
+
+#define LEDn ((uint32_t)4)
+
+#define LED1_GPIO_PORT GPIOI
+#define LED1_PIN GPIO_PIN_12
+
+#define LED2_GPIO_PORT GPIOI
+#define LED2_PIN GPIO_PIN_13
+
+#define LED3_GPIO_PORT GPIOI
+#define LED3_PIN GPIO_PIN_14
+
+#define LED4_GPIO_PORT GPIOI
+#define LED4_PIN GPIO_PIN_15
+
+#define LEDx_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define LEDx_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+
+/* Only one User/Wakeup button */
+#define BUTTONn ((uint8_t)1)
+
+/**
+ * @brief Wakeup push-button
+ */
+#define WAKEUP_BUTTON_PIN GPIO_PIN_13
+#define WAKEUP_BUTTON_GPIO_PORT GPIOC
+#define WAKEUP_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define WAKEUP_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
+#define WAKEUP_BUTTON_EXTI_IRQn EXTI15_10_IRQn
+
+/* Define the USER button as an alias of the Wakeup button */
+#define USER_BUTTON_PIN WAKEUP_BUTTON_PIN
+#define USER_BUTTON_GPIO_PORT WAKEUP_BUTTON_GPIO_PORT
+#define USER_BUTTON_GPIO_CLK_ENABLE() WAKEUP_BUTTON_GPIO_CLK_ENABLE()
+#define USER_BUTTON_GPIO_CLK_DISABLE() WAKEUP_BUTTON_GPIO_CLK_DISABLE()
+#define USER_BUTTON_EXTI_IRQn WAKEUP_BUTTON_EXTI_IRQn
+
+#define BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+
+#define JOYn ((uint8_t)5)
+
+/**
+ * @brief Joystick Selection push-button
+ */
+#define SEL_JOY_PIN GPIO_PIN_2
+#define SEL_JOY_GPIO_PORT GPIOK
+#define SEL_JOY_GPIO_CLK_ENABLE() __HAL_RCC_GPIOK_CLK_ENABLE()
+#define SEL_JOY_GPIO_CLK_DISABLE() __HAL_RCC_GPIOK_CLK_DISABLE()
+#define SEL_JOY_EXTI_IRQn EXTI2_IRQn
+
+/**
+* @brief Joystick Down push-button
+*/
+#define DOWN_JOY_PIN GPIO_PIN_3
+#define DOWN_JOY_GPIO_PORT GPIOK
+#define DOWN_JOY_GPIO_CLK_ENABLE() __HAL_RCC_GPIOK_CLK_ENABLE()
+#define DOWN_JOY_GPIO_CLK_DISABLE() __HAL_RCC_GPIOK_CLK_DISABLE()
+#define DOWN_JOY_EXTI_IRQn EXTI3_IRQn
+
+/**
+* @brief Joystick Left push-button
+*/
+#define LEFT_JOY_PIN GPIO_PIN_4
+#define LEFT_JOY_GPIO_PORT GPIOK
+#define LEFT_JOY_GPIO_CLK_ENABLE() __HAL_RCC_GPIOK_CLK_ENABLE()
+#define LEFT_JOY_GPIO_CLK_DISABLE() __HAL_RCC_GPIOK_CLK_DISABLE()
+#define LEFT_JOY_EXTI_IRQn EXTI4_IRQn
+
+/**
+ * @brief Joystick Right push-button
+ */
+#define RIGHT_JOY_PIN GPIO_PIN_5
+#define RIGHT_JOY_GPIO_PORT GPIOK
+#define RIGHT_JOY_GPIO_CLK_ENABLE() __HAL_RCC_GPIOK_CLK_ENABLE()
+#define RIGHT_JOY_GPIO_CLK_DISABLE() __HAL_RCC_GPIOK_CLK_DISABLE()
+#define RIGHT_JOY_EXTI_IRQn EXTI9_5_IRQn
+
+/**
+* @brief Joystick Up push-button
+*/
+#define UP_JOY_PIN GPIO_PIN_6
+#define UP_JOY_GPIO_PORT GPIOK
+#define UP_JOY_GPIO_CLK_ENABLE() __HAL_RCC_GPIOK_CLK_ENABLE()
+#define UP_JOY_GPIO_CLK_DISABLE() __HAL_RCC_GPIOK_CLK_DISABLE()
+#define UP_JOY_EXTI_IRQn EXTI9_5_IRQn
+
+#define JOYx_GPIO_CLK_ENABLE(__JOY__) do { if((__JOY__) == JOY_SEL) { SEL_JOY_GPIO_CLK_ENABLE(); } else \
+ if((__JOY__) == JOY_DOWN) { DOWN_JOY_GPIO_CLK_ENABLE(); } else \
+ if((__JOY__) == JOY_LEFT) { LEFT_JOY_GPIO_CLK_ENABLE(); } else \
+ if((__JOY__) == JOY_RIGHT) { RIGHT_JOY_GPIO_CLK_ENABLE(); } else \
+ if((__JOY__) == JOY_UP) { UP_JOY_GPIO_CLK_ENABLE(); } } while(0)
+
+#define JOYx_GPIO_CLK_DISABLE(__JOY__) do { if((__JOY__) == JOY_SEL) { SEL_JOY_GPIO_CLK_DISABLE(); } else \
+ if((__JOY__) == JOY_DOWN) { DOWN_JOY_GPIO_CLK_DISABLE(); } else \
+ if((__JOY__) == JOY_LEFT) { LEFT_JOY_GPIO_CLK_DISABLE(); } else \
+ if((__JOY__) == JOY_RIGHT) { RIGHT_JOY_GPIO_CLK_DISABLE(); } else \
+ if((__JOY__) == JOY_UP) { UP_JOY_GPIO_CLK_DISABLE(); } } while(0)
+
+#define JOY_ALL_PINS (RIGHT_JOY_PIN | LEFT_JOY_PIN | UP_JOY_PIN | DOWN_JOY_PIN | SEL_JOY_PIN)
+
+
+/**
+ * @brief USB OTG HS Over Current signal
+ */
+#define OTG_HS_OVER_CURRENT_PIN GPIO_PIN_1
+#define OTG_HS_OVER_CURRENT_PORT GPIOJ
+#define OTG_HS_OVER_CURRENT_PORT_CLK_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE()
+
+/**
+ * @brief SD-detect signal
+ */
+#define SD_DETECT_PIN ((uint32_t)GPIO_PIN_8)
+#define SD_DETECT_GPIO_PORT ((GPIO_TypeDef*)GPIOI)
+#define SD_DETECT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE()
+#define SD_DETECT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE()
+#define SD_DETECT_EXTI_IRQn EXTI9_5_IRQn
+
+/**
+ * @brief TS_INT signal from TouchScreen when it is configured in interrupt mode
+ * GPIOI13 is used for that purpose on Manta Dragon Discovery board
+ */
+#define TS_INT_PIN ((uint32_t)GPIO_PIN_7)
+#define TS_INT_GPIO_PORT ((GPIO_TypeDef*)GPIOK)
+#define TS_INT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOK_CLK_ENABLE()
+#define TS_INT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOK_CLK_DISABLE()
+#define TS_INT_EXTI_IRQn EXTI9_5_IRQn
+
+/**
+ * @brief TouchScreen FT6206 Slave I2C address 1
+ */
+#define TS_I2C_ADDRESS ((uint16_t)0x54)
+
+/**
+ * @brief TouchScreen FT6336G Slave I2C address 2
+ */
+#define TS_I2C_ADDRESS_A02 ((uint16_t)0x70)
+
+/**
+ * @brief LCD DSI Slave I2C address 1
+ */
+#define LCD_DSI_ADDRESS TS_I2C_ADDRESS
+
+/**
+ * @brief LCD DSI Slave I2C address 2
+ */
+#define LCD_DSI_ADDRESS_A02 TS_I2C_ADDRESS_A02
+
+/**
+ * @brief Audio I2C Slave address
+ */
+#define AUDIO_I2C_ADDRESS ((uint16_t)0x34)
+
+#define CAMERA_I2C_ADDRESS ((uint16_t)0x60)
+
+/**
+ * @brief User can use this section to tailor I2C4/I2C4 instance used and associated
+ * resources (audio codec).
+ * Definition for I2C4 clock resources
+ */
+#define DISCOVERY_I2Cx I2C4
+#define DISCOVERY_I2Cx_CLK_ENABLE() __HAL_RCC_I2C4_CLK_ENABLE()
+#define DISCOVERY_I2Cx_SCL_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
+
+#define DISCOVERY_I2Cx_FORCE_RESET() __HAL_RCC_I2C4_FORCE_RESET()
+#define DISCOVERY_I2Cx_RELEASE_RESET() __HAL_RCC_I2C4_RELEASE_RESET()
+
+/** @brief Definition for I2C4 Pins
+ */
+#define DISCOVERY_I2Cx_SCL_PIN GPIO_PIN_12 /*!< PD12 */
+#define DISCOVERY_I2Cx_SDA_PIN GPIO_PIN_13 /*!< PD13 */
+#define DISCOVERY_I2Cx_SCL_SDA_AF GPIO_AF4_I2C4
+#define DISCOVERY_I2Cx_SCL_SDA_GPIO_PORT GPIOD
+/** @brief Definition of I2C4 interrupt requests
+ */
+#define DISCOVERY_I2Cx_EV_IRQn I2C4_EV_IRQn
+#define DISCOVERY_I2Cx_ER_IRQn I2C4_ER_IRQn
+
+/* I2C TIMING Register define when I2C clock source is SYSCLK */
+/* I2C TIMING is calculated from APB1 source clock = 50 MHz */
+/* Due to the big MOFSET capacity for adapting the camera level the rising time is very large (>1us) */
+/* 0x40912732 takes in account the big rising and aims a clock of 100khz */
+#ifndef DISCOVERY_I2Cx_TIMING
+#define DISCOVERY_I2Cx_TIMING ((uint32_t)0x40912732)
+#endif /* DISCOVERY_I2Cx_TIMING */
+
+/**
+ * @}
+ */
+
+
+/** @addtogroup STM32H747I_DISCOVERY_LOW_LEVEL_Exported_Functions
+ * @{
+ */
+uint32_t BSP_GetVersion(void);
+void BSP_LED_Init(Led_TypeDef Led);
+void BSP_LED_DeInit(Led_TypeDef Led);
+void BSP_LED_On(Led_TypeDef Led);
+void BSP_LED_Off(Led_TypeDef Led);
+void BSP_LED_Toggle(Led_TypeDef Led);
+void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef Button_Mode);
+void BSP_PB_DeInit(Button_TypeDef Button);
+uint32_t BSP_PB_GetState(Button_TypeDef Button);
+uint8_t BSP_JOY_Init(JOYMode_TypeDef Joy_Mode);
+void BSP_JOY_DeInit(void);
+JOYState_TypeDef BSP_JOY_GetState(void);
+void BSP_ErrorNotify(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32H747I_DISCOVERY_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery_audio.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,1627 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery_audio.c
+ * @author MCD Application Team
+ * @brief This file provides the Audio driver for the STM32H747I-DISCOVERY
+ * board.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ + This driver supports STM32H7xx devices on STM32H747I-DISCOVERY (MB1248) Discovery boards.
+ + Call the function BSP_AUDIO_OUT_Init(
+ OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER,
+ OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
+ Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
+ AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...)
+ this parameter is relative to the audio file/stream type.
+ )
+ This function configures all the hardware required for the audio application (codec, I2C, SAI,
+ GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
+ If the returned value is different from AUDIO_OK or the function is stuck then the communication with
+ the codec has failed (try to un-plug the power or reset device in this case).
+ - OUTPUT_DEVICE_SPEAKER : only speaker will be set as output for the audio stream.
+ - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
+ - OUTPUT_DEVICE_BOTH : both Speaker and Headphone are used as outputs for the audio stream
+ at the same time.
+ Note. On STM32H747I-DISCOVERY SAI_DMA is configured in CIRCULAR mode. Due to this the application
+ does NOT need to call BSP_AUDIO_OUT_ChangeBuffer() to assure streaming.
+ + Call the function BSP_AUDIO_OUT_Play(
+ pBuffer: pointer to the audio data file address
+ Size : size of the buffer to be sent in Bytes
+ )
+ to start playing (for the first time) from the audio file/stream.
+ + Call the function BSP_AUDIO_OUT_Pause() to pause playing
+ + Call the function BSP_AUDIO_OUT_Resume() to resume playing.
+ Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
+ for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
+ Note. This function should be called only when the audio file is played or paused (not stopped).
+ + For each mode, you may need to implement the relative callback functions into your code.
+ The Callback functions are named BSP_AUDIO_OUT_XXX_CallBack() and only their prototypes are declared in
+ the stm32h747i_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
+ + To Stop playing, to modify the volume level, the frequency, the audio frame slot,
+ the device output mode the mute or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(),
+ AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetAudioFrameSlot(), BSP_AUDIO_OUT_SetOutputMode(),
+ BSP_AUDIO_OUT_SetMute() and BSP_AUDIO_OUT_Stop().
+
+ + Call the function BSP_AUDIO_IN_Init(
+ AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000...)
+ this parameter is relative to the audio file/stream type.
+ BitRes: Bit resolution fixed to 16bit
+ ChnlNbr: Number of channel to be configured for the DFSDM peripheral
+ )
+ This function configures all the hardware required for the audio in application (channels,
+ Clock source for SAI PDM periphiral, GPIOs, DMA and interrupt if needed).
+ This function returns AUDIO_OK if configuration is OK.If the returned value is different from AUDIO_OK then
+ the configuration should be wrong.
+ + Call the function BSP_AUDIO_IN_AllocScratch(
+ pScratch: pointer to scratch tables
+ size: size of scratch buffer)
+ This function must be called before BSP_AUDIO_IN_RECORD() to allocate buffer scratch for each DFSDM channel
+ and its size.
+ Note: These buffers scratch are used as intermidiate buffers to collect data within final record buffer.
+ size is the total size of the four buffers scratch; If size is 512 then the size of each is 128.
+ This function must be called after BSP_AUDIO_IN_Init()
+ + Call the function BSP_AUDIO_IN_RECORD(
+ pBuf: pointer to the recorded audio data file address
+ Size: size of the buffer to be written in Bytes
+ )
+ to start recording from microphones.
+
+ + Call the function BSP_AUDIO_IN_Pause() to pause recording
+ + Call the function BSP_AUDIO_IN_Resume() to recording playing.
+ Note. After calling BSP_AUDIO_IN_Pause() function for pause, only BSP_AUDIO_IN_Resume() should be called
+ for resume (it is not allowed to call BSP_AUDIO_IN_RECORD() in this case).
+ + Call the function BSP_AUDIO_IN_Stop() to stop recording
+ + For each mode, you may need to implement the relative callback functions into your code.
+ The Callback functions are named BSP_AUDIO_IN_XXX_CallBack() and only their prototypes are declared in
+ the stm32h747i_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
+ + Call the function BSP_AUDIO_IN_SelectInterface(uint32_t Interface) to select one of the two interfaces
+ available on the STM32H747I-Discovery board: SAI or PDM. This function is to be called before BSP_AUDIO_IN_InitEx().
+ + Call the function BSP_AUDIO_IN_GetInterface() to get the current used interface.
+ + Call the function BSP_AUDIO_IN_PDMToPCM_Init(uint32_t AudioFreq, uint32_t ChnlNbrIn, uint32_t ChnlNbrOut)
+ to init PDM filters if the libPDMFilter is used for audio data filtering.
+ + Call the function BSP_AUDIO_IN_PDMToPCM(uint16_t* PDMBuf, uint16_t* PCMBuf) to filter PDM data to PCM format
+ if the libPDMFilter library is used for audio data filtering.
+
+ Driver architecture:
+ --------------------
+ + This driver provides the High Audio Layer: consists of the function API exported in the stm32h747i_discovery_audio.h file
+ (BSP_AUDIO_OUT_Init(), BSP_AUDIO_OUT_Play() ...)
+ + This driver provide also the Media Access Layer (MAL): which consists of functions allowing to access the media containing/
+ providing the audio file/stream. These functions are also included as local functions into
+ the stm32h747i_discovery_audio.c file (DFSDMx_Init(), DFSDMx_DeInit(), SAIx_Init() and SAIx_DeInit())
+
+ Known Limitations:
+ ------------------
+ 1- If the TDM Format used to play in parallel 2 audio Stream (the first Stream is configured in codec SLOT0 and second
+ Stream in SLOT1) the Pause/Resume, volume and mute feature will control the both streams.
+ 2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size,
+ File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
+ 3- Supports only Stereo audio streaming.
+ 4- Supports only 16-bits audio data size.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h747i_discovery_audio.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_AUDIO STM32H747I_DISCOVERY_AUDIO
+ * @brief This file includes the low layer driver for wm8994 Audio Codec
+ * available on STM32H747I-DISCOVERY discovery board(MB1248).
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_AUDIO_Private_Variables Private Variables
+ * @{
+ */
+/* PLAY */
+AUDIO_DrvTypeDef *audio_drv;
+SAI_HandleTypeDef haudio_out_sai;
+SAI_HandleTypeDef haudio_in_sai;
+
+/* RECORD */
+AUDIOIN_ContextTypeDef hAudioIn;
+
+
+
+/* Audio in Volume value */
+__IO uint16_t AudioInVolume = DEFAULT_AUDIO_IN_VOLUME;
+
+/* PDM filters params */
+PDM_Filter_Handler_t PDM_FilterHandler[2];
+PDM_Filter_Config_t PDM_FilterConfig[2];
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_AUDIO_Private_Function_Prototypes Private FunctionPrototypes
+ * @{
+ */
+static void SAIx_Out_Init(uint32_t SaiOutMode, uint32_t SlotActive, uint32_t AudioFreq);
+static void SAIx_Out_DeInit(SAI_HandleTypeDef *hsai);
+static void SAIx_In_MspInit(SAI_HandleTypeDef *hsai, void *Params);
+static void SAIx_In_MspDeInit(SAI_HandleTypeDef *hsai, void *Params);
+static void SAIx_In_Init(uint32_t SaiInMode, uint32_t SlotActive, uint32_t AudioFreq);
+static void SAIx_In_DeInit(SAI_HandleTypeDef *hsai);
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_AUDIO_OUT_Exported_Functions OUT Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Configures the audio Out peripheral.
+ * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
+ * or OUTPUT_DEVICE_BOTH.
+ * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
+ * @param AudioFreq: Audio frequency used to play the audio stream.
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
+{
+ uint8_t ret = AUDIO_ERROR;
+ uint32_t deviceid = 0x00;
+ uint32_t slot_active;
+
+ /* Initialize SAI1 sub_block A as MASTER TX */
+ haudio_out_sai.Instance = AUDIO_OUT_SAIx;
+
+ /* Disable SAI */
+ SAIx_Out_DeInit(&haudio_out_sai);
+
+ /* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */
+ BSP_AUDIO_OUT_ClockConfig(&haudio_out_sai, AudioFreq, NULL);
+
+ /* SAI data transfer preparation:
+ Prepare the Media to be used for the audio transfer from memory to SAI peripheral */
+
+ if(HAL_SAI_GetState(&haudio_out_sai) == HAL_SAI_STATE_RESET)
+ {
+ /* Init the SAI MSP: this __weak function can be redefined by the application*/
+ BSP_AUDIO_OUT_MspInit(&haudio_out_sai, NULL);
+ }
+
+ /* Init SAI as master RX output */
+ slot_active = CODEC_AUDIOFRAME_SLOT_0123;
+ SAIx_Out_Init(SAI_MODEMASTER_TX, slot_active, AudioFreq);
+
+ /* wm8994 codec initialization */
+ deviceid = wm8994_drv.ReadID(AUDIO_I2C_ADDRESS);
+
+ if((deviceid) == WM8994_ID)
+ {
+ /* Reset the Codec Registers */
+ wm8994_drv.Reset(AUDIO_I2C_ADDRESS);
+ /* Initialize the audio driver structure */
+ audio_drv = &wm8994_drv;
+ ret = AUDIO_OK;
+ }
+ else
+ {
+ ret = AUDIO_ERROR;
+ }
+
+ if(ret == AUDIO_OK)
+ {
+ /* Initialize the codec internal registers */
+ audio_drv->Init(AUDIO_I2C_ADDRESS, OutputDevice, Volume, AudioFreq);
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Starts playing audio stream from a data buffer for a determined size.
+ * @param pBuffer: Pointer to the buffer
+ * @param Size: Number of audio data BYTES.
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size)
+{
+ /* Call the audio Codec Play function */
+ if(audio_drv->Play(AUDIO_I2C_ADDRESS, pBuffer, Size) != 0)
+ {
+ return AUDIO_ERROR;
+ }
+ else
+ {
+ /* Update the Media layer and enable it for play */
+ HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pBuffer, DMA_MAX(Size / AUDIODATA_SIZE));
+
+ return AUDIO_OK;
+ }
+}
+
+/**
+ * @brief Sends n-Bytes on the SAI interface.
+ * @param pData: pointer on data address
+ * @param Size: number of data to be written
+ * @retval None
+ */
+void BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size)
+{
+ HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pData, Size);
+}
+
+/**
+ * @brief This function Pauses the audio file stream. In case
+ * of using DMA, the DMA Pause feature is used.
+ * @warning When calling BSP_AUDIO_OUT_Pause() function for pause, only
+ * BSP_AUDIO_OUT_Resume() function should be called for resume (use of BSP_AUDIO_OUT_Play()
+ * function for resume could lead to unexpected behaviour).
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_OUT_Pause(void)
+{
+ /* Call the Audio Codec Pause/Resume function */
+ if(audio_drv->Pause(AUDIO_I2C_ADDRESS) != 0)
+ {
+ return AUDIO_ERROR;
+ }
+ else
+ {
+ /* Call the Media layer pause function */
+ HAL_SAI_DMAPause(&haudio_out_sai);
+
+ /* Return AUDIO_OK when all operations are correctly done */
+ return AUDIO_OK;
+ }
+}
+
+/**
+ * @brief Resumes the audio file stream.
+ * @warning When calling BSP_AUDIO_OUT_Pause() function for pause, only
+ * BSP_AUDIO_OUT_Resume() function should be called for resume (use of BSP_AUDIO_OUT_Play()
+ * function for resume could lead to unexpected behaviour).
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_OUT_Resume(void)
+{
+ /* Call the Audio Codec Pause/Resume function */
+ if(audio_drv->Resume(AUDIO_I2C_ADDRESS) != 0)
+ {
+ return AUDIO_ERROR;
+ }
+ else
+ {
+ /* Call the Media layer pause/resume function */
+ HAL_SAI_DMAResume(&haudio_out_sai);
+
+ /* Return AUDIO_OK when all operations are correctly done */
+ return AUDIO_OK;
+ }
+}
+
+/**
+ * @brief Stops audio playing and Power down the Audio Codec.
+ * @param Option: could be one of the following parameters
+ * - CODEC_PDWN_SW: for software power off (by writing registers).
+ * Then no need to reconfigure the Codec after power on.
+ * - CODEC_PDWN_HW: completely shut down the codec (physically).
+ * Then need to reconfigure the Codec after power on.
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option)
+{
+ /* Call the Media layer stop function */
+ HAL_SAI_DMAStop(&haudio_out_sai);
+
+ /* Call Audio Codec Stop function */
+ if(audio_drv->Stop(AUDIO_I2C_ADDRESS, Option) != 0)
+ {
+ return AUDIO_ERROR;
+ }
+ else
+ {
+ if(Option == CODEC_PDWN_HW)
+ {
+ /* Wait at least 100us */
+ HAL_Delay(1);
+ }
+ /* Return AUDIO_OK when all operations are correctly done */
+ return AUDIO_OK;
+ }
+}
+
+/**
+ * @brief Controls the current audio volume level.
+ * @param Volume: Volume level to be set in percentage from 0% to 100% (0 for
+ * Mute and 100 for Max volume level).
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume)
+{
+ /* Call the codec volume control function with converted volume value */
+ if(audio_drv->SetVolume(AUDIO_I2C_ADDRESS, Volume) != 0)
+ {
+ return AUDIO_ERROR;
+ }
+ else
+ {
+ /* Return AUDIO_OK when all operations are correctly done */
+ return AUDIO_OK;
+ }
+}
+
+/**
+ * @brief Enables or disables the MUTE mode by software
+ * @param Cmd: Could be AUDIO_MUTE_ON to mute sound or AUDIO_MUTE_OFF to
+ * unmute the codec and restore previous volume level.
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd)
+{
+ /* Call the Codec Mute function */
+ if(audio_drv->SetMute(AUDIO_I2C_ADDRESS, Cmd) != 0)
+ {
+ return AUDIO_ERROR;
+ }
+ else
+ {
+ /* Return AUDIO_OK when all operations are correctly done */
+ return AUDIO_OK;
+ }
+}
+
+/**
+ * @brief Switch dynamically (while audio file is played) the output target
+ * (speaker or headphone).
+ * @param Output: The audio output target: OUTPUT_DEVICE_SPEAKER,
+ * OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output)
+{
+ /* Call the Codec output device function */
+ if(audio_drv->SetOutputMode(AUDIO_I2C_ADDRESS, Output) != 0)
+ {
+ return AUDIO_ERROR;
+ }
+ else
+ {
+ /* Return AUDIO_OK when all operations are correctly done */
+ return AUDIO_OK;
+ }
+}
+
+/**
+ * @brief Updates the audio frequency.
+ * @param AudioFreq: Audio frequency used to play the audio stream.
+ * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
+ * audio frequency.
+ * @retval None
+ */
+void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq)
+{
+ /* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */
+ BSP_AUDIO_OUT_ClockConfig(&haudio_out_sai, AudioFreq, NULL);
+
+ /* Disable SAI peripheral to allow access to SAI internal registers */
+ __HAL_SAI_DISABLE(&haudio_out_sai);
+
+ /* Update the SAI audio frequency configuration */
+ haudio_out_sai.Init.AudioFrequency = AudioFreq;
+ HAL_SAI_Init(&haudio_out_sai);
+
+ /* Enable SAI peripheral to generate MCLK */
+ __HAL_SAI_ENABLE(&haudio_out_sai);
+}
+
+/**
+ * @brief Updates the Audio frame slot configuration.
+ * @param AudioFrameSlot: specifies the audio Frame slot
+ * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
+ * audio frame slot.
+ * @retval None
+ */
+void BSP_AUDIO_OUT_SetAudioFrameSlot(uint32_t AudioFrameSlot)
+{
+ /* Disable SAI peripheral to allow access to SAI internal registers */
+ __HAL_SAI_DISABLE(&haudio_out_sai);
+
+ /* Update the SAI audio frame slot configuration */
+ haudio_out_sai.SlotInit.SlotActive = AudioFrameSlot;
+ HAL_SAI_Init(&haudio_out_sai);
+
+ /* Enable SAI peripheral to generate MCLK */
+ __HAL_SAI_ENABLE(&haudio_out_sai);
+}
+
+/**
+ * @brief De-initializes the audio out peripheral.
+ * @retval None
+ */
+void BSP_AUDIO_OUT_DeInit(void)
+{
+ SAIx_Out_DeInit(&haudio_out_sai);
+ /* DeInit the SAI MSP : this __weak function can be rewritten by the application */
+ BSP_AUDIO_OUT_MspDeInit(&haudio_out_sai, NULL);
+}
+
+/**
+ * @brief Manages the DMA full Transfer complete event.
+ * @retval None
+ */
+__weak void BSP_AUDIO_OUT_TransferComplete_CallBack(void)
+{
+}
+
+/**
+ * @brief Manages the DMA Half Transfer complete event.
+ * @retval None
+ */
+__weak void BSP_AUDIO_OUT_HalfTransfer_CallBack(void)
+{
+}
+
+/**
+ * @brief Manages the DMA FIFO error event.
+ * @retval None
+ */
+__weak void BSP_AUDIO_OUT_Error_CallBack(void)
+{
+}
+
+/**
+ * @brief Initializes BSP_AUDIO_OUT MSP.
+ * @param hsai: SAI handle
+ * @param Params: pointer on additional configuration parameters, can be NULL.
+ * @retval None
+ */
+__weak void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params)
+{
+ static DMA_HandleTypeDef hdma_sai_tx;
+ GPIO_InitTypeDef gpio_init_structure;
+
+ /* Enable SAI clock */
+ AUDIO_OUT_SAIx_CLK_ENABLE();
+
+ /* CODEC_SAI pins configuration: FS, SCK and SD pins */
+ /* Enable FS, SCK and SD clocks */
+ AUDIO_OUT_SAIx_SD_FS_CLK_ENABLE();
+ /* Enable FS, SCK and SD pins */
+ gpio_init_structure.Pin = AUDIO_OUT_SAIx_FS_PIN | AUDIO_OUT_SAIx_SCK_PIN | AUDIO_OUT_SAIx_SD_PIN;
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ gpio_init_structure.Alternate = AUDIO_OUT_SAIx_AF;
+ HAL_GPIO_Init(AUDIO_OUT_SAIx_SD_FS_SCK_GPIO_PORT, &gpio_init_structure);
+
+ /* Enable MCLK clock */
+ AUDIO_OUT_SAIx_MCLK_ENABLE();
+ /* Enable MCLK pin */
+ gpio_init_structure.Pin = AUDIO_OUT_SAIx_MCLK_PIN;
+ HAL_GPIO_Init(AUDIO_OUT_SAIx_MCLK_GPIO_PORT, &gpio_init_structure);
+
+ /* Enable the DMA clock */
+ AUDIO_OUT_SAIx_DMAx_CLK_ENABLE();
+
+ if(hsai->Instance == AUDIO_OUT_SAIx)
+ {
+ /* Configure the hdma_saiTx handle parameters */
+ hdma_sai_tx.Init.Request = AUDIO_OUT_SAIx_DMAx_REQUEST;
+ hdma_sai_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ hdma_sai_tx.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_sai_tx.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_sai_tx.Init.PeriphDataAlignment = AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE;
+ hdma_sai_tx.Init.MemDataAlignment = AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE;
+ hdma_sai_tx.Init.Mode = DMA_CIRCULAR;
+ hdma_sai_tx.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_sai_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
+ hdma_sai_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_sai_tx.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_sai_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+ hdma_sai_tx.Instance = AUDIO_OUT_SAIx_DMAx_STREAM;
+
+ /* Associate the DMA handle */
+ __HAL_LINKDMA(hsai, hdmatx, hdma_sai_tx);
+
+ /* Deinitialize the Stream for new transfer */
+ HAL_DMA_DeInit(&hdma_sai_tx);
+
+ /* Configure the DMA Stream */
+ HAL_DMA_Init(&hdma_sai_tx);
+ }
+
+ /* SAI DMA IRQ Channel configuration */
+ HAL_NVIC_SetPriority(AUDIO_OUT_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
+ HAL_NVIC_EnableIRQ(AUDIO_OUT_SAIx_DMAx_IRQ);
+}
+
+/**
+ * @brief Deinitializes SAI MSP.
+ * @param hsai: SAI handle
+ * @param Params: pointer on additional configuration parameters, can be NULL.
+ * @retval None
+ */
+__weak void BSP_AUDIO_OUT_MspDeInit(SAI_HandleTypeDef *hsai, void *Params)
+{
+ GPIO_InitTypeDef gpio_init_structure;
+
+ /* SAI DMA IRQ Channel deactivation */
+ HAL_NVIC_DisableIRQ(AUDIO_OUT_SAIx_DMAx_IRQ);
+
+ if(hsai->Instance == AUDIO_OUT_SAIx)
+ {
+ /* Deinitialize the DMA stream */
+ HAL_DMA_DeInit(hsai->hdmatx);
+ }
+
+ /* Disable SAI peripheral */
+ __HAL_SAI_DISABLE(hsai);
+
+ /* Deactivates CODEC_SAI pins FS, SCK, MCK and SD by putting them in input mode */
+ gpio_init_structure.Pin = AUDIO_OUT_SAIx_FS_PIN | AUDIO_OUT_SAIx_SCK_PIN | AUDIO_OUT_SAIx_SD_PIN;
+ HAL_GPIO_DeInit(AUDIO_OUT_SAIx_SD_FS_SCK_GPIO_PORT, gpio_init_structure.Pin);
+
+ gpio_init_structure.Pin = AUDIO_OUT_SAIx_MCLK_PIN;
+ HAL_GPIO_DeInit(AUDIO_OUT_SAIx_MCLK_GPIO_PORT, gpio_init_structure.Pin);
+
+ /* Disable SAI clock */
+ AUDIO_OUT_SAIx_CLK_DISABLE();
+
+ /* GPIO pins clock and DMA clock can be shut down in the applic
+ by surcharging this __weak function */
+}
+
+/**
+ * @brief Clock Config.
+ * @param hsai: might be required to set audio peripheral predivider if any.
+ * @param AudioFreq: Audio frequency used to play the audio stream.
+ * @param Params: pointer on additional configuration parameters, can be NULL.
+ * @note This API is called by BSP_AUDIO_OUT_Init() and BSP_AUDIO_OUT_SetFrequency()
+ * Being __weak it can be overwritten by the application
+ * @retval None
+ */
+__weak void BSP_AUDIO_OUT_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params)
+{
+ RCC_PeriphCLKInitTypeDef rcc_ex_clk_init_struct;
+
+ HAL_RCCEx_GetPeriphCLKConfig(&rcc_ex_clk_init_struct);
+
+ /* Set the PLL configuration according to the audio frequency */
+ if((AudioFreq == AUDIO_FREQUENCY_11K) || (AudioFreq == AUDIO_FREQUENCY_22K) || (AudioFreq == AUDIO_FREQUENCY_44K))
+ {
+ /* SAI clock config:
+ PLL2_VCO Input = HSE_VALUE/PLL2M = 1 Mhz
+ PLL2_VCO Output = PLL2_VCO Input * PLL2N = 429 Mhz
+ SAI_CLK_x = PLL2_VCO Output/PLL2P = 429/38 = 11.289 Mhz */
+ rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
+ rcc_ex_clk_init_struct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
+ rcc_ex_clk_init_struct.PLL2.PLL2P = 38;
+ rcc_ex_clk_init_struct.PLL2.PLL2Q = 1;
+ rcc_ex_clk_init_struct.PLL2.PLL2R = 1;
+ rcc_ex_clk_init_struct.PLL2.PLL2N = 429;
+ rcc_ex_clk_init_struct.PLL2.PLL2M = 25;
+ HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
+ }
+ else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */
+ {
+ /* SAI clock config:
+ PLL2_VCO Input = HSE_VALUE/PLL2M = 1 Mhz
+ PLL2_VCO Output = PLL2_VCO Input * PLL2N = 344 Mhz
+ SAI_CLK_x = PLL2_VCO Output/PLL2P = 344/7 = 49.142 Mhz */
+ rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
+ rcc_ex_clk_init_struct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
+ rcc_ex_clk_init_struct.PLL2.PLL2P = 7;
+ rcc_ex_clk_init_struct.PLL2.PLL2Q = 1;
+ rcc_ex_clk_init_struct.PLL2.PLL2R = 1;
+ rcc_ex_clk_init_struct.PLL2.PLL2N = 344;
+ rcc_ex_clk_init_struct.PLL2.PLL2M = 25;
+ HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_AUDIO_OUT_Private_Functions OUT Private Functions
+ * @{
+ */
+
+/*******************************************************************************
+ HAL Callbacks
+*******************************************************************************/
+/**
+ * @brief Tx Transfer completed callbacks.
+ * @param hsai: SAI handle
+ * @retval None
+ */
+void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
+{
+ /* Manage the remaining file size and new address offset: This function
+ should be coded by user (its prototype is already declared in stm32h747i_discovery_audio.h) */
+ BSP_AUDIO_OUT_TransferComplete_CallBack();
+}
+
+/**
+ * @brief Tx Half Transfer completed callbacks.
+ * @param hsai: SAI handle
+ * @retval None
+ */
+void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
+{
+ /* Manage the remaining file size and new address offset: This function
+ should be coded by user (its prototype is already declared in stm32h747i_discovery_audio.h) */
+ BSP_AUDIO_OUT_HalfTransfer_CallBack();
+}
+
+/**
+ * @brief SAI error callbacks.
+ * @param hsai: SAI handle
+ * @retval None
+ */
+void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
+{
+ if(hsai->Instance == AUDIO_OUT_SAIx)
+ {
+ BSP_AUDIO_OUT_Error_CallBack();
+ }
+ else
+ {
+ BSP_AUDIO_IN_Error_CallBack();
+ }
+}
+
+/*******************************************************************************
+ Static Functions
+*******************************************************************************/
+
+/**
+ * @brief Initializes the Audio Codec audio interface (SAI).
+ * @param SaiOutMode: Audio mode to be configured for the SAI peripheral.
+ * @param SlotActive: Audio active slot to be configured for the SAI peripheral.
+ * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
+ * @note The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123
+ * and user can update this configuration using
+ * @retval None
+ */
+static void SAIx_Out_Init(uint32_t SaiOutMode, uint32_t SlotActive, uint32_t AudioFreq)
+{
+ /* Disable SAI peripheral to allow access to SAI internal registers */
+ __HAL_SAI_DISABLE(&haudio_out_sai);
+
+ /* Configure SAI_Block_x
+ LSBFirst: Disabled
+ DataSize: 16 */
+ haudio_out_sai.Init.MonoStereoMode = SAI_STEREOMODE;
+ haudio_out_sai.Init.AudioFrequency = AudioFreq;
+ haudio_out_sai.Init.AudioMode = SaiOutMode;
+ haudio_out_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
+ haudio_out_sai.Init.Protocol = SAI_FREE_PROTOCOL;
+ haudio_out_sai.Init.DataSize = SAI_DATASIZE_16;
+ haudio_out_sai.Init.FirstBit = SAI_FIRSTBIT_MSB;
+ haudio_out_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
+ haudio_out_sai.Init.Synchro = SAI_ASYNCHRONOUS;
+ haudio_out_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
+ haudio_out_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
+ haudio_out_sai.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
+ haudio_out_sai.Init.CompandingMode = SAI_NOCOMPANDING;
+ haudio_out_sai.Init.TriState = SAI_OUTPUT_NOTRELEASED;
+ haudio_out_sai.Init.Mckdiv = 0;
+ haudio_out_sai.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
+ haudio_out_sai.Init.PdmInit.Activation = DISABLE;
+ haudio_out_sai.Init.PdmInit.ClockEnable = 0;
+ haudio_out_sai.Init.PdmInit.MicPairsNbr = 0;
+
+ /* Configure SAI_Block_x Frame
+ Frame Length: 64
+ Frame active Length: 32
+ FS Definition: Start frame + Channel Side identification
+ FS Polarity: FS active Low
+ FS Offset: FS asserted one bit before the first bit of slot 0 */
+ haudio_out_sai.FrameInit.FrameLength = 128;
+ haudio_out_sai.FrameInit.ActiveFrameLength = 64;
+ haudio_out_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
+ haudio_out_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
+ haudio_out_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
+
+ /* Configure SAI Block_x Slot
+ Slot First Bit Offset: 0
+ Slot Size : 16
+ Slot Number: 4
+ Slot Active: All slot actives */
+ haudio_out_sai.SlotInit.FirstBitOffset = 0;
+ haudio_out_sai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
+ haudio_out_sai.SlotInit.SlotNumber = 4;
+ haudio_out_sai.SlotInit.SlotActive = SlotActive;
+ HAL_SAI_Init(&haudio_out_sai);
+
+ /* Enable SAI peripheral to generate MCLK */
+ __HAL_SAI_ENABLE(&haudio_out_sai);
+}
+
+/**
+ * @brief Deinitializes the Audio Codec audio interface (SAI).
+ * @retval None
+ */
+static void SAIx_Out_DeInit(SAI_HandleTypeDef *hsai)
+{
+ /* Disable SAI peripheral */
+ __HAL_SAI_DISABLE(hsai);
+
+ HAL_SAI_DeInit(hsai);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_AUDIO_IN_Exported_Functions IN Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Initialize wave recording.
+ * @param AudioFreq: Audio frequency to be configured for the DFSDM peripheral.
+ * @param BitRes: Audio frequency to be configured for the DFSDM peripheral.
+ * @param ChnlNbr: Audio frequency to be configured for the DFSDM peripheral.
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
+{
+ /* Set audio in interface to default one */
+ BSP_AUDIO_IN_SelectInterface(AUDIO_IN_INTERFACE_PDM);
+ return BSP_AUDIO_IN_InitEx(INPUT_DEVICE_DIGITAL_MIC, AudioFreq, BitRes, ChnlNbr);
+}
+
+/**
+ * @brief Initialize wave recording.
+ * @param InputDevice: INPUT_DEVICE_DIGITAL_MIC or INPUT_DEVICE_ANALOG_MIC.
+ * @param AudioFreq: Audio frequency to be configured.
+ * @param BitRes: Audio bit resolution to be configured..
+ * @param ChnlNbr: Number of channel to be configured.
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_IN_InitEx(uint16_t InputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
+{
+ uint8_t ret = AUDIO_OK;
+ uint32_t slot_active;
+
+ /* Store the audio record context */
+ hAudioIn.Frequency = AudioFreq;
+ hAudioIn.BitResolution = BitRes;
+ hAudioIn.InputDevice = InputDevice;
+ hAudioIn.ChannelNbr = ChnlNbr;
+
+ if(hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC)
+ {
+ if(hAudioIn.Interface == AUDIO_IN_INTERFACE_SAI)
+ {
+ /* Initialize SAI1 block B as SLAVE RX synchrounous with SAI1 block A */
+ haudio_in_sai.Instance = AUDIO_IN_SAIx;
+
+ /* Disable SAI */
+ SAIx_In_DeInit(&haudio_in_sai);
+
+ /* PLL clock is set depending on the AudioFreq (44.1khz vs 48khz groups) */
+ BSP_AUDIO_IN_ClockConfig(AudioFreq, NULL); /* Clock config is shared between AUDIO IN and OUT */
+
+ /* SAI data transfer preparation:
+ Prepare the Media to be used for the audio transfer from SAI peripheral to memory */
+ if(HAL_SAI_GetState(&haudio_in_sai) == HAL_SAI_STATE_RESET)
+ {
+ /* Init the SAI MSP: this __weak function can be redefined by the application*/
+ BSP_AUDIO_IN_MspInit();
+ }
+
+ /* Configure SAI in master mode :
+ * - SAI1_block_B in slave RX mode synchronous from SAI1_block_A
+ */
+ slot_active = CODEC_AUDIOFRAME_SLOT_13;
+ SAIx_In_Init(SAI_MODESLAVE_RX, slot_active, AudioFreq);
+ }
+ else if(hAudioIn.Interface == AUDIO_IN_INTERFACE_PDM)
+ {
+ /* Initialize SAI1 block A as MASTER RX */
+ haudio_in_sai.Instance = AUDIO_IN_SAI_PDMx;
+
+ /* Disable SAI */
+ SAIx_In_DeInit(&haudio_in_sai);
+
+ /* PLL clock is set depending on the AudioFreq (44.1khz vs 48khz groups) */
+ BSP_AUDIO_IN_ClockConfig(AudioFreq, NULL);
+
+ /* SAI data transfer preparation:
+ Prepare the Media to be used for the audio transfer from SAI peripheral to memory */
+ /* Initialize the haudio_in_sai Instance parameter */
+
+ if(HAL_SAI_GetState(&haudio_in_sai) == HAL_SAI_STATE_RESET)
+ {
+ /* Init the SAI MSP: this __weak function can be redefined by the application*/
+ BSP_AUDIO_IN_MspInit();
+ }
+
+ /* Configure SAI in master mode :
+ * - SAI1_block_A in master RX mode
+ */
+ slot_active = CODEC_AUDIOFRAME_SLOT_0;
+ SAIx_In_Init(SAI_MODEMASTER_RX, slot_active, AudioFreq);
+
+ if(BSP_AUDIO_IN_PDMToPCM_Init(AudioFreq, hAudioIn.ChannelNbr, hAudioIn.ChannelNbr) != AUDIO_OK)
+ {
+ ret = AUDIO_ERROR;
+ }
+ }
+ else
+ {
+ ret = AUDIO_ERROR;
+ }
+ }
+ else
+ {
+ /* Analog Input */
+ ret = AUDIO_ERROR;
+ }
+
+ /* Return AUDIO_OK when all operations are correctly done */
+ return ret;
+}
+
+
+/**
+ * @brief Initializes wave recording and playback in parallel.
+ * @param InputDevice: INPUT_DEVICE_DIGITAL_MICROPHONE_2
+ * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
+ * or OUTPUT_DEVICE_BOTH.
+ * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
+ * @param BitRes: Audio frequency to be configured.
+ * @param ChnlNbr: Channel number.
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_IN_OUT_Init(uint32_t InputDevice, uint32_t OutputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
+{
+ uint32_t slot_active;
+ uint32_t deviceid = 0, ret = AUDIO_OK;
+
+ /* Store the audio record context */
+ hAudioIn.Frequency = AudioFreq;
+ hAudioIn.BitResolution = BitRes;
+ hAudioIn.InputDevice = InputDevice;
+ hAudioIn.ChannelNbr = ChnlNbr;
+
+ /* Input device is Digital MIC2 and Codec interface is SAI */
+ if (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MICROPHONE_2)
+ {
+ haudio_in_sai.Instance = AUDIO_IN_SAIx;
+ haudio_out_sai.Instance = AUDIO_OUT_SAIx;
+
+ /* PLL clock is set depending on the AudioFreq (44.1khz vs 48khz groups) */
+ BSP_AUDIO_OUT_ClockConfig(&haudio_in_sai, AudioFreq, NULL);
+ /* SAI data transfer preparation:
+ Prepare the Media to be used for the audio transfer from SAI peripheral to memory */
+ if(HAL_SAI_GetState(&haudio_in_sai) == HAL_SAI_STATE_RESET)
+ {
+ /* Init the SAI MSP: this __weak function can be redefined by the application*/
+ BSP_AUDIO_IN_MspInit();
+ }
+
+ /* SAI data transfer preparation:
+ Prepare the Media to be used for the audio transfer from memory to SAI peripheral */
+ if(HAL_SAI_GetState(&haudio_out_sai) == HAL_SAI_STATE_RESET)
+ {
+ /* Init the SAI MSP: this __weak function can be redefined by the application*/
+ BSP_AUDIO_OUT_MspInit(&haudio_out_sai, NULL);
+ }
+
+ /* Configure SAI in master TX mode :
+ * - SAI1_block_A in master TX mode
+ * - SAI1_block_B in slave RX mode synchronous from SAI1_block_A
+ */
+ slot_active = CODEC_AUDIOFRAME_SLOT_13;
+ SAIx_In_Init(SAI_MODESLAVE_RX, slot_active, AudioFreq);
+
+ slot_active = CODEC_AUDIOFRAME_SLOT_02;
+ SAIx_Out_Init(SAI_MODEMASTER_TX, slot_active, AudioFreq);
+
+ /* wm8994 codec initialization */
+ deviceid = wm8994_drv.ReadID(AUDIO_I2C_ADDRESS);
+
+ if((deviceid) == WM8994_ID)
+ {
+ /* Reset the Codec Registers */
+ wm8994_drv.Reset(AUDIO_I2C_ADDRESS);
+ /* Initialize the audio driver structure */
+ audio_drv = &wm8994_drv;
+ ret = AUDIO_OK;
+ }
+ else
+ {
+ ret = AUDIO_ERROR;
+ }
+
+ if(ret == AUDIO_OK)
+ {
+ /* Initialize the codec internal registers */
+ audio_drv->Init(AUDIO_I2C_ADDRESS, InputDevice|OutputDevice, 90, AudioFreq);
+ }
+ }
+ else
+ {
+ ret = AUDIO_ERROR;
+ }
+
+ /* Return AUDIO_OK when all operations are correctly done */
+ return ret;
+}
+
+/**
+ * @brief Link digital mic to specified source
+ * @param Interface : Audio In interface for Digital mic. It can be:
+ * AUDIO_IN_INTERFACE_SAI
+ * AUDIO_IN_INTERFACE_PDM
+ * @retval None
+ */
+void BSP_AUDIO_IN_SelectInterface(uint32_t Interface)
+{
+ hAudioIn.Interface = Interface;
+}
+
+/**
+ * @brief Get digital mic interface
+ * @retval Digital mic interface.
+ */
+uint32_t BSP_AUDIO_IN_GetInterface(void)
+{
+ return (hAudioIn.Interface);
+}
+
+/**
+ * @brief Return audio in channel number
+ * @retval Number of channel
+ */
+uint8_t BSP_AUDIO_IN_GetChannelNumber(void)
+{
+ return hAudioIn.ChannelNbr;
+}
+
+/**
+ * @brief Start audio recording.
+ * @param pBuf: Main buffer pointer for the recorded data storing
+ * @param size: Current size of the recorded buffer
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_IN_Record(uint16_t *pBuf, uint32_t size)
+{
+ /* Start the process receive DMA */
+ if(HAL_OK != HAL_SAI_Receive_DMA(&haudio_in_sai, (uint8_t*)pBuf, size))
+ {
+ return AUDIO_ERROR;
+ }
+
+ /* Return AUDIO_OK when all operations are correctly done */
+ return AUDIO_OK;
+}
+
+/**
+ * @brief Stop audio recording.
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_IN_Stop(void)
+{
+ /* Call the Media layer stop function */
+ HAL_SAI_DMAStop(&haudio_in_sai);
+
+ /* Return AUDIO_OK when all operations are correctly done */
+ return AUDIO_OK;
+}
+
+/**
+ * @brief Pause the audio file stream.
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_IN_Pause(void)
+{
+ if (hAudioIn.InputDevice == INPUT_DEVICE_ANALOG_MIC)
+ {
+ return AUDIO_ERROR;
+ }
+ else
+ {
+ /* Call the Media layer pause function */
+ HAL_SAI_DMAPause(&haudio_in_sai);
+ }
+
+ /* Return AUDIO_OK when all operations are correctly done */
+ return AUDIO_OK;
+}
+
+/**
+ * @brief Resume the audio file stream.
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_IN_Resume(void)
+{
+ if (hAudioIn.InputDevice == INPUT_DEVICE_ANALOG_MIC)
+ {
+ return AUDIO_ERROR;
+ }
+ else
+ {
+ /* Call the Media layer resume function */
+ HAL_SAI_DMAResume(&haudio_in_sai);
+ }
+
+ /* Return AUDIO_OK when all operations are correctly done */
+ return AUDIO_OK;
+}
+
+/**
+ * @brief Controls the audio in volume level.
+ * @param Volume: Volume level to be set in percentage from 0% to 100% (0 for
+ * Mute and 100 for Max volume level).
+ * @retval AUDIO_OK if correct communication, else wrong communication
+ */
+uint8_t BSP_AUDIO_IN_SetVolume(uint8_t Volume)
+{
+ /* Set the Global variable AudioInVolume */
+ AudioInVolume = Volume;
+
+ /* Return AUDIO_OK when all operations are correctly done */
+ return AUDIO_OK;
+}
+
+/**
+ * @brief Deinit the audio IN peripherals.
+ * @retval None
+ */
+void BSP_AUDIO_IN_DeInit(void)
+{
+ SAIx_In_DeInit(&haudio_in_sai);
+
+ BSP_AUDIO_IN_MspDeInit();
+}
+
+/**
+* @brief Initialize the PDM library.
+* @param AudioFreq: Audio sampling frequency
+* @param ChnlNbrIn: Number of input audio channels in the PDM buffer
+* @param ChnlNbrOut: Number of desired output audio channels in the resulting PCM buffer
+* @retval None
+*/
+uint8_t BSP_AUDIO_IN_PDMToPCM_Init(uint32_t AudioFreq, uint32_t ChnlNbrIn, uint32_t ChnlNbrOut)
+{
+ uint32_t index = 0;
+
+ /* Enable CRC peripheral to unlock the PDM library */
+ __HAL_RCC_CRC_CLK_ENABLE();
+
+ for(index = 0; index < ChnlNbrIn; index++)
+ {
+ /* Init PDM filters */
+ PDM_FilterHandler[index].bit_order = PDM_FILTER_BIT_ORDER_MSB;
+ PDM_FilterHandler[index].endianness = PDM_FILTER_ENDIANNESS_LE;
+ PDM_FilterHandler[index].high_pass_tap = 2122358088;
+ PDM_FilterHandler[index].out_ptr_channels = ChnlNbrOut;
+ PDM_FilterHandler[index].in_ptr_channels = ChnlNbrIn;
+ PDM_Filter_Init((PDM_Filter_Handler_t *)(&PDM_FilterHandler[index]));
+
+ /* PDM lib config phase */
+ PDM_FilterConfig[index].output_samples_number = AudioFreq/1000;
+ PDM_FilterConfig[index].mic_gain = 24;
+ PDM_FilterConfig[index].decimation_factor = PDM_FILTER_DEC_FACTOR_64;
+ PDM_Filter_setConfig((PDM_Filter_Handler_t *)&PDM_FilterHandler[index], &PDM_FilterConfig[index]);
+ }
+
+ return AUDIO_OK;
+}
+
+
+/**
+* @brief Converts audio format from PDM to PCM.
+
+* @param PDMBuf: Pointer to PDM buffer data
+* @param PCMBuf: Pointer to PCM buffer data
+* @retval AUDIO_OK in case of success, AUDIO_ERROR otherwise
+*/
+uint8_t BSP_AUDIO_IN_PDMToPCM(uint16_t *PDMBuf, uint16_t *PCMBuf)
+{
+ uint32_t index = 0;
+
+ for(index = 0; index < hAudioIn.ChannelNbr; index++)
+ {
+ PDM_Filter(&((uint8_t*)(PDMBuf))[index], (uint16_t*)&(PCMBuf[index]), &PDM_FilterHandler[index]);
+ }
+
+ return AUDIO_OK;
+}
+
+/**
+ * @brief User callback when record buffer is filled.
+ * @retval None
+ */
+__weak void BSP_AUDIO_IN_TransferComplete_CallBack(void)
+{
+ /* This function should be implemented by the user application.
+ It is called into this driver when the current buffer is filled
+ to prepare the next buffer pointer and its size. */
+}
+
+/**
+ * @brief Manages the DMA Half Transfer complete event.
+ * @retval None
+ */
+__weak void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
+{
+ /* This function should be implemented by the user application.
+ It is called into this driver when the current buffer is filled
+ to prepare the next buffer pointer and its size. */
+}
+
+/**
+ * @brief User callback when record buffer is filled.
+ * @param InputDevice: INPUT_DEVICE_DIGITAL_MIC1 or INPUT_DEVICE_DIGITAL_MIC2
+ */
+__weak void BSP_AUDIO_IN_TransferComplete_CallBackEx(uint32_t InputDevice)
+{
+ /* This function should be implemented by the user application.
+ It is called into this driver when the current buffer is filled
+ to prepare the next buffer pointer and its size. */
+}
+
+/**
+ * @brief User callback when record buffer is filled.
+ * @param InputDevice: INPUT_DEVICE_DIGITAL_MIC1 or INPUT_DEVICE_DIGITAL_MIC2
+ */
+__weak void BSP_AUDIO_IN_HalfTransfer_CallBackEx(uint32_t InputDevice)
+{
+ /* This function should be implemented by the user application.
+ It is called into this driver when the current buffer is filled
+ to prepare the next buffer pointer and its size. */
+}
+
+/**
+ * @brief Audio IN Error callback function.
+ * @retval None
+ */
+__weak void BSP_AUDIO_IN_Error_CallBack(void)
+{
+ /* This function is called when an Interrupt due to transfer error on or peripheral
+ error occurs. */
+}
+
+/**
+ * @brief Initialize BSP_AUDIO_IN MSP.
+ * @retval None
+ */
+__weak void BSP_AUDIO_IN_MspInit(void)
+{
+ SAIx_In_MspInit(&haudio_in_sai, NULL);
+}
+
+/**
+ * @brief DeInitialize BSP_AUDIO_IN MSP.
+ * @retval None
+ */
+__weak void BSP_AUDIO_IN_MspDeInit(void)
+{
+ SAIx_In_MspDeInit(&haudio_in_sai, NULL);
+}
+
+/**
+ * @brief Clock Config.
+ * @param AudioFreq: Audio frequency used to play the audio stream.
+ * @param Params: pointer on additional configuration parameters, can be NULL.
+ * @note This API is called by BSP_AUDIO_IN_Init()
+ * Being __weak it can be overwritten by the application
+ * @retval None
+ */
+__weak void BSP_AUDIO_IN_ClockConfig(uint32_t AudioFreq, void *Params)
+{
+ RCC_PeriphCLKInitTypeDef rcc_ex_clk_init_struct;
+
+ HAL_RCCEx_GetPeriphCLKConfig(&rcc_ex_clk_init_struct);
+
+ /* Set the PLL configuration according to the audio frequency */
+ if((AudioFreq == AUDIO_FREQUENCY_11K) || (AudioFreq == AUDIO_FREQUENCY_22K) || (AudioFreq == AUDIO_FREQUENCY_44K))
+ {
+ /* SAI clock config:
+ PLL2_VCO Input = HSE_VALUE/PLL2M = 1 Mhz
+ PLL2_VCO Output = PLL2_VCO Input * PLL2N = 429 Mhz
+ SAI_CLK_x = PLL2_VCO Output/PLL2P = 429/38 = 11.289 Mhz */
+ rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
+ rcc_ex_clk_init_struct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
+ rcc_ex_clk_init_struct.PLL2.PLL2P = 38;
+ rcc_ex_clk_init_struct.PLL2.PLL2Q = 1;
+ rcc_ex_clk_init_struct.PLL2.PLL2R = 1;
+ rcc_ex_clk_init_struct.PLL2.PLL2N = 429;
+ rcc_ex_clk_init_struct.PLL2.PLL2M = 25;
+ if (hAudioIn.Interface == AUDIO_IN_INTERFACE_PDM)
+ {
+ rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI4A;
+ rcc_ex_clk_init_struct.Sai4AClockSelection = RCC_SAI4ACLKSOURCE_PLL2;
+ }
+ HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
+
+ }
+ else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_32K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */
+ {
+ /* SAI clock config:
+ PLL2_VCO Input = HSE_VALUE/PLL2M = 1 Mhz
+ PLL2_VCO Output = PLL2_VCO Input * PLL2N = 344 Mhz
+ SAI_CLK_x = PLL2_VCO Output/PLL2P = 344/7 = 49.142 Mhz */
+ rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
+ rcc_ex_clk_init_struct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
+ rcc_ex_clk_init_struct.PLL2.PLL2P = 7;
+ rcc_ex_clk_init_struct.PLL2.PLL2Q = 1;
+ rcc_ex_clk_init_struct.PLL2.PLL2R = 1;
+ rcc_ex_clk_init_struct.PLL2.PLL2N = 344;
+ rcc_ex_clk_init_struct.PLL2.PLL2M = 25;
+ if (hAudioIn.Interface == AUDIO_IN_INTERFACE_PDM)
+ {
+ rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI4A;
+ rcc_ex_clk_init_struct.Sai4AClockSelection = RCC_SAI4ACLKSOURCE_PLL2;
+ }
+ HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
+ }
+}
+/**
+ * @}
+ */
+
+
+/** @defgroup STM32H747I_DISCOVERY_AUDIO_IN_Private_Functions IN Private Functions
+ * @{
+ */
+
+/*******************************************************************************
+ HAL Callbacks
+*******************************************************************************/
+
+/**
+ * @brief Half reception complete callback.
+ * @param hsai: SAI handle.
+ * @retval None
+ */
+void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
+{
+ /* Manage the remaining file size and new address offset: This function should be coded by user */
+ BSP_AUDIO_IN_HalfTransfer_CallBack();
+}
+
+/**
+ * @brief Reception complete callback.
+ * @param hsai: SAI handle.
+ * @retval None
+ */
+void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
+{
+ /* Call the record update function to get the next buffer to fill and its size (size is ignored) */
+ BSP_AUDIO_IN_TransferComplete_CallBack();
+}
+
+/*******************************************************************************
+ Static Functions
+*******************************************************************************/
+/**
+ * @brief Initializes SAI Audio IN MSP.
+ * @param hsai: SAI handle
+ * @param Params: pointer on additional configuration parameters, can be NULL.
+ * @retval None
+ */
+static void SAIx_In_MspInit(SAI_HandleTypeDef *hsai, void *Params)
+{
+ static DMA_HandleTypeDef hdma_sai_rx;
+ GPIO_InitTypeDef gpio_init_structure;
+
+ if(hsai->Instance == AUDIO_IN_SAI_PDMx)
+ {
+ /* Enable SAI clock */
+ AUDIO_IN_SAI_PDMx_CLK_ENABLE();
+
+ AUDIO_IN_SAI_PDMx_CLK_IN_ENABLE();
+ AUDIO_IN_SAI_PDMx_DATA_IN_ENABLE();
+
+ gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_CLK_IN_PIN;
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
+ gpio_init_structure.Alternate = AUDIO_IN_SAI_PDMx_DATA_CLK_AF;
+ HAL_GPIO_Init(AUDIO_IN_SAI_PDMx_CLK_IN_PORT, &gpio_init_structure);
+
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_MEDIUM;
+ gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_DATA_IN_PIN;
+ HAL_GPIO_Init(AUDIO_IN_SAI_PDMx_DATA_IN_PORT, &gpio_init_structure);
+
+ AUDIO_IN_SAI_PDMx_FS_SCK_ENABLE();
+
+ /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
+ gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_FS_PIN | AUDIO_IN_SAI_PDMx_SCK_PIN;
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
+ gpio_init_structure.Alternate = AUDIO_IN_SAI_PDMx_FS_SCK_AF;
+ HAL_GPIO_Init(AUDIO_IN_SAI_PDMx_FS_SCK_GPIO_PORT, &gpio_init_structure);
+
+ /* Enable the DMA clock */
+ AUDIO_IN_SAI_PDMx_DMAx_CLK_ENABLE();
+
+ /* Configure the hdma_sai_rx handle parameters */
+ hdma_sai_rx.Init.Request = AUDIO_IN_SAI_PDMx_DMAx_REQUEST;
+ hdma_sai_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_sai_rx.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_sai_rx.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_sai_rx.Init.PeriphDataAlignment = AUDIO_IN_SAI_PDMx_DMAx_PERIPH_DATA_SIZE;
+ hdma_sai_rx.Init.MemDataAlignment = AUDIO_IN_SAI_PDMx_DMAx_MEM_DATA_SIZE;
+ hdma_sai_rx.Init.Mode = DMA_CIRCULAR;
+ hdma_sai_rx.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_sai_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+ hdma_sai_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_sai_rx.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_sai_rx.Init.PeriphBurst = DMA_MBURST_SINGLE;
+
+ hdma_sai_rx.Instance = AUDIO_IN_SAI_PDMx_DMAx_STREAM;
+
+ /* Associate the DMA handle */
+ __HAL_LINKDMA(hsai, hdmarx, hdma_sai_rx);
+
+ /* Deinitialize the Stream for new transfer */
+ HAL_DMA_DeInit(&hdma_sai_rx);
+
+ /* Configure the DMA Stream */
+ HAL_DMA_Init(&hdma_sai_rx);
+
+ /* SAI DMA IRQ Channel configuration */
+ HAL_NVIC_SetPriority(AUDIO_IN_SAI_PDMx_DMAx_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
+ HAL_NVIC_EnableIRQ(AUDIO_IN_SAI_PDMx_DMAx_IRQ);
+ }
+ else
+ {
+ /* Enable SAI clock */
+ AUDIO_IN_SAIx_CLK_ENABLE();
+
+ /* Enable SD GPIO clock */
+ AUDIO_IN_SAIx_SD_ENABLE();
+ /* CODEC_SAI pin configuration: SD pin */
+ gpio_init_structure.Pin = AUDIO_IN_SAIx_SD_PIN;
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
+ gpio_init_structure.Alternate = AUDIO_IN_SAIx_AF;
+ HAL_GPIO_Init(AUDIO_IN_SAIx_SD_GPIO_PORT, &gpio_init_structure);
+
+ /* Enable Audio INT GPIO clock */
+ AUDIO_IN_INT_GPIO_ENABLE();
+ /* Audio INT pin configuration: input */
+ gpio_init_structure.Pin = AUDIO_IN_INT_GPIO_PIN;
+ gpio_init_structure.Mode = GPIO_MODE_INPUT;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
+ HAL_GPIO_Init(AUDIO_IN_INT_GPIO_PORT, &gpio_init_structure);
+
+ /* Enable the DMA clock */
+ AUDIO_IN_SAIx_DMAx_CLK_ENABLE();
+
+ /* Configure the hdma_sai_rx handle parameters */
+ hdma_sai_rx.Init.Request = AUDIO_IN_SAIx_DMAx_REQUEST;
+ hdma_sai_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_sai_rx.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_sai_rx.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_sai_rx.Init.PeriphDataAlignment = AUDIO_IN_SAIx_DMAx_PERIPH_DATA_SIZE;
+ hdma_sai_rx.Init.MemDataAlignment = AUDIO_IN_SAIx_DMAx_MEM_DATA_SIZE;
+ hdma_sai_rx.Init.Mode = DMA_CIRCULAR;
+ hdma_sai_rx.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_sai_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+ hdma_sai_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_sai_rx.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_sai_rx.Init.PeriphBurst = DMA_MBURST_SINGLE;
+
+ hdma_sai_rx.Instance = AUDIO_IN_SAIx_DMAx_STREAM;
+
+ /* Associate the DMA handle */
+ __HAL_LINKDMA(hsai, hdmarx, hdma_sai_rx);
+
+ /* Deinitialize the Stream for new transfer */
+ HAL_DMA_DeInit(&hdma_sai_rx);
+
+ /* Configure the DMA Stream */
+ HAL_DMA_Init(&hdma_sai_rx);
+
+ /* SAI DMA IRQ Channel configuration */
+ HAL_NVIC_SetPriority(AUDIO_IN_SAIx_DMAx_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
+ HAL_NVIC_EnableIRQ(AUDIO_IN_SAIx_DMAx_IRQ);
+
+ /* Audio INT IRQ Channel configuration */
+ HAL_NVIC_SetPriority(AUDIO_IN_INT_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
+ HAL_NVIC_EnableIRQ(AUDIO_IN_INT_IRQ);
+ }
+}
+
+/**
+ * @brief De-Initializes SAI Audio IN MSP.
+ * @param hsai: SAI handle
+ * @param Params: pointer on additional configuration parameters, can be NULL.
+ * @retval None
+ */
+static void SAIx_In_MspDeInit(SAI_HandleTypeDef *hsai, void *Params)
+{
+ GPIO_InitTypeDef gpio_init_structure;
+
+ if(hsai->Instance == AUDIO_IN_SAI_PDMx)
+ {
+ /* Deinitialize the DMA stream */
+ HAL_DMA_Abort(hsai->hdmarx);
+
+ HAL_SAI_DeInit(hsai);
+ /* Disable SAI peripheral */
+ __HAL_SAI_DISABLE(hsai);
+
+ /* Deinitialize the DMA stream */
+ HAL_DMA_DeInit(hsai->hdmarx);
+
+ gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_CLK_IN_PIN;
+ HAL_GPIO_DeInit(AUDIO_IN_SAI_PDMx_CLK_IN_PORT, gpio_init_structure.Pin);
+
+ gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_DATA_IN_PIN;
+ HAL_GPIO_DeInit(AUDIO_IN_SAI_PDMx_DATA_IN_PORT, gpio_init_structure.Pin);
+
+ /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
+ gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_FS_PIN | AUDIO_IN_SAI_PDMx_SCK_PIN;
+ HAL_GPIO_DeInit(AUDIO_IN_SAI_PDMx_FS_SCK_GPIO_PORT, gpio_init_structure.Pin);
+
+ /* Disable SAI clock */
+ AUDIO_IN_SAI_PDMx_CLK_DISABLE();
+ }
+ else
+ {
+ /* SAI DMA IRQ Channel deactivation */
+ HAL_NVIC_DisableIRQ(AUDIO_IN_SAIx_DMAx_IRQ);
+
+ if(hsai->Instance == AUDIO_IN_SAIx)
+ {
+ /* Deinitialize the DMA stream */
+ HAL_DMA_DeInit(hsai->hdmatx);
+ }
+
+ /* Disable SAI peripheral */
+ __HAL_SAI_DISABLE(hsai);
+
+ /* Deactivates CODEC_SAI pin SD by putting them in input mode */
+ gpio_init_structure.Pin = AUDIO_IN_SAIx_SD_PIN;
+ HAL_GPIO_DeInit(AUDIO_IN_SAIx_SD_GPIO_PORT, gpio_init_structure.Pin);
+
+ gpio_init_structure.Pin = AUDIO_IN_INT_GPIO_PIN;
+ HAL_GPIO_DeInit(AUDIO_IN_INT_GPIO_PORT, gpio_init_structure.Pin);
+
+ /* Disable SAI clock */
+ AUDIO_IN_SAIx_CLK_DISABLE();
+ }
+}
+
+/**
+ * @brief Initializes the Audio Codec audio interface (SAI).
+ * @param SaiInMode: Audio mode to be configured for the SAI peripheral.
+ * @param SlotActive: Audio active slot to be configured for the SAI peripheral.
+ * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
+ * @retval None
+ */
+static void SAIx_In_Init(uint32_t SaiInMode, uint32_t SlotActive, uint32_t AudioFreq)
+{
+ /* Disable SAI peripheral to allow access to SAI internal registers */
+ __HAL_SAI_DISABLE(&haudio_in_sai);
+
+ /* Configure SAI_Block_x
+ LSBFirst: Disabled
+ DataSize: 16 */
+ haudio_in_sai.Init.MonoStereoMode = SAI_STEREOMODE;
+ haudio_in_sai.Init.AudioFrequency = AudioFreq;
+ haudio_in_sai.Init.AudioMode = SaiInMode;
+ haudio_in_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
+ haudio_in_sai.Init.Protocol = SAI_FREE_PROTOCOL;
+ haudio_in_sai.Init.DataSize = SAI_DATASIZE_16;
+ haudio_in_sai.Init.FirstBit = SAI_FIRSTBIT_MSB;
+ haudio_in_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
+ haudio_in_sai.Init.Synchro = SAI_SYNCHRONOUS;
+ haudio_in_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
+ haudio_in_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
+ haudio_in_sai.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
+ haudio_in_sai.Init.CompandingMode = SAI_NOCOMPANDING;
+ haudio_in_sai.Init.TriState = SAI_OUTPUT_RELEASED;
+ haudio_in_sai.Init.Mckdiv = 0;
+ haudio_in_sai.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
+ haudio_in_sai.Init.PdmInit.Activation = DISABLE;
+
+ /* Configure SAI_Block_x Frame
+ Frame Length: 64
+ Frame active Length: 32
+ FS Definition: Start frame + Channel Side identification
+ FS Polarity: FS active Low
+ FS Offset: FS asserted one bit before the first bit of slot 0 */
+ haudio_in_sai.FrameInit.FrameLength = 128;
+ haudio_in_sai.FrameInit.ActiveFrameLength = 64;
+ haudio_in_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
+ haudio_in_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
+ haudio_in_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
+
+ /* Configure SAI Block_x Slot
+ Slot First Bit Offset: 0
+ Slot Size : 16
+ Slot Number: 4
+ Slot Active: All slot active */
+ haudio_in_sai.SlotInit.FirstBitOffset = 0;
+ haudio_in_sai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
+ haudio_in_sai.SlotInit.SlotNumber = 4;
+ haudio_in_sai.SlotInit.SlotActive = SlotActive;
+
+ if(hAudioIn.Interface == AUDIO_IN_INTERFACE_PDM)
+ {
+ haudio_in_sai.Init.AudioFrequency = AudioFreq * 8;
+ haudio_in_sai.Init.Synchro = SAI_ASYNCHRONOUS;
+ haudio_in_sai.Init.NoDivider = SAI_MASTERDIVIDER_DISABLE;
+
+ haudio_in_sai.Init.PdmInit.Activation = ENABLE;
+ haudio_in_sai.Init.PdmInit.MicPairsNbr = 1;
+ haudio_in_sai.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;
+ haudio_in_sai.Init.FirstBit = SAI_FIRSTBIT_LSB;
+ haudio_in_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
+
+ haudio_in_sai.FrameInit.FrameLength = 16;
+ haudio_in_sai.FrameInit.ActiveFrameLength = 1;
+ haudio_in_sai.FrameInit.FSDefinition = SAI_FS_STARTFRAME;
+ haudio_in_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH;
+ haudio_in_sai.FrameInit.FSOffset = SAI_FS_FIRSTBIT;
+
+ haudio_in_sai.SlotInit.SlotNumber = 1;
+ haudio_in_sai.SlotInit.SlotActive = SlotActive;
+ }
+
+ HAL_SAI_Init(&haudio_in_sai);
+
+ /* Enable SAI peripheral */
+ __HAL_SAI_ENABLE(&haudio_in_sai);
+}
+
+/**
+ * @brief De-initializes the output Audio Codec audio interface (SAI).
+ * @retval None
+ */
+static void SAIx_In_DeInit(SAI_HandleTypeDef *hsai)
+{
+ /* Disable SAI peripheral */
+ __HAL_SAI_DISABLE(hsai);
+
+ HAL_SAI_DeInit(hsai);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery_audio.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,342 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery_audio.h
+ * @author MCD Application Team
+ * @brief This file contains the common defines and functions prototypes for
+ * the stm32h747i_discovery_audio.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32H747I_DISCOVERY_AUDIO_H
+#define __STM32H747I_DISCOVERY_AUDIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include audio component Driver */
+#include "../Components/wm8994/wm8994.h"
+#include "stm32h747i_discovery.h"
+#include <stdlib.h>
+/* Include PDM to PCM lib header file */
+#include "pdm2pcm_glo.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY_AUDIO
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_AUDIO_Exported_Types Exported Types
+ * @{
+ */
+typedef struct
+{
+ uint32_t Frequency; /* Record Frequency */
+ uint32_t BitResolution; /* Record bit resolution */
+ uint32_t ChannelNbr; /* Record Channel Number */
+ uint16_t *pRecBuf; /* Pointer to record user buffer */
+ uint32_t RecSize; /* Size to record in mono, double size to record in stereo */
+ uint32_t InputDevice; /* Audio Input Device */
+ uint32_t Interface; /* Audio Input Interface */
+ uint32_t MultiBuffMode; /* Multi buffer mode selection */
+}AUDIOIN_ContextTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_AUDIO_Exported_Constants Exported Constants
+ * @{
+ */
+#define BSP_AUDIO_FREQUENCY_96K SAI_AUDIO_FREQUENCY_96K
+#define BSP_AUDIO_FREQUENCY_48K SAI_AUDIO_FREQUENCY_48K
+#define BSP_AUDIO_FREQUENCY_44K SAI_AUDIO_FREQUENCY_44K
+#define BSP_AUDIO_FREQUENCY_32K SAI_AUDIO_FREQUENCY_32K
+#define BSP_AUDIO_FREQUENCY_22K SAI_AUDIO_FREQUENCY_22K
+#define BSP_AUDIO_FREQUENCY_16K SAI_AUDIO_FREQUENCY_16K
+#define BSP_AUDIO_FREQUENCY_11K SAI_AUDIO_FREQUENCY_11K
+#define BSP_AUDIO_FREQUENCY_8K SAI_AUDIO_FREQUENCY_8K
+
+/*------------------------------------------------------------------------------
+ USER SAI defines parameters
+ -----------------------------------------------------------------------------*/
+/** In W8994 codec the Audio frame contains 4 slots : TDM Mode
+ * TDM format :
+ * +------------------|------------------|--------------------|-------------------+
+ * | CODEC_SLOT0 Left | CODEC_SLOT1 Left | CODEC_SLOT0 Right | CODEC_SLOT1 Right |
+ * +------------------------------------------------------------------------------+
+ */
+/* To have 2 separate audio stream in Both headphone and speaker the 4 slot must be activated */
+#define CODEC_AUDIOFRAME_SLOT_0123 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_2 | SAI_SLOTACTIVE_3
+
+/* To have an audio stream in headphone only SAI Slot 0 and Slot 2 must be activated */
+#define CODEC_AUDIOFRAME_SLOT_02 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_2
+/* To have an audio stream in speaker only SAI Slot 1 and Slot 3 must be activated */
+#define CODEC_AUDIOFRAME_SLOT_13 SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_3
+/* To have an audio stream in SAI PDM input Slot 0 must be activated */
+#define CODEC_AUDIOFRAME_SLOT_0 SAI_SLOTACTIVE_0
+
+/*------------------------------------------------------------------------------
+ AUDIO OUT CONFIGURATION
+------------------------------------------------------------------------------*/
+/* SAI peripheral configuration defines */
+#define AUDIO_OUT_SAIx SAI1_Block_A
+#define AUDIO_OUT_SAIx_CLK_ENABLE() __HAL_RCC_SAI1_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_CLK_DISABLE() __HAL_RCC_SAI1_CLK_DISABLE()
+#define AUDIO_OUT_SAIx_AF GPIO_AF6_SAI1
+
+#define AUDIO_OUT_SAIx_MCLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_MCLK_GPIO_PORT GPIOG
+#define AUDIO_OUT_SAIx_MCLK_PIN GPIO_PIN_7
+#define AUDIO_OUT_SAIx_SD_FS_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_SD_FS_SCK_GPIO_PORT GPIOE
+#define AUDIO_OUT_SAIx_FS_PIN GPIO_PIN_4
+#define AUDIO_OUT_SAIx_SCK_PIN GPIO_PIN_5
+#define AUDIO_OUT_SAIx_SD_PIN GPIO_PIN_6
+
+/* SAI DMA Stream definitions */
+#define AUDIO_OUT_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
+#define AUDIO_OUT_SAIx_DMAx_STREAM DMA2_Stream1
+#define AUDIO_OUT_SAIx_DMAx_REQUEST DMA_REQUEST_SAI1_A
+#define AUDIO_OUT_SAIx_DMAx_IRQ DMA2_Stream1_IRQn
+#define AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
+#define AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
+#define AUDIO_OUT_SAIx_DMAx_IRQHandler DMA2_Stream1_IRQHandler
+
+/* Select the interrupt preemption priority and subpriority for the DMA interrupt */
+#define AUDIO_OUT_IRQ_PREPRIO ((uint32_t)0x0E)
+
+/*------------------------------------------------------------------------------
+ AUDIO IN CONFIGURATION
+------------------------------------------------------------------------------*/
+/* SAI peripheral configuration defines */
+#define AUDIO_IN_SAIx SAI1_Block_B
+#define AUDIO_IN_SAIx_CLK_ENABLE() __HAL_RCC_SAI1_CLK_ENABLE()
+#define AUDIO_IN_SAIx_CLK_DISABLE() __HAL_RCC_SAI1_CLK_DISABLE()
+#define AUDIO_IN_SAIx_AF GPIO_AF6_SAI1
+#define AUDIO_IN_SAIx_SD_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
+#define AUDIO_IN_SAIx_SD_GPIO_PORT GPIOE
+#define AUDIO_IN_SAIx_SD_PIN GPIO_PIN_3
+
+/* SAI DMA Stream definitions */
+#define AUDIO_IN_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
+#define AUDIO_IN_SAIx_DMAx_STREAM DMA2_Stream4
+#define AUDIO_IN_SAIx_DMAx_REQUEST DMA_REQUEST_SAI1_B
+#define AUDIO_IN_SAIx_DMAx_IRQ DMA2_Stream4_IRQn
+#define AUDIO_IN_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
+#define AUDIO_IN_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
+
+#define AUDIO_IN_SAIx_DMAx_IRQHandler DMA2_Stream4_IRQHandler
+
+#define AUDIO_IN_INT_GPIO_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE()
+#define AUDIO_IN_INT_GPIO_PORT GPIOJ
+#define AUDIO_IN_INT_GPIO_PIN GPIO_PIN_15
+#define AUDIO_IN_INT_IRQ EXTI15_10_IRQn
+
+/* SAI PDM input definitions */
+#define AUDIO_IN_SAI_PDMx SAI4_Block_A
+#define AUDIO_IN_SAI_PDMx_CLK_ENABLE() __HAL_RCC_SAI4_CLK_ENABLE()
+#define AUDIO_IN_SAI_PDMx_CLK_DISABLE() __HAL_RCC_SAI4_CLK_DISABLE()
+#define AUDIO_IN_SAI_PDMx_FS_SCK_AF GPIO_AF8_SAI4
+#define AUDIO_IN_SAI_PDMx_FS_SCK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
+#define AUDIO_IN_SAI_PDMx_FS_SCK_GPIO_PORT GPIOE
+#define AUDIO_IN_SAI_PDMx_FS_PIN GPIO_PIN_4
+#define AUDIO_IN_SAI_PDMx_SCK_PIN GPIO_PIN_5
+
+#define AUDIO_IN_SAI_PDMx_CLK_IN_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
+#define AUDIO_IN_SAI_PDMx_CLK_IN_PIN GPIO_PIN_2
+#define AUDIO_IN_SAI_PDMx_CLK_IN_PORT GPIOE
+#define AUDIO_IN_SAI_PDMx_DATA_IN_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define AUDIO_IN_SAI_PDMx_DATA_IN_PIN GPIO_PIN_1
+#define AUDIO_IN_SAI_PDMx_DATA_IN_PORT GPIOC
+#define AUDIO_IN_SAI_PDMx_DATA_CLK_AF GPIO_AF10_SAI4
+#define AUDIO_IN_SAI_PDMx_IRQHandler SAI4_IRQHandler
+#define AUDIO_IN_SAI_PDMx_IRQ SAI4_IRQn
+
+/* SAI PDM DMA Stream definitions */
+#define AUDIO_IN_SAI_PDMx_DMAx_CLK_ENABLE() __HAL_RCC_BDMA_CLK_ENABLE()
+#define AUDIO_IN_SAI_PDMx_DMAx_STREAM BDMA_Channel1
+#define AUDIO_IN_SAI_PDMx_DMAx_REQUEST BDMA_REQUEST_SAI4_A
+#define AUDIO_IN_SAI_PDMx_DMAx_IRQ BDMA_Channel1_IRQn
+#define AUDIO_IN_SAI_PDMx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
+#define AUDIO_IN_SAI_PDMx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
+#define AUDIO_IN_SAI_PDMx_DMAx_IRQHandler BDMA_Channel1_IRQHandler
+
+/* Select the interrupt preemption priority and subpriority for the DMA interrupt */
+#define AUDIO_IN_IRQ_PREPRIO ((uint32_t)0x0F)
+
+
+/*------------------------------------------------------------------------------
+ CONFIGURATION: Audio Driver Configuration parameters
+------------------------------------------------------------------------------*/
+
+#define AUDIODATA_SIZE ((uint32_t)2) /* 16-bits audio data size */
+
+/* Audio status definition */
+#define AUDIO_OK ((uint8_t)0)
+#define AUDIO_ERROR ((uint8_t)1)
+#define AUDIO_TIMEOUT ((uint8_t)2)
+
+/* Audio In default settings */
+#define DEFAULT_AUDIO_IN_FREQ BSP_AUDIO_FREQUENCY_16K
+#define DEFAULT_AUDIO_IN_BIT_RESOLUTION ((uint8_t)16)
+#define DEFAULT_AUDIO_IN_CHANNEL_NBR ((uint8_t)2)
+#define DEFAULT_AUDIO_IN_VOLUME ((uint16_t)64)
+
+/*------------------------------------------------------------------------------
+ OUTPUT DEVICES definition
+------------------------------------------------------------------------------*/
+/* Alias on existing output devices to adapt for 2 headphones output */
+#define OUTPUT_DEVICE_HEADPHONE1 OUTPUT_DEVICE_HEADPHONE
+#define OUTPUT_DEVICE_HEADPHONE2 OUTPUT_DEVICE_SPEAKER /* Headphone2 is connected to Speaker output of the wm8994 */
+
+/*------------------------------------------------------------------------------
+ INPUT DEVICES definition
+------------------------------------------------------------------------------*/
+/* Analog microphone input from 3.5 audio jack connector */
+#define INPUT_DEVICE_ANALOG_MIC ((uint32_t)0x00000001)
+/* MP34DT01TR digital microphone on PCB top side */
+#define INPUT_DEVICE_DIGITAL_MIC1 ((uint32_t)0x00000010)
+#define INPUT_DEVICE_DIGITAL_MIC2 ((uint32_t)0x00000020)
+#define INPUT_DEVICE_DIGITAL_MIC ((uint32_t)(INPUT_DEVICE_DIGITAL_MIC1 | INPUT_DEVICE_DIGITAL_MIC2))
+
+/* Audio In interface for Digital mic */
+#define AUDIO_IN_INTERFACE_SAI ((uint16_t)0)
+#define AUDIO_IN_INTERFACE_PDM ((uint16_t)1)
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_AUDIO_Exported_Macros Exported Macros
+ * @{
+ */
+#define DMA_MAX_SIZE 0xFFFF
+#define DMA_MAX(x) (((x) <= DMA_MAX_SIZE)? (x):DMA_MAX_SIZE)
+#define POS_VAL(VAL) (POSITION_VAL(VAL) - 4)
+/**
+ * @}
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY_AUDIO_OUT_Exported_Functions
+ * @{
+ */
+uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq);
+void BSP_AUDIO_OUT_DeInit(void);
+uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size);
+void BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size);
+uint8_t BSP_AUDIO_OUT_Pause(void);
+uint8_t BSP_AUDIO_OUT_Resume(void);
+uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option);
+uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume);
+void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq);
+void BSP_AUDIO_OUT_SetAudioFrameSlot(uint32_t AudioFrameSlot);
+uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd);
+uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output);
+
+/* User Callbacks: user has to implement these functions in his code if they are needed. */
+/* This function is called when the requested data has been completely transferred.*/
+void BSP_AUDIO_OUT_TransferComplete_CallBack(void);
+
+/* This function is called when half of the requested buffer has been transferred. */
+void BSP_AUDIO_OUT_HalfTransfer_CallBack(void);
+
+/* This function is called when an Interrupt due to transfer error on or peripheral
+ error occurs. */
+void BSP_AUDIO_OUT_Error_CallBack(void);
+
+/* These function can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_AUDIO_OUT_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params);
+void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params);
+void BSP_AUDIO_OUT_MspDeInit(SAI_HandleTypeDef *hsai, void *Params);
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY_AUDIO_IN_Exported_Functions
+ * @{
+ */
+uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_InitEx(uint16_t InputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_AllocScratch (int32_t *pScratch, uint32_t size);
+uint8_t BSP_AUDIO_IN_Record(uint16_t *pBuf, uint32_t Size);
+uint8_t BSP_AUDIO_IN_RecordEx(uint32_t *pBuf, uint32_t Size);
+uint8_t BSP_AUDIO_IN_SetFrequency(uint32_t AudioFreq);
+uint8_t BSP_AUDIO_IN_Stop(void);
+uint8_t BSP_AUDIO_IN_StopEx(uint32_t InputDevice);
+uint8_t BSP_AUDIO_IN_Pause(void);
+uint8_t BSP_AUDIO_IN_PauseEx(uint32_t InputDevice);
+uint8_t BSP_AUDIO_IN_Resume(void);
+uint8_t BSP_AUDIO_IN_ResumeEx(uint32_t *pBuf, uint32_t InputDevice);
+uint8_t BSP_AUDIO_IN_SetVolume(uint8_t Volume);
+void BSP_AUDIO_IN_DeInit(void);
+uint8_t BSP_AUDIO_IN_PDMToPCM(uint16_t *PDMBuf, uint16_t *PCMBuf);
+uint8_t BSP_AUDIO_IN_PDMToPCM_Init(uint32_t AudioFreq, uint32_t ChnlNbrIn, uint32_t ChnlNbrOut);
+void BSP_AUDIO_IN_SelectInterface(uint32_t Interface);
+uint32_t BSP_AUDIO_IN_GetInterface(void);
+uint8_t BSP_AUDIO_IN_OUT_Init(uint32_t InputDevice, uint32_t OutputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+uint8_t BSP_AUDIO_IN_GetChannelNumber(void);
+void BSP_AUDIO_IN_Error_Callback(void);
+
+/* User Callbacks: user has to implement these functions in his code if they are needed. */
+/* This function should be implemented by the user application.
+ It is called into this driver when the current buffer is filled to prepare the next
+ buffer pointer and its size. */
+void BSP_AUDIO_IN_TransferComplete_CallBack(void);
+void BSP_AUDIO_IN_HalfTransfer_CallBack(void);
+void BSP_AUDIO_IN_TransferComplete_CallBackEx(uint32_t InputDevice);
+void BSP_AUDIO_IN_HalfTransfer_CallBackEx(uint32_t InputDevice);
+
+/* This function is called when an Interrupt due to transfer error on or peripheral
+ error occurs. */
+void BSP_AUDIO_IN_Error_CallBack(void);
+
+/* These function can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_AUDIO_IN_ClockConfig(uint32_t AudioFreq, void *Params);
+void BSP_AUDIO_IN_MspInit(void);
+void BSP_AUDIO_IN_MspDeInit(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32H747I_DISCOVERY_AUDIO_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery_camera.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,643 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery.c
+ * @author MCD Application Team
+ * @brief This file includes the driver for Camera modules mounted on
+ * STM32H747I-DISCOVERY board.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* File Info: ------------------------------------------------------------------
+ User NOTES
+1. How to use this driver:
+--------------------------
+ - This driver is used to drive the camera.
+ - The OV9655 component driver MUST be included with this driver.
+
+2. Driver description:
+---------------------
+ + Initialization steps:
+ o Initialize the camera using the BSP_CAMERA_Init() function.
+ o Start the camera capture/snapshot using the CAMERA_Start() function.
+ o Suspend, resume or stop the camera capture using the following functions:
+ - BSP_CAMERA_Suspend()
+ - BSP_CAMERA_Resume()
+ - BSP_CAMERA_Stop()
+
+ + Options
+ o Increase or decrease on the fly the brightness and/or contrast
+ using the following function:
+ - BSP_CAMERA_ContrastBrightnessConfig
+ o Add a special effect on the fly using the following functions:
+ - BSP_CAMERA_BlackWhiteConfig()
+ - BSP_CAMERA_ColorEffectConfig()
+
+------------------------------------------------------------------------------*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h747i_discovery_camera.h"
+
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_CAMERA STM32H747I_DISCOVERY_CAMERA
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_CAMERA_Exported_Variables Exported Variables
+ * @{
+ */
+DCMI_HandleTypeDef hdcmi_discovery;
+CAMERA_DrvTypeDef *camera_drv;
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_CAMERA_Private_Variables Private Variables
+ * @{
+ */
+/* Camera current resolution naming (QQVGA, VGA, ...) */
+static uint32_t CameraCurrentResolution;
+
+/* Camera image rotation on LCD Displayed frame buffer */
+uint32_t CameraRotation = CAMERA_ROTATION_INVALID;
+
+/* Camera module I2C HW address */
+static uint32_t CameraHwAddress;
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_CAMERA_Private_FunctionPrototypes Private FunctionPrototypes
+ * @{
+ */
+static uint32_t GetSize(uint32_t Resolution);
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_CAMERA_Exported_Functions Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Set Camera image rotation on LCD Displayed frame buffer.
+ * @param rotation : uint32_t rotation of camera image in preview buffer sent to LCD
+ * need to be of type Camera_ImageRotationTypeDef
+ * @retval Camera status
+ */
+uint8_t BSP_CAMERA_SetRotation(uint32_t rotation)
+{
+ uint8_t status = CAMERA_ERROR;
+
+ if(rotation < CAMERA_ROTATION_INVALID)
+ {
+ /* Set Camera image rotation on LCD Displayed frame buffer */
+ CameraRotation = rotation;
+ status = CAMERA_OK;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Get Camera image rotation on LCD Displayed frame buffer.
+ * @retval rotation : uint32_t value of type Camera_ImageRotationTypeDef
+ */
+uint32_t BSP_CAMERA_GetRotation(void)
+{
+ return(CameraRotation);
+}
+
+/**
+ * @brief Initializes the camera.
+ * @param Resolution : camera sensor requested resolution (x, y) : standard resolution
+ * naming QQVGA, QVGA, VGA ...
+ * @retval Camera status
+ */
+uint8_t BSP_CAMERA_Init(uint32_t Resolution)
+{
+ DCMI_HandleTypeDef *phdcmi;
+ uint8_t status = CAMERA_ERROR;
+
+ /* Get the DCMI handle structure */
+ phdcmi = &hdcmi_discovery;
+
+ /*** Configures the DCMI to interface with the camera module ***/
+ /* DCMI configuration */
+ phdcmi->Init.CaptureRate = DCMI_CR_ALL_FRAME;
+ phdcmi->Init.HSPolarity = DCMI_HSPOLARITY_LOW;
+ phdcmi->Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
+ phdcmi->Init.VSPolarity = DCMI_VSPOLARITY_HIGH;
+ phdcmi->Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
+ phdcmi->Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;
+ phdcmi->Instance = DCMI;
+
+ /* Power up camera */
+ BSP_CAMERA_PwrUp();
+
+ /* Read ID of Camera module via I2C */
+ if(ov9655_ReadID(CAMERA_I2C_ADDRESS) == OV9655_ID)
+ {
+ /* Initialize the camera driver structure */
+ camera_drv = &ov9655_drv;
+ CameraHwAddress = CAMERA_I2C_ADDRESS;
+
+ /* DCMI Initialization */
+ BSP_CAMERA_MspInit(&hdcmi_discovery, NULL);
+ HAL_DCMI_Init(phdcmi);
+
+ /* Camera Module Initialization via I2C to the wanted 'Resolution' */
+ if (Resolution == CAMERA_R480x272)
+ { /* For 480x272 resolution, the OV9655 sensor is set to VGA resolution
+ * as OV9655 doesn't supports 480x272 resolution,
+ * then DCMI is configured to output a 480x272 cropped window */
+ camera_drv->Init(CameraHwAddress, CAMERA_R640x480);
+ HAL_DCMI_ConfigCROP(phdcmi, /* Crop in the middle of the VGA picture */
+ (CAMERA_VGA_RES_X - CAMERA_480x272_RES_X)/2,
+ (CAMERA_VGA_RES_Y - CAMERA_480x272_RES_Y)/2,
+ (CAMERA_480x272_RES_X * 2) - 1,
+ CAMERA_480x272_RES_Y - 1);
+ HAL_DCMI_EnableCROP(phdcmi);
+ }
+ else
+ {
+ camera_drv->Init(CameraHwAddress, Resolution);
+ HAL_DCMI_DisableCROP(phdcmi);
+ }
+
+ CameraCurrentResolution = Resolution;
+
+ /* Return CAMERA_OK status */
+ status = CAMERA_OK;
+ }
+ else
+ {
+ /* Return CAMERA_NOT_SUPPORTED status */
+ status = CAMERA_NOT_SUPPORTED;
+ }
+
+ return status;
+}
+
+
+/**
+ * @brief DeInitializes the camera.
+ * @retval Camera status
+ */
+uint8_t BSP_CAMERA_DeInit(void)
+{
+ hdcmi_discovery.Instance = DCMI;
+
+ HAL_DCMI_DeInit(&hdcmi_discovery);
+ BSP_CAMERA_MspDeInit(&hdcmi_discovery, NULL);
+ return CAMERA_OK;
+}
+
+/**
+ * @brief Starts the camera capture in continuous mode.
+ * @param buff: pointer to the camera output buffer
+ * @retval None
+ */
+void BSP_CAMERA_ContinuousStart(uint8_t *buff)
+{
+ /* Start the camera capture */
+ HAL_DCMI_Start_DMA(&hdcmi_discovery, DCMI_MODE_CONTINUOUS, (uint32_t)buff, GetSize(CameraCurrentResolution));
+}
+
+/**
+ * @brief Starts the camera capture in snapshot mode.
+ * @param buff: pointer to the camera output buffer
+ * @retval None
+ */
+void BSP_CAMERA_SnapshotStart(uint8_t *buff)
+{
+ /* Start the camera capture */
+ HAL_DCMI_Start_DMA(&hdcmi_discovery, DCMI_MODE_SNAPSHOT, (uint32_t)buff, GetSize(CameraCurrentResolution));
+}
+
+/**
+ * @brief Suspend the CAMERA capture
+ * @retval None
+ */
+void BSP_CAMERA_Suspend(void)
+{
+ /* Suspend the Camera Capture */
+ HAL_DCMI_Suspend(&hdcmi_discovery);
+}
+
+/**
+ * @brief Resume the CAMERA capture
+ * @retval None
+ */
+void BSP_CAMERA_Resume(void)
+{
+ /* Start the Camera Capture */
+ HAL_DCMI_Resume(&hdcmi_discovery);
+}
+
+/**
+ * @brief Stop the CAMERA capture
+ * @retval Camera status
+ */
+uint8_t BSP_CAMERA_Stop(void)
+{
+ uint8_t status = CAMERA_ERROR;
+
+ if(HAL_DCMI_Stop(&hdcmi_discovery) == HAL_OK)
+ {
+ status = CAMERA_OK;
+ }
+
+ /* Set Camera in Power Down */
+ BSP_CAMERA_PwrDown();
+
+ return status;
+}
+
+/**
+ * @brief CANERA power up
+ * @retval None
+ */
+void BSP_CAMERA_PwrUp(void)
+{
+ GPIO_InitTypeDef gpio_init_structure;
+
+ /* Enable GPIO clock */
+ __HAL_RCC_GPIOJ_CLK_ENABLE();
+
+ /*** Configure the GPIO ***/
+ /* Configure DCMI GPIO as alternate function */
+ gpio_init_structure.Pin = GPIO_PIN_14;
+ gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ HAL_GPIO_Init(GPIOJ, &gpio_init_structure);
+
+ /* De-assert the camera POWER_DOWN pin (active high) */
+ HAL_GPIO_WritePin(GPIOJ, GPIO_PIN_14, GPIO_PIN_RESET);
+
+ HAL_Delay(3); /* POWER_DOWN de-asserted during 3ms */
+}
+
+/**
+ * @brief CAMERA power down
+ * @retval None
+ */
+void BSP_CAMERA_PwrDown(void)
+{
+ GPIO_InitTypeDef gpio_init_structure;
+
+ /* Enable GPIO clock */
+ __HAL_RCC_GPIOJ_CLK_ENABLE();
+
+ /*** Configure the GPIO ***/
+ /* Configure DCMI GPIO as alternate function */
+ gpio_init_structure.Pin = GPIO_PIN_14;
+ gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ HAL_GPIO_Init(GPIOJ, &gpio_init_structure);
+
+ /* Assert the camera POWER_DOWN pin (active high) */
+ HAL_GPIO_WritePin(GPIOJ, GPIO_PIN_14, GPIO_PIN_SET);
+}
+
+/**
+ * @brief Configures the camera contrast and brightness.
+ * @param contrast_level: Contrast level
+ * This parameter can be one of the following values:
+ * @arg CAMERA_CONTRAST_LEVEL4: for contrast +2
+ * @arg CAMERA_CONTRAST_LEVEL3: for contrast +1
+ * @arg CAMERA_CONTRAST_LEVEL2: for contrast 0
+ * @arg CAMERA_CONTRAST_LEVEL1: for contrast -1
+ * @arg CAMERA_CONTRAST_LEVEL0: for contrast -2
+ * @param brightness_level: Contrast level
+ * This parameter can be one of the following values:
+ * @arg CAMERA_BRIGHTNESS_LEVEL4: for brightness +2
+ * @arg CAMERA_BRIGHTNESS_LEVEL3: for brightness +1
+ * @arg CAMERA_BRIGHTNESS_LEVEL2: for brightness 0
+ * @arg CAMERA_BRIGHTNESS_LEVEL1: for brightness -1
+ * @arg CAMERA_BRIGHTNESS_LEVEL0: for brightness -2
+ */
+void BSP_CAMERA_ContrastBrightnessConfig(uint32_t contrast_level, uint32_t brightness_level)
+{
+ if(camera_drv->Config != NULL)
+ {
+ camera_drv->Config(CameraHwAddress, CAMERA_CONTRAST_BRIGHTNESS, contrast_level, brightness_level);
+ }
+}
+
+/**
+ * @brief Configures the camera white balance.
+ * @param Mode: black_white mode
+ * This parameter can be one of the following values:
+ * @arg CAMERA_BLACK_WHITE_BW
+ * @arg CAMERA_BLACK_WHITE_NEGATIVE
+ * @arg CAMERA_BLACK_WHITE_BW_NEGATIVE
+ * @arg CAMERA_BLACK_WHITE_NORMAL
+ */
+void BSP_CAMERA_BlackWhiteConfig(uint32_t Mode)
+{
+ if(camera_drv->Config != NULL)
+ {
+ camera_drv->Config(CameraHwAddress, CAMERA_BLACK_WHITE, Mode, 0);
+ }
+}
+
+/**
+ * @brief Configures the camera color effect.
+ * @param Effect: Color effect
+ * This parameter can be one of the following values:
+ * @arg CAMERA_COLOR_EFFECT_ANTIQUE
+ * @arg CAMERA_COLOR_EFFECT_BLUE
+ * @arg CAMERA_COLOR_EFFECT_GREEN
+ * @arg CAMERA_COLOR_EFFECT_RED
+ * @retval None
+ */
+void BSP_CAMERA_ColorEffectConfig(uint32_t Effect)
+{
+ if(camera_drv->Config != NULL)
+ {
+ camera_drv->Config(CameraHwAddress, CAMERA_COLOR_EFFECT, Effect, 0);
+ }
+}
+
+/**
+ * @brief Get the capture size in pixels unit.
+ * @param Resolution: the current resolution.
+ * @retval capture size in pixels unit.
+ */
+static uint32_t GetSize(uint32_t Resolution)
+{
+ uint32_t size = 0;
+
+ /* Get capture size */
+ switch (Resolution)
+ {
+ case CAMERA_R160x120:
+ {
+ size = 0x2580;
+ }
+ break;
+ case CAMERA_R320x240:
+ {
+ size = 0x9600;
+ }
+ break;
+ case CAMERA_R480x272:
+ {
+ size = 0xFF00;
+ }
+ break;
+ case CAMERA_R640x480:
+ {
+ size = 0x25800;
+ }
+ break;
+ default:
+ {
+ break;
+ }
+ }
+
+ return size;
+}
+
+/**
+ * @brief Initializes the DCMI MSP.
+ * @param hdcmi: HDMI handle
+ * @param Params : pointer on additional configuration parameters, can be NULL.
+ * @retval None
+ */
+__weak void BSP_CAMERA_MspInit(DCMI_HandleTypeDef *hdcmi, void *Params)
+{
+ static DMA_HandleTypeDef hdma_handler;
+ GPIO_InitTypeDef gpio_init_structure;
+
+ /*** Enable peripherals and GPIO clocks ***/
+ /* Enable DCMI clock */
+ __HAL_RCC_DCMI_CLK_ENABLE();
+
+ /* Enable DMA clock */
+ CAMERA_DCMI_DMAx_CLK_ENABLE();
+
+ /* Enable GPIO clocks */
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOD_CLK_ENABLE();
+ __HAL_RCC_GPIOG_CLK_ENABLE();
+
+ /*** Configure the GPIO ***/
+ /* Configure DCMI GPIO as alternate function */
+ gpio_init_structure.Pin = GPIO_PIN_4 | GPIO_PIN_6;
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ gpio_init_structure.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOA, &gpio_init_structure);
+
+ gpio_init_structure.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9;
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ gpio_init_structure.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOB, &gpio_init_structure);
+
+ gpio_init_structure.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_9 | GPIO_PIN_11;
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ gpio_init_structure.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOC, &gpio_init_structure);
+
+ gpio_init_structure.Pin = GPIO_PIN_3;
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ gpio_init_structure.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOD, &gpio_init_structure);
+
+ gpio_init_structure.Pin = GPIO_PIN_10;
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ gpio_init_structure.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOG, &gpio_init_structure);
+
+ /*** Configure the DMA ***/
+ /* Set the parameters to be configured */
+ hdma_handler.Init.Request = DMA_REQUEST_DCMI;
+ hdma_handler.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_handler.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_handler.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ hdma_handler.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ hdma_handler.Init.Mode = DMA_CIRCULAR;
+ hdma_handler.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+ hdma_handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_handler.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_handler.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+ hdma_handler.Instance = CAMERA_DCMI_DMAx_STREAM;
+
+ /* Associate the initialized DMA handle to the DCMI handle */
+ __HAL_LINKDMA(hdcmi, DMA_Handle, hdma_handler);
+
+ /*** Configure the NVIC for DCMI and DMA ***/
+ /* NVIC configuration for DCMI transfer complete interrupt */
+ HAL_NVIC_SetPriority(DCMI_IRQn, 0x0F, 0);
+ HAL_NVIC_EnableIRQ(DCMI_IRQn);
+
+ /* NVIC configuration for DMA transfer complete interrupt */
+ HAL_NVIC_SetPriority(CAMERA_DCMI_DMAx_IRQ, 0x0F, 0);
+ HAL_NVIC_EnableIRQ(CAMERA_DCMI_DMAx_IRQ);
+
+ /* Configure the DMA stream */
+ HAL_DMA_Init(hdcmi->DMA_Handle);
+}
+
+/**
+ * @brief DeInitializes the DCMI MSP.
+ * @param hdcmi: HDMI handle
+ * @param Params : pointer on additional configuration parameters, can be NULL.
+ * @retval None
+ */
+__weak void BSP_CAMERA_MspDeInit(DCMI_HandleTypeDef *hdcmi, void *Params)
+{
+ /* Disable NVIC for DCMI transfer complete interrupt */
+ HAL_NVIC_DisableIRQ(DCMI_IRQn);
+
+ /* Disable NVIC for DMA2 transfer complete interrupt */
+ HAL_NVIC_DisableIRQ(CAMERA_DCMI_DMAx_IRQ);
+
+ /* Configure the DMA stream */
+ HAL_DMA_DeInit(hdcmi->DMA_Handle);
+
+ /* Disable DCMI clock */
+ __HAL_RCC_DCMI_CLK_DISABLE();
+
+ /* GPIO pins clock and DMA clock can be shut down in the application
+ by surcharging this __weak function */
+}
+
+/**
+ * @brief Line event callback
+ * @param hdcmi: pointer to the DCMI handle
+ * @retval None
+ */
+void HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef *hdcmi)
+{
+ BSP_CAMERA_LineEventCallback();
+}
+
+/**
+ * @brief Line Event callback.
+ * @retval None
+ */
+__weak void BSP_CAMERA_LineEventCallback(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_DCMI_LineEventCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief VSYNC event callback
+ * @param hdcmi: pointer to the DCMI handle
+ * @retval None
+ */
+void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi)
+{
+ BSP_CAMERA_VsyncEventCallback();
+}
+
+/**
+ * @brief VSYNC Event callback.
+ * @retval None
+ */
+__weak void BSP_CAMERA_VsyncEventCallback(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_DCMI_VsyncEventCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Frame event callback
+ * @param hdcmi: pointer to the DCMI handle
+ * @retval None
+ */
+void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
+{
+ BSP_CAMERA_FrameEventCallback();
+}
+
+/**
+ * @brief Frame Event callback.
+ * @retval None
+ */
+__weak void BSP_CAMERA_FrameEventCallback(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_DCMI_FrameEventCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Error callback
+ * @param hdcmi: pointer to the DCMI handle
+ * @retval None
+ */
+void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi)
+{
+ BSP_CAMERA_ErrorCallback();
+}
+
+/**
+ * @brief Error callback.
+ * @retval None
+ */
+__weak void BSP_CAMERA_ErrorCallback(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_DCMI_ErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery_camera.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,149 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery.h
+ * @author MCD Application Team
+ * @brief This file contains the common defines and functions prototypes for
+ * the STM32H747I_DISCOVERY_camera.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32H747I_DISCOVERY_CAMERA_H
+#define __STM32H747I_DISCOVERY_CAMERA_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include Camera component Driver */
+#include "../Components/ov9655/ov9655.h"
+#include "stm32h747i_discovery.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY_CAMERA
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_CAMERA_Exported_Constants Exported Constants
+ * @{
+ */
+
+/**
+ * @brief Camera State structures definition
+ */
+#define CAMERA_OK 0x00
+#define CAMERA_ERROR 0x01
+#define CAMERA_TIMEOUT 0x02
+#define CAMERA_NOT_DETECTED 0x03
+#define CAMERA_NOT_SUPPORTED 0x04
+
+/**
+ * @brief Camera Image rotation definition
+ * in frame buffer for LCD Display.
+ */
+#define CAMERA_NO_ROTATION 0x00
+#define CAMERA_ROTATION_90 0x01
+#define CAMERA_ROTATION_INVALID 0x02
+
+#define RESOLUTION_R160x120 CAMERA_R160x120 /* QQVGA Resolution */
+#define RESOLUTION_R320x240 CAMERA_R320x240 /* QVGA Resolution */
+#define RESOLUTION_R480x272 CAMERA_R480x272 /* 480x272 Resolution */
+#define RESOLUTION_R640x480 CAMERA_R640x480 /* VGA Resolution */
+
+#define CAMERA_VGA_RES_X 640
+#define CAMERA_VGA_RES_Y 480
+#define CAMERA_480x272_RES_X 480
+#define CAMERA_480x272_RES_Y 272
+#define CAMERA_QVGA_RES_X 320
+#define CAMERA_QVGA_RES_Y 240
+#define CAMERA_QQVGA_RES_X 160
+#define CAMERA_QQVGA_RES_Y 120
+
+#define BSP_CAMERA_IRQHandler DCMI_IRQHandler
+#define BSP_CAMERA_DMA_IRQHandler DMA2_Stream3_IRQHandler
+
+/* DCMI DMA Stream definitions */
+#define CAMERA_DCMI_DMAx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE
+#define CAMERA_DCMI_DMAx_STREAM DMA2_Stream3
+#define CAMERA_DCMI_DMAx_IRQ DMA2_Stream3_IRQn
+
+/**
+ * @brief CAMERA FB_StartAddress
+ */
+#define CAMERA_FB_START_ADDRESS ((uint32_t)0xD0600000)
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY_CAMERA_Exported_Functions
+ * @{
+ */
+uint8_t BSP_CAMERA_Init(uint32_t Resolution);
+uint8_t BSP_CAMERA_DeInit(void);
+void BSP_CAMERA_ContinuousStart(uint8_t *buff);
+void BSP_CAMERA_SnapshotStart(uint8_t *buff);
+void BSP_CAMERA_Suspend(void);
+void BSP_CAMERA_Resume(void);
+uint8_t BSP_CAMERA_Stop(void);
+void BSP_CAMERA_PwrUp(void);
+void BSP_CAMERA_PwrDown(void);
+void BSP_CAMERA_LineEventCallback(void);
+void BSP_CAMERA_VsyncEventCallback(void);
+void BSP_CAMERA_FrameEventCallback(void);
+void BSP_CAMERA_ErrorCallback(void);
+
+/* Camera features functions prototype */
+void BSP_CAMERA_ContrastBrightnessConfig(uint32_t contrast_level, uint32_t brightness_level);
+void BSP_CAMERA_BlackWhiteConfig(uint32_t Mode);
+void BSP_CAMERA_ColorEffectConfig(uint32_t Effect);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_CAMERA_MspInit(DCMI_HandleTypeDef *hdcmi, void *Params);
+void BSP_CAMERA_MspDeInit(DCMI_HandleTypeDef *hdcmi, void *Params);
+uint8_t BSP_CAMERA_SetRotation(uint32_t rotation);
+uint32_t BSP_CAMERA_GetRotation(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32H747I_DISCOVERY_CAMERA_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery_lcd.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,1981 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery_lcd.c
+ * @author MCD Application Team
+ * @brief This file includes the driver for Liquid Crystal Display (LCD) module
+ * mounted on STM32H747I_DISCOVERY board.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* File Info: ------------------------------------------------------------------
+ User NOTES
+1. How To use this driver:
+--------------------------
+ - This driver is used to drive directly in video mode a LCD TFT using the DSI interface.
+ The following IPs are implied : DSI Host IP block working
+ in conjunction to the LTDC controller.
+ - This driver is linked by construction to LCD KoD mounted on board MB1166.
+
+2. Driver description:
+---------------------
+ + Initialization steps:
+ o Initialize the LCD using the BSP_LCD_Init() function.
+ o Select the LCD layer to be used using the BSP_LCD_SelectLayer() function.
+ o Enable the LCD display using the BSP_LCD_DisplayOn() function.
+
+ + Options
+ o Configure and enable the color keying functionality using the
+ BSP_LCD_SetColorKeying() function.
+ o Modify in the fly the transparency and/or the frame buffer address
+ using the following functions:
+ - BSP_LCD_SetTransparency()
+ - BSP_LCD_SetLayerAddress()
+
+ + Display on LCD
+ o Clear the whole LCD using BSP_LCD_Clear() function or only one specified string
+ line using the BSP_LCD_ClearStringLine() function.
+ o Display a character on the specified line and column using the BSP_LCD_DisplayChar()
+ function or a complete string line using the BSP_LCD_DisplayStringAtLine() function.
+ o Display a string line on the specified position (x,y in pixel) and align mode
+ using the BSP_LCD_DisplayStringAtLine() function.
+ o Draw and fill a basic shapes (dot, line, rectangle, circle, ellipse, .. bitmap)
+ on LCD using the available set of functions.
+
+------------------------------------------------------------------------------*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h747i_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 STM32H747I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LCD STM32H747I_DISCOVERY_LCD
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LCD_Private_Defines Private Defines
+ * @{
+ */
+
+#if defined(USE_LCD_HDMI)
+#define HDMI_ASPECT_RATIO_16_9 ADV7533_ASPECT_RATIO_16_9
+#define HDMI_ASPECT_RATIO_4_3 ADV7533_ASPECT_RATIO_4_3
+#endif /* USE_LCD_HDMI */
+#define LCD_DSI_ID 0x11
+#define LCD_DSI_ID_REG 0xA8
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LCD_Private_Types Private Types
+ * @{
+ */
+
+#if defined(USE_LCD_HDMI)
+/**
+ * @brief DSI timming params used for different HDMI adpater
+ */
+typedef struct
+{
+ uint16_t HACT;
+ uint16_t HSYNC;
+ uint16_t HBP;
+ uint16_t HFP;
+ uint16_t VACT;
+ uint16_t VSYNC;
+ uint16_t VBP;
+ uint16_t VFP;
+ uint8_t ASPECT_RATIO;
+ uint8_t RGB_CODING;
+} HDMI_FormatTypeDef;
+
+/**
+ * @brief DSI packet params used for different HDMI adpater
+ */
+typedef struct
+{
+ uint16_t NullPacketSize;
+ uint16_t NumberOfChunks;
+ uint16_t PacketSize;
+} HDMI_DSIPacketTypeDef;
+
+/**
+ * @brief LTDC PLL params used for different HDMI adpater
+ */
+typedef struct
+{
+ uint16_t PLL_LTDC_N;
+ uint16_t PLL_LTDC_R;
+ uint32_t PCLK;
+ uint16_t IDF;
+ uint16_t NDIV;
+ uint16_t ODF;
+ uint16_t LaneByteClock;
+ uint16_t TXEscapeCkdiv;
+} HDMI_PLLConfigTypeDef;
+
+#endif /* USE_LCD_HDMI */
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LCD_Private_Macros Private Macros
+ * @{
+ */
+#define ABS(X) ((X) > 0 ? (X) : -(X))
+#define POLY_X(Z) ((int32_t)((Points + (Z))->X))
+#define POLY_Y(Z) ((int32_t)((Points + (Z))->Y))
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LCD_Exported_Variables Exported Variables
+ * @{
+ */
+DMA2D_HandleTypeDef hdma2d_discovery;
+LTDC_HandleTypeDef hltdc_discovery;
+DSI_HandleTypeDef hdsi_discovery;
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LCD_Private_Variables Private Variables
+ * @{
+ */
+static DSI_VidCfgTypeDef hdsivideo_handle;
+uint32_t lcd_x_size = OTM8009A_800X480_WIDTH;
+uint32_t lcd_y_size = OTM8009A_800X480_HEIGHT;
+
+#if defined(USE_LCD_HDMI)
+/**
+ * @brief DSI timming used for different HDMI resolution (720x480 and 720x576)
+ */
+HDMI_FormatTypeDef HDMI_Format[2] =
+{
+/* HA HS HB HF VA VS VB VF ASPECT BPP */
+ {720, 62, 60, 30, 480, 6, 19, 9, HDMI_ASPECT_RATIO_4_3, LCD_DSI_PIXEL_DATA_FMT_RBG888},
+ {720, 64, 68, 12, 576, 5, 39, 5, HDMI_ASPECT_RATIO_16_9, LCD_DSI_PIXEL_DATA_FMT_RBG888}
+
+};
+
+/**
+ * @brief DSI packet size used for different HDMI resolution (720x480 and 720x576)
+ */
+HDMI_DSIPacketTypeDef HDMI_DSIPacket[2] =
+{
+ /* NP NC VP */
+ {0, 1, 720},
+ {0, 1, 720}
+};
+
+/**
+ * @brief LTDC PLL settings used for different HDMI resolution (720x480 and 720x576)
+ */
+HDMI_PLLConfigTypeDef HDMI_PLLConfig[4] =
+{
+/* N DIV Pclk IDF NDIV ODF LBClk TXEscapeCkdiv*/
+ {13, 12, 27083, DSI_PLL_IN_DIV5, 65, DSI_PLL_OUT_DIV1, 40625, 3},
+ {13, 12, 27083, DSI_PLL_IN_DIV5, 65, DSI_PLL_OUT_DIV1, 40625, 3},
+
+};
+#endif /* USE_LCD_HDMI */
+
+/**
+ * @brief Default Active LTDC Layer in which drawing is made is LTDC Layer Background
+ */
+static uint32_t ActiveLayer = LTDC_ACTIVE_LAYER_BACKGROUND;
+
+/**
+ * @brief Current Drawing Layer properties variable
+ */
+static LCD_DrawPropTypeDef DrawProp[LTDC_MAX_LAYER_NUMBER];
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LCD_Private_FunctionPrototypes Private FunctionPrototypes
+ * @{
+ */
+static void DrawChar(uint16_t Xpos, uint16_t Ypos, const uint8_t *c);
+static void FillTriangle(uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3);
+static void LL_FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex);
+static void LL_ConvertLineToARGB8888(void * pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode);
+static uint16_t LCD_IO_GetID(void);
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LCD_Exported_Functions Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes the DSI LCD.
+ * @retval LCD state
+ */
+uint8_t BSP_LCD_Init(void)
+{
+ return (BSP_LCD_InitEx(LCD_ORIENTATION_LANDSCAPE));
+}
+
+/**
+ * @brief Initializes the DSI LCD.
+ * The ititialization is done as below:
+ * - DSI PLL ititialization
+ * - DSI ititialization
+ * - LTDC ititialization
+ * - OTM8009A LCD Display IC Driver ititialization
+ * @param orientation Display orientation
+ * @retval LCD state
+ */
+uint8_t BSP_LCD_InitEx(LCD_OrientationTypeDef orientation)
+{
+ DSI_PLLInitTypeDef dsiPllInit;
+ DSI_PHY_TimerTypeDef PhyTimings;
+ static RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
+ uint32_t LcdClock = 26400; /*!< LcdClk = 26400 kHz */
+ uint16_t read_id = 0;
+
+ uint32_t laneByteClk_kHz = 0;
+ uint32_t VSA; /*!< Vertical start active time in units of lines */
+ uint32_t VBP; /*!< Vertical Back Porch time in units of lines */
+ uint32_t VFP; /*!< Vertical Front Porch time in units of lines */
+ uint32_t VACT; /*!< Vertical Active time in units of lines = imageSize Y in pixels to display */
+ uint32_t HSA; /*!< Horizontal start active time in units of lcdClk */
+ uint32_t HBP; /*!< Horizontal Back Porch time in units of lcdClk */
+ uint32_t HFP; /*!< Horizontal Front Porch time in units of lcdClk */
+ uint32_t HACT; /*!< Horizontal Active time in units of lcdClk = imageSize X in pixels to display */
+
+ /* Toggle Hardware Reset of the DSI LCD using
+ * its XRES signal (active low) */
+ BSP_LCD_Reset();
+
+ /* Check the connected monitor */
+ read_id = LCD_IO_GetID();
+
+#if defined(USE_LCD_HDMI)
+ if(read_id == ADV7533_ID)
+ {
+ return BSP_LCD_HDMIInitEx(HDMI_FORMAT_720_576);
+ }
+ else if(read_id != LCD_DSI_ID)
+ {
+ return LCD_ERROR;
+ }
+#else
+ if(read_id != LCD_DSI_ID)
+ {
+ return LCD_ERROR;
+ }
+#endif /* USE_LCD_HDMI */
+
+ /* Call first MSP Initialize only in case of first initialization
+ * This will set IP blocks LTDC, DSI and DMA2D
+ * - out of reset
+ * - clocked
+ * - NVIC IRQ related to IP blocks enabled
+ */
+ BSP_LCD_MspInit();
+
+/*************************DSI Initialization***********************************/
+
+ /* Base address of DSI Host/Wrapper registers to be set before calling De-Init */
+ hdsi_discovery.Instance = DSI;
+
+ HAL_DSI_DeInit(&(hdsi_discovery));
+
+ dsiPllInit.PLLNDIV = 100;
+ dsiPllInit.PLLIDF = DSI_PLL_IN_DIV5;
+ dsiPllInit.PLLODF = DSI_PLL_OUT_DIV1;
+ laneByteClk_kHz = 62500; /* 500 MHz / 8 = 62.5 MHz = 62500 kHz */
+
+ /* Set number of Lanes */
+ hdsi_discovery.Init.NumberOfLanes = DSI_TWO_DATA_LANES;
+
+ /* TXEscapeCkdiv = f(LaneByteClk)/15.62 = 4 */
+ hdsi_discovery.Init.TXEscapeCkdiv = laneByteClk_kHz/15620;
+
+ HAL_DSI_Init(&(hdsi_discovery), &(dsiPllInit));
+
+ /* Timing parameters for all Video modes
+ * Set Timing parameters of LTDC depending on its chosen orientation
+ */
+ if(orientation == LCD_ORIENTATION_PORTRAIT)
+ {
+ lcd_x_size = OTM8009A_480X800_WIDTH; /* 480 */
+ lcd_y_size = OTM8009A_480X800_HEIGHT; /* 800 */
+ }
+ else
+ {
+ /* lcd_orientation == LCD_ORIENTATION_LANDSCAPE */
+ lcd_x_size = OTM8009A_800X480_WIDTH; /* 800 */
+ lcd_y_size = OTM8009A_800X480_HEIGHT; /* 480 */
+ }
+
+ HACT = lcd_x_size;
+ VACT = lcd_y_size;
+
+ /* The following values are same for portrait and landscape orientations */
+ VSA = OTM8009A_480X800_VSYNC; /* 10 */
+ VBP = OTM8009A_480X800_VBP; /* 15 */
+ VFP = OTM8009A_480X800_VFP; /* 16 */
+ HSA = OTM8009A_480X800_HSYNC; /* 2 */
+ HBP = OTM8009A_480X800_HBP; /* 20 */
+ HFP = OTM8009A_480X800_HFP; /* 20 */
+
+
+ hdsivideo_handle.VirtualChannelID = LCD_OTM8009A_ID;
+ hdsivideo_handle.ColorCoding = LCD_DSI_PIXEL_DATA_FMT_RBG888;
+ hdsivideo_handle.VSPolarity = DSI_VSYNC_ACTIVE_HIGH;
+ hdsivideo_handle.HSPolarity = DSI_HSYNC_ACTIVE_HIGH;
+ hdsivideo_handle.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH;
+ hdsivideo_handle.Mode = DSI_VID_MODE_BURST; /* Mode Video burst ie : one LgP per line */
+ hdsivideo_handle.NullPacketSize = 0xFFF;
+ hdsivideo_handle.NumberOfChunks = 0;
+ hdsivideo_handle.PacketSize = HACT; /* Value depending on display orientation choice portrait/landscape */
+ hdsivideo_handle.HorizontalSyncActive = (HSA * laneByteClk_kHz)/LcdClock;
+ hdsivideo_handle.HorizontalBackPorch = (HBP * laneByteClk_kHz)/LcdClock;
+ hdsivideo_handle.HorizontalLine = ((HACT + HSA + HBP + HFP) * laneByteClk_kHz)/LcdClock; /* Value depending on display orientation choice portrait/landscape */
+ hdsivideo_handle.VerticalSyncActive = VSA;
+ hdsivideo_handle.VerticalBackPorch = VBP;
+ hdsivideo_handle.VerticalFrontPorch = VFP;
+ hdsivideo_handle.VerticalActive = VACT; /* Value depending on display orientation choice portrait/landscape */
+
+ /* Enable or disable sending LP command while streaming is active in video mode */
+ hdsivideo_handle.LPCommandEnable = DSI_LP_COMMAND_ENABLE; /* Enable sending commands in mode LP (Low Power) */
+
+ /* Largest packet size possible to transmit in LP mode in VSA, VBP, VFP regions */
+ /* Only useful when sending LP packets is allowed while streaming is active in video mode */
+ hdsivideo_handle.LPLargestPacketSize = 16;
+
+ /* Largest packet size possible to transmit in LP mode in HFP region during VACT period */
+ /* Only useful when sending LP packets is allowed while streaming is active in video mode */
+ hdsivideo_handle.LPVACTLargestPacketSize = 0;
+
+
+ /* Specify for each region of the video frame, if the transmission of command in LP mode is allowed in this region */
+ /* while streaming is active in video mode */
+ hdsivideo_handle.LPHorizontalFrontPorchEnable = DSI_LP_HFP_ENABLE; /* Allow sending LP commands during HFP period */
+ hdsivideo_handle.LPHorizontalBackPorchEnable = DSI_LP_HBP_ENABLE; /* Allow sending LP commands during HBP period */
+ hdsivideo_handle.LPVerticalActiveEnable = DSI_LP_VACT_ENABLE; /* Allow sending LP commands during VACT period */
+ hdsivideo_handle.LPVerticalFrontPorchEnable = DSI_LP_VFP_ENABLE; /* Allow sending LP commands during VFP period */
+ hdsivideo_handle.LPVerticalBackPorchEnable = DSI_LP_VBP_ENABLE; /* Allow sending LP commands during VBP period */
+ hdsivideo_handle.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_ENABLE; /* Allow sending LP commands during VSync = VSA period */
+
+ /* Configure DSI Video mode timings with settings set above */
+ HAL_DSI_ConfigVideoMode(&(hdsi_discovery), &(hdsivideo_handle));
+
+ /* Configure DSI PHY HS2LP and LP2HS timings */
+ PhyTimings.ClockLaneHS2LPTime = 35;
+ PhyTimings.ClockLaneLP2HSTime = 35;
+ PhyTimings.DataLaneHS2LPTime = 35;
+ PhyTimings.DataLaneLP2HSTime = 35;
+ PhyTimings.DataLaneMaxReadTime = 0;
+ PhyTimings.StopWaitTime = 10;
+ HAL_DSI_ConfigPhyTimer(&hdsi_discovery, &PhyTimings);
+
+/*************************End DSI Initialization*******************************/
+
+
+/************************LTDC Initialization***********************************/
+
+ /* Timing Configuration */
+ hltdc_discovery.Init.HorizontalSync = (HSA - 1);
+ hltdc_discovery.Init.AccumulatedHBP = (HSA + HBP - 1);
+ hltdc_discovery.Init.AccumulatedActiveW = (lcd_x_size + HSA + HBP - 1);
+ hltdc_discovery.Init.TotalWidth = (lcd_x_size + HSA + HBP + HFP - 1);
+
+ /* Initialize the LCD pixel width and pixel height */
+ hltdc_discovery.LayerCfg->ImageWidth = lcd_x_size;
+ hltdc_discovery.LayerCfg->ImageHeight = lcd_y_size;
+
+
+ /* LCD clock configuration */
+ /* PLL3_VCO Input = HSE_VALUE/PLL3M = 5 Mhz */
+ /* PLL3_VCO Output = PLL3_VCO Input * PLL3N = 480 Mhz */
+ /* PLLLCDCLK = PLL3_VCO Output/PLL3R = 480/18 = 26.666 Mhz */
+ /* LTDC clock frequency = PLLLCDCLK = 26.666 Mhz */
+ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
+ PeriphClkInitStruct.PLL3.PLL3M = 5;
+ PeriphClkInitStruct.PLL3.PLL3N = 96;
+ PeriphClkInitStruct.PLL3.PLL3P = 2;
+ PeriphClkInitStruct.PLL3.PLL3Q = 10;
+ PeriphClkInitStruct.PLL3.PLL3R = 18;
+ HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
+
+ /* Background value */
+ hltdc_discovery.Init.Backcolor.Blue = 0;
+ hltdc_discovery.Init.Backcolor.Green = 0;
+ hltdc_discovery.Init.Backcolor.Red = 0;
+ hltdc_discovery.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
+ hltdc_discovery.Instance = LTDC;
+
+ /* Get LTDC Configuration from DSI Configuration */
+ HAL_LTDC_StructInitFromVideoConfig(&(hltdc_discovery), &(hdsivideo_handle));
+
+ /* Initialize the LTDC */
+ HAL_LTDC_Init(&hltdc_discovery);
+
+ /* Enable the DSI host and wrapper : after LTDC */
+ /* To avoid any synchronization issue, the DSI shall be started after enabling the LTDC */
+ HAL_DSI_Start(&hdsi_discovery);
+
+#if !defined(DATA_IN_ExtSDRAM)
+ /* Initialize the SDRAM */
+ BSP_SDRAM_Init();
+#endif /* DATA_IN_ExtSDRAM */
+
+ /* Initialize the font */
+ BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
+
+/************************End LTDC Initialization*******************************/
+
+
+/***********************OTM8009A Initialization********************************/
+
+ /* Initialize the OTM8009A LCD Display IC Driver (KoD LCD IC Driver)
+ * depending on configuration set in 'hdsivideo_handle'.
+ */
+ OTM8009A_Init(OTM8009A_FORMAT_RGB888, orientation);
+
+/***********************End OTM8009A Initialization****************************/
+
+ return LCD_OK;
+}
+
+#if defined(USE_LCD_HDMI)
+/**
+ * @brief Initializes the DSI for HDMI monitor.
+ * The ititialization is done as below:
+ * - DSI PLL ititialization
+ * - DSI ititialization
+ * - LTDC ititialization
+ * - DSI-HDMI ADV7533 adapter device ititialization
+ * @param format : HDMI format could be HDMI_FORMAT_720_480 or HDMI_FORMAT_720_576
+ * @retval LCD state
+ */
+uint8_t BSP_LCD_HDMIInitEx(uint8_t format)
+{
+ /************************ADV7533 Initialization******************************/
+
+ /* Initialize the ADV7533 HDMI Bridge
+ depending on configuration set in 'hdsivideo_handle'. */
+ adv7533ConfigTypeDef adv7533_config;
+
+ adv7533_config.DSI_LANES = 2;
+ adv7533_config.HACT = HDMI_Format[format].HACT;
+ adv7533_config.HSYNC = HDMI_Format[format].HSYNC;
+ adv7533_config.HBP = HDMI_Format[format].HBP;
+ adv7533_config.HFP = HDMI_Format[format].HFP;
+ adv7533_config.VACT = HDMI_Format[format].VACT;
+ adv7533_config.VSYNC = HDMI_Format[format].VSYNC;
+ adv7533_config.VBP = HDMI_Format[format].VBP;
+ adv7533_config.VFP = HDMI_Format[format].VFP;
+
+ ADV7533_Init();
+ ADV7533_Configure(&adv7533_config);
+ ADV7533_PowerOn();
+
+/************************ Update hdmi_x_size and hdmi_y_size *****************/
+ lcd_x_size = HDMI_Format[format].HACT;
+ lcd_y_size = HDMI_Format[format].VACT;
+
+/***********************End ADV7533 Initialization****************************/
+
+ DSI_PLLInitTypeDef dsiPllInit;
+ DSI_PHY_TimerTypeDef dsiPhyInit;
+ static RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
+
+ /* Call first MSP Initialize only in case of first initialization
+ * This will set IP blocks LTDC and DSI
+ * - out of reset
+ * - clocked
+ * - NVIC IRQ related to IP blocks enabled
+ */
+ BSP_LCD_MspInit();
+
+/*************************DSI Initialization***********************************/
+
+ /* Base address of DSI Host/Wrapper registers to be set before calling De-Init */
+ hdsi_discovery.Instance = DSI;
+
+ HAL_DSI_DeInit(&(hdsi_discovery));
+
+ /* Configure the DSI PLL */
+ dsiPllInit.PLLNDIV = HDMI_PLLConfig[format].NDIV;
+ dsiPllInit.PLLIDF = HDMI_PLLConfig[format].IDF;
+ dsiPllInit.PLLODF = HDMI_PLLConfig[format].ODF;
+
+ /* Set number of Lanes */
+ hdsi_discovery.Init.NumberOfLanes = DSI_TWO_DATA_LANES;
+ /* Set the TX escape clock division ratio */
+ hdsi_discovery.Init.TXEscapeCkdiv = HDMI_PLLConfig[format].TXEscapeCkdiv;
+ /* Disable the automatic clock lane control (the ADV7533 must be clocked) */
+ hdsi_discovery.Init.AutomaticClockLaneControl = DSI_AUTO_CLK_LANE_CTRL_DISABLE;
+
+ /* Init the DSI */
+ HAL_DSI_Init(&hdsi_discovery, &dsiPllInit);
+
+ /* Configure the D-PHY Timings */
+ dsiPhyInit.ClockLaneHS2LPTime = 0x14;
+ dsiPhyInit.ClockLaneLP2HSTime = 0x14;
+ dsiPhyInit.DataLaneHS2LPTime = 0x0A;
+ dsiPhyInit.DataLaneLP2HSTime = 0x0A;
+ dsiPhyInit.DataLaneMaxReadTime = 0x00;
+ dsiPhyInit.StopWaitTime = 0x0;
+ HAL_DSI_ConfigPhyTimer(&hdsi_discovery, &dsiPhyInit);
+
+ /* Virutal channel used by the ADV7533 */
+ hdsivideo_handle.VirtualChannelID = HDMI_ADV7533_ID;
+
+ /* Timing parameters for Video modes
+ Set Timing parameters of DSI depending on its chosen format */
+ hdsivideo_handle.ColorCoding = HDMI_Format[format].RGB_CODING;
+ hdsivideo_handle.LooselyPacked = DSI_LOOSELY_PACKED_DISABLE;
+ hdsivideo_handle.VSPolarity = DSI_VSYNC_ACTIVE_LOW;
+ hdsivideo_handle.HSPolarity = DSI_HSYNC_ACTIVE_LOW;
+ hdsivideo_handle.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH;
+ hdsivideo_handle.Mode = DSI_VID_MODE_NB_PULSES;
+ hdsivideo_handle.NullPacketSize = HDMI_DSIPacket[format].NullPacketSize;
+ hdsivideo_handle.NumberOfChunks = HDMI_DSIPacket[format].NumberOfChunks;
+ hdsivideo_handle.PacketSize = HDMI_DSIPacket[format].PacketSize;
+ hdsivideo_handle.HorizontalSyncActive = HDMI_Format[format].HSYNC*HDMI_PLLConfig[format].LaneByteClock/HDMI_PLLConfig[format].PCLK;
+ hdsivideo_handle.HorizontalBackPorch = HDMI_Format[format].HBP*HDMI_PLLConfig[format].LaneByteClock/HDMI_PLLConfig[format].PCLK;
+ hdsivideo_handle.HorizontalLine = (HDMI_Format[format].HACT + HDMI_Format[format].HSYNC + HDMI_Format[format].HBP + HDMI_Format[format].HFP)*HDMI_PLLConfig[format].LaneByteClock/HDMI_PLLConfig[format].PCLK;
+ hdsivideo_handle.VerticalSyncActive = HDMI_Format[format].VSYNC;
+ hdsivideo_handle.VerticalBackPorch = HDMI_Format[format].VBP;
+ hdsivideo_handle.VerticalFrontPorch = HDMI_Format[format].VFP;
+ hdsivideo_handle.VerticalActive = HDMI_Format[format].VACT;
+
+ /* Enable or disable sending LP command while streaming is active in video mode */
+ hdsivideo_handle.LPCommandEnable = DSI_LP_COMMAND_DISABLE; /* Enable sending commands in mode LP (Low Power) */
+
+ /* Largest packet size possible to transmit in LP mode in VSA, VBP, VFP regions */
+ /* Only useful when sending LP packets is allowed while streaming is active in video mode */
+ hdsivideo_handle.LPLargestPacketSize = 4;
+
+ /* Largest packet size possible to transmit in LP mode in HFP region during VACT period */
+ /* Only useful when sending LP packets is allowed while streaming is active in video mode */
+ hdsivideo_handle.LPVACTLargestPacketSize = 4;
+
+ /* Specify for each region, if the going in LP mode is allowed */
+ /* while streaming is active in video mode */
+ hdsivideo_handle.LPHorizontalFrontPorchEnable = DSI_LP_HFP_DISABLE;
+ hdsivideo_handle.LPHorizontalBackPorchEnable = DSI_LP_HBP_DISABLE;
+ hdsivideo_handle.LPVerticalActiveEnable = DSI_LP_VACT_DISABLE;
+ hdsivideo_handle.LPVerticalFrontPorchEnable = DSI_LP_VFP_DISABLE;
+ hdsivideo_handle.LPVerticalBackPorchEnable = DSI_LP_VBP_DISABLE;
+ hdsivideo_handle.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_DISABLE;
+
+ /* No acknoledge at the end of a frame */
+ hdsivideo_handle.FrameBTAAcknowledgeEnable = DSI_FBTAA_DISABLE;
+
+ /* Configure DSI Video mode timings with settings set above */
+ HAL_DSI_ConfigVideoMode(&hdsi_discovery, &hdsivideo_handle);
+
+ /* Enable the DSI host and wrapper : but LTDC is not started yet at this stage */
+ HAL_DSI_Start(&hdsi_discovery);
+
+/*************************End DSI Initialization*******************************/
+
+
+/************************LTDC Initialization***********************************/
+
+ /* LCD clock configuration */
+ /* LCD clock configuration */
+ /* PLL3_VCO Input = HSE_VALUE/PLL3M = 25 Mhz */
+ /* PLL3_VCO Output = PLL3_VCO Input * PLL3N */
+ /* PLLLCDCLK = PLL3_VCO Output/PLL3R */
+ /* LTDC clock frequency = PLLLCDCLK */
+ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
+ PeriphClkInitStruct.PLL3.PLL3M = 1;
+ PeriphClkInitStruct.PLL3.PLL3N = HDMI_PLLConfig[format].PLL_LTDC_N;
+ PeriphClkInitStruct.PLL3.PLL3P = 2;
+ PeriphClkInitStruct.PLL3.PLL3Q = 2;
+ PeriphClkInitStruct.PLL3.PLL3R = HDMI_PLLConfig[format].PLL_LTDC_R;
+ HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
+
+ /* Base address of LTDC registers to be set before calling De-Init */
+ hltdc_discovery.Instance = LTDC;
+
+ HAL_LTDC_DeInit(&(hltdc_discovery));
+
+ /* Timing Configuration */
+ hltdc_discovery.Init.HorizontalSync = (HDMI_Format[format].HSYNC - 1);
+ hltdc_discovery.Init.AccumulatedHBP = (HDMI_Format[format].HSYNC + HDMI_Format[format].HBP - 1);
+ hltdc_discovery.Init.AccumulatedActiveW = (HDMI_Format[format].HACT + HDMI_Format[format].HSYNC + HDMI_Format[format].HBP - 1);
+ hltdc_discovery.Init.TotalWidth = (HDMI_Format[format].HACT + HDMI_Format[format].HSYNC + HDMI_Format[format].HBP + HDMI_Format[format].HFP - 1);
+ hltdc_discovery.Init.VerticalSync = (HDMI_Format[format].VSYNC - 1);
+ hltdc_discovery.Init.AccumulatedVBP = (HDMI_Format[format].VSYNC + HDMI_Format[format].VBP - 1);
+ hltdc_discovery.Init.AccumulatedActiveH = (HDMI_Format[format].VACT + HDMI_Format[format].VSYNC + HDMI_Format[format].VBP - 1);
+ hltdc_discovery.Init.TotalHeigh = (HDMI_Format[format].VACT + HDMI_Format[format].VSYNC + HDMI_Format[format].VBP + HDMI_Format[format].VFP - 1);
+
+ /* background value */
+ hltdc_discovery.Init.Backcolor.Blue = 0x00;
+ hltdc_discovery.Init.Backcolor.Green = 0xFF;
+ hltdc_discovery.Init.Backcolor.Red = 0xFF;
+
+ /* Polarity */
+ hltdc_discovery.Init.HSPolarity = LTDC_HSPOLARITY_AL;
+ hltdc_discovery.Init.VSPolarity = LTDC_VSPOLARITY_AL;
+ hltdc_discovery.Init.DEPolarity = LTDC_DEPOLARITY_AL;
+ hltdc_discovery.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
+
+ /* Initialize & Start the LTDC */
+ HAL_LTDC_Init(&hltdc_discovery);
+
+#if !defined(DATA_IN_ExtSDRAM)
+ /* Initialize the SDRAM */
+ BSP_SDRAM_Init();
+#endif /* DATA_IN_ExtSDRAM */
+
+ /* Initialize the font */
+ BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
+/************************End LTDC Initialization*******************************/
+
+ return LCD_OK;
+}
+#endif /* USE_LCD_HDMI */
+
+/**
+ * @brief BSP LCD Reset
+ * Hw reset the LCD DSI activating its XRES signal (active low for some time)
+ * and deactivating it later.
+ * @retval None
+ */
+void BSP_LCD_Reset(void)
+{
+ GPIO_InitTypeDef gpio_init_structure;
+
+ __HAL_RCC_GPIOG_CLK_ENABLE();
+
+ /* Configure the GPIO on PG3 */
+ gpio_init_structure.Pin = GPIO_PIN_3;
+ gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+
+ HAL_GPIO_Init(GPIOG, &gpio_init_structure);
+
+ /* Activate XRES active low */
+ HAL_GPIO_WritePin(GPIOG, GPIO_PIN_3, GPIO_PIN_RESET);
+
+ HAL_Delay(20); /* wait 20 ms */
+
+ /* Desactivate XRES */
+ HAL_GPIO_WritePin(GPIOG, GPIO_PIN_3, GPIO_PIN_SET);
+
+ /* Wait for 10ms after releasing XRES before sending commands */
+ HAL_Delay(10);
+}
+
+/**
+ * @brief Gets the LCD X size.
+ * @retval Used LCD X size
+ */
+uint32_t BSP_LCD_GetXSize(void)
+{
+ return (lcd_x_size);
+}
+
+/**
+ * @brief Gets the LCD Y size.
+ * @retval Used LCD Y size
+ */
+uint32_t BSP_LCD_GetYSize(void)
+{
+ return (lcd_y_size);
+}
+
+/**
+ * @brief Set the LCD X size.
+ * @param imageWidthPixels : uint32_t image width in pixels unit
+ * @retval None
+ */
+void BSP_LCD_SetXSize(uint32_t imageWidthPixels)
+{
+ hltdc_discovery.LayerCfg[ActiveLayer].ImageWidth = imageWidthPixels;
+}
+
+/**
+ * @brief Set the LCD Y size.
+ * @param imageHeightPixels : uint32_t image height in lines unit
+ */
+void BSP_LCD_SetYSize(uint32_t imageHeightPixels)
+{
+ hltdc_discovery.LayerCfg[ActiveLayer].ImageHeight = imageHeightPixels;
+}
+
+
+/**
+ * @brief Initializes the LCD layers.
+ * @param LayerIndex: Layer foreground or background
+ * @param FB_Address: Layer frame buffer
+ * @retval None
+ */
+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(&hltdc_discovery, &Layercfg, LayerIndex);
+
+ DrawProp[LayerIndex].BackColor = LCD_COLOR_WHITE;
+ DrawProp[LayerIndex].pFont = &Font24;
+ DrawProp[LayerIndex].TextColor = LCD_COLOR_BLACK;
+}
+
+
+/**
+ * @brief Selects the LCD Layer.
+ * @param LayerIndex: Layer foreground or background
+ */
+void BSP_LCD_SelectLayer(uint32_t LayerIndex)
+{
+ ActiveLayer = LayerIndex;
+}
+
+/**
+ * @brief Sets an LCD Layer visible
+ * @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
+ */
+void BSP_LCD_SetLayerVisible(uint32_t LayerIndex, FunctionalState State)
+{
+ if(State == ENABLE)
+ {
+ __HAL_LTDC_LAYER_ENABLE(&(hltdc_discovery), LayerIndex);
+ }
+ else
+ {
+ __HAL_LTDC_LAYER_DISABLE(&(hltdc_discovery), LayerIndex);
+ }
+ __HAL_LTDC_RELOAD_CONFIG(&(hltdc_discovery));
+
+}
+
+/**
+ * @brief Configures the transparency.
+ * @param LayerIndex: Layer foreground or background.
+ * @param Transparency: Transparency
+ * This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF
+ */
+void BSP_LCD_SetTransparency(uint32_t LayerIndex, uint8_t Transparency)
+{
+
+ HAL_LTDC_SetAlpha(&(hltdc_discovery), Transparency, LayerIndex);
+
+}
+
+/**
+ * @brief Sets an LCD layer frame buffer address.
+ * @param LayerIndex: Layer foreground or background
+ * @param Address: New LCD frame buffer value
+ */
+void BSP_LCD_SetLayerAddress(uint32_t LayerIndex, uint32_t Address)
+{
+
+ HAL_LTDC_SetAddress(&(hltdc_discovery), Address, LayerIndex);
+
+}
+
+/**
+ * @brief Sets 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(&(hltdc_discovery), Width, Height, LayerIndex);
+
+ /* Reconfigure the layer position */
+ HAL_LTDC_SetWindowPosition(&(hltdc_discovery), Xpos, Ypos, LayerIndex);
+
+}
+
+/**
+ * @brief Configures and sets the color keying.
+ * @param LayerIndex: Layer foreground or background
+ * @param RGBValue: Color reference
+ */
+void BSP_LCD_SetColorKeying(uint32_t LayerIndex, uint32_t RGBValue)
+{
+ /* Configure and Enable the color Keying for LCD Layer */
+ HAL_LTDC_ConfigColorKeying(&(hltdc_discovery), RGBValue, LayerIndex);
+ HAL_LTDC_EnableColorKeying(&(hltdc_discovery), LayerIndex);
+}
+
+/**
+ * @brief Disables the color keying.
+ * @param LayerIndex: Layer foreground or background
+ */
+void BSP_LCD_ResetColorKeying(uint32_t LayerIndex)
+{
+ /* Disable the color Keying for LCD Layer */
+ HAL_LTDC_DisableColorKeying(&(hltdc_discovery), LayerIndex);
+}
+
+/**
+ * @brief Sets the LCD text color.
+ * @param Color: Text color code ARGB(8-8-8-8)
+ */
+void BSP_LCD_SetTextColor(uint32_t Color)
+{
+ DrawProp[ActiveLayer].TextColor = Color;
+}
+
+/**
+ * @brief Gets the LCD text color.
+ * @retval Used text color.
+ */
+uint32_t BSP_LCD_GetTextColor(void)
+{
+ return DrawProp[ActiveLayer].TextColor;
+}
+
+/**
+ * @brief Sets the LCD background color.
+ * @param Color: Layer background color code ARGB(8-8-8-8)
+ */
+void BSP_LCD_SetBackColor(uint32_t Color)
+{
+ DrawProp[ActiveLayer].BackColor = Color;
+}
+
+/**
+ * @brief Gets the LCD background color.
+ * @retval Used background color
+ */
+uint32_t BSP_LCD_GetBackColor(void)
+{
+ return DrawProp[ActiveLayer].BackColor;
+}
+
+/**
+ * @brief Sets the LCD text font.
+ * @param fonts: Layer font to be used
+ */
+void BSP_LCD_SetFont(sFONT *fonts)
+{
+ DrawProp[ActiveLayer].pFont = fonts;
+}
+
+/**
+ * @brief Gets the LCD text font.
+ * @retval Used layer font
+ */
+sFONT *BSP_LCD_GetFont(void)
+{
+ return DrawProp[ActiveLayer].pFont;
+}
+
+/**
+ * @brief Reads an LCD pixel.
+ * @param Xpos: X position
+ * @param Ypos: Y position
+ * @retval RGB pixel color
+ */
+uint32_t BSP_LCD_ReadPixel(uint16_t Xpos, uint16_t Ypos)
+{
+ uint32_t ret = 0;
+
+ if(hltdc_discovery.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888)
+ {
+ /* Read data value from SDRAM memory */
+ ret = *(__IO uint32_t*) (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress + (4*(Ypos*BSP_LCD_GetXSize() + Xpos)));
+ }
+ else if(hltdc_discovery.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB888)
+ {
+ /* Read data value from SDRAM memory */
+ ret = (*(__IO uint32_t*) (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress + (4*(Ypos*BSP_LCD_GetXSize() + Xpos))) & 0x00FFFFFF);
+ }
+ else if((hltdc_discovery.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \
+ (hltdc_discovery.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \
+ (hltdc_discovery.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_AL88))
+ {
+ /* Read data value from SDRAM memory */
+ ret = *(__IO uint16_t*) (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress + (2*(Ypos*BSP_LCD_GetXSize() + Xpos)));
+ }
+ else
+ {
+ /* Read data value from SDRAM memory */
+ ret = *(__IO uint8_t*) (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress + (2*(Ypos*BSP_LCD_GetXSize() + Xpos)));
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Clears the whole currently active layer of LTDC.
+ * @param Color: Color of the background
+ * @retval None
+ */
+void BSP_LCD_Clear(uint32_t Color)
+{
+ /* Clear the LCD */
+ LL_FillBuffer(ActiveLayer, (uint32_t *)(hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress), BSP_LCD_GetXSize(), BSP_LCD_GetYSize(), 0, Color);
+}
+
+/**
+ * @brief Clears the selected line in currently active layer.
+ * @param Line: Line to be cleared
+ * @retval None
+ */
+void BSP_LCD_ClearStringLine(uint32_t Line)
+{
+ uint32_t color_backup = 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 = color_backup;
+ BSP_LCD_SetTextColor(DrawProp[ActiveLayer].TextColor);
+}
+
+/**
+ * @brief Displays one character in currently active layer.
+ * @param Xpos: Start column address
+ * @param Ypos: Line where to display the character shape.
+ * @param Ascii: Character ascii code
+ * This parameter must be a number between Min_Data = 0x20 and Max_Data = 0x7E
+ * @retval None
+ */
+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 characters in currently active layer.
+ * @param Xpos: X position (in pixel)
+ * @param Ypos: Y position (in pixel)
+ * @param Text: Pointer to string to display on LCD
+ * @param Mode: Display mode
+ * This parameter can be one of the following values:
+ * @arg CENTER_MODE
+ * @arg RIGHT_MODE
+ * @arg LEFT_MODE
+ * @retval None
+ */
+void BSP_LCD_DisplayStringAt(uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Text_AlignModeTypdef Mode)
+{
+ uint16_t refcolumn = 1, i = 0;
+ uint32_t size = 0, xsize = 0;
+ uint8_t *ptr = Text;
+
+ /* 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 = Xpos + ((xsize - size)* DrawProp[ActiveLayer].pFont->Width) / 2;
+ break;
+ }
+ case LEFT_MODE:
+ {
+ refcolumn = Xpos;
+ break;
+ }
+ case RIGHT_MODE:
+ {
+ refcolumn = - Xpos + ((xsize - size)*DrawProp[ActiveLayer].pFont->Width);
+ break;
+ }
+ default:
+ {
+ refcolumn = Xpos;
+ break;
+ }
+ }
+
+ /* Check that the Start column is located in the screen */
+ if ((refcolumn < 1) || (refcolumn >= 0x8000))
+ {
+ refcolumn = 1;
+ }
+
+ /* Send the string character by character on LCD */
+ while ((*Text != 0) & (((BSP_LCD_GetXSize() - (i*DrawProp[ActiveLayer].pFont->Width)) & 0xFFFF) >= DrawProp[ActiveLayer].pFont->Width))
+ {
+ /* Display one character on LCD */
+ BSP_LCD_DisplayChar(refcolumn, Ypos, *Text);
+ /* Decrement the column position by 16 */
+ refcolumn += DrawProp[ActiveLayer].pFont->Width;
+
+ /* Point on the next character */
+ Text++;
+ i++;
+ }
+
+}
+
+/**
+ * @brief Displays a maximum of 60 characters on the LCD.
+ * @param Line: Line where to display the character shape
+ * @param ptr: Pointer to string to display on LCD
+ * @retval None
+ */
+void BSP_LCD_DisplayStringAtLine(uint16_t Line, uint8_t *ptr)
+{
+ BSP_LCD_DisplayStringAt(0, LINE(Line), ptr, LEFT_MODE);
+}
+
+/**
+ * @brief Draws an horizontal line in currently active layer.
+ * @param Xpos: X position
+ * @param Ypos: Y position
+ * @param Length: Line length
+ * @retval None
+ */
+void BSP_LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length)
+{
+ uint32_t Xaddress = 0;
+
+ /* Get the line address */
+ Xaddress = (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress) + 4*(BSP_LCD_GetXSize()*Ypos + Xpos);
+
+ /* Write line */
+ LL_FillBuffer(ActiveLayer, (uint32_t *)Xaddress, Length, 1, 0, DrawProp[ActiveLayer].TextColor);
+}
+
+/**
+ * @brief Draws a vertical line in currently active layer.
+ * @param Xpos: X position
+ * @param Ypos: Y position
+ * @param Length: Line length
+ * @retval None
+ */
+void BSP_LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length)
+{
+ uint32_t Xaddress = 0;
+
+ /* Get the line address */
+ Xaddress = (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress) + 4*(BSP_LCD_GetXSize()*Ypos + Xpos);
+
+ /* Write line */
+ LL_FillBuffer(ActiveLayer, (uint32_t *)Xaddress, 1, Length, (BSP_LCD_GetXSize() - 1), DrawProp[ActiveLayer].TextColor);
+}
+
+/**
+ * @brief Draws an uni-line (between two points) in currently active layer.
+ * @param x1: Point 1 X position
+ * @param y1: Point 1 Y position
+ * @param x2: Point 2 X position
+ * @param y2: Point 2 Y position
+ * @retval None
+ */
+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 Draws a rectangle in currently active layer.
+ * @param Xpos: X position
+ * @param Ypos: Y position
+ * @param Width: Rectangle width
+ * @param Height: Rectangle height
+ * @retval None
+ */
+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 Draws a circle in currently active layer.
+ * @param Xpos: X position
+ * @param Ypos: Y position
+ * @param Radius: Circle radius
+ * @retval None
+ */
+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 Draws an poly-line (between many points) in currently active layer.
+ * @param Points: Pointer to the points array
+ * @param PointCount: Number of points
+ * @retval None
+ */
+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 Draws an ellipse on LCD in currently active layer.
+ * @param Xpos: X position
+ * @param Ypos: Y position
+ * @param XRadius: Ellipse X radius
+ * @param YRadius: Ellipse Y radius
+ * @retval None
+ */
+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 Draws a bitmap picture loaded in the internal Flash (32 bpp) in currently active layer.
+ * @param Xpos: Bmp X position in the LCD
+ * @param Ypos: Bmp Y position in the LCD
+ * @param pbmp: Pointer to Bmp picture address in the internal Flash
+ * @retval None
+ */
+void BSP_LCD_DrawBitmap(uint32_t Xpos, uint32_t Ypos, uint8_t *pbmp)
+{
+ uint32_t index = 0, width = 0, height = 0, bit_pixel = 0;
+ uint32_t Address;
+ uint32_t InputColorMode = 0;
+
+ /* Get bitmap data address offset */
+ index = *(__IO uint16_t *) (pbmp + 10);
+ index |= (*(__IO uint16_t *) (pbmp + 12)) << 16;
+
+ /* Read bitmap width */
+ width = *(uint16_t *) (pbmp + 18);
+ width |= (*(uint16_t *) (pbmp + 20)) << 16;
+
+ /* Read bitmap height */
+ height = *(uint16_t *) (pbmp + 22);
+ height |= (*(uint16_t *) (pbmp + 24)) << 16;
+
+ /* Read bit/pixel */
+ bit_pixel = *(uint16_t *) (pbmp + 28);
+
+ /* Set the address */
+ Address = hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress + (((BSP_LCD_GetXSize()*Ypos) + Xpos)*(4));
+
+ /* Get the layer pixel format */
+ if ((bit_pixel/8) == 4)
+ {
+ InputColorMode = DMA2D_INPUT_ARGB8888;
+ }
+ else if ((bit_pixel/8) == 2)
+ {
+ InputColorMode = DMA2D_INPUT_RGB565;
+ }
+ else
+ {
+ InputColorMode = DMA2D_INPUT_RGB888;
+ }
+
+ /* Bypass the bitmap header */
+ pbmp += (index + (width * (height - 1) * (bit_pixel/8)));
+
+ /* Convert picture to ARGB8888 pixel format */
+ for(index=0; index < height; index++)
+ {
+ /* Pixel format conversion */
+ LL_ConvertLineToARGB8888((uint32_t *)pbmp, (uint32_t *)Address, width, InputColorMode);
+
+ /* Increment the source and destination buffers */
+ Address+= (BSP_LCD_GetXSize()*4);
+ pbmp -= width*(bit_pixel/8);
+ }
+}
+
+/**
+ * @brief Draws a full rectangle in currently active layer.
+ * @param Xpos: X position
+ * @param Ypos: Y position
+ * @param Width: Rectangle width
+ * @param Height: Rectangle height
+ * @retval None
+ */
+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 = (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress) + 4*(BSP_LCD_GetXSize()*Ypos + Xpos);
+
+ /* Fill the rectangle */
+ LL_FillBuffer(ActiveLayer, (uint32_t *)Xaddress, Width, Height, (BSP_LCD_GetXSize() - Width), DrawProp[ActiveLayer].TextColor);
+}
+
+/**
+ * @brief Draws a full circle in currently active layer.
+ * @param Xpos: X position
+ * @param Ypos: Y position
+ * @param Radius: Circle radius
+ * @retval None
+ */
+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 Draws a full poly-line (between many points) in currently active layer.
+ * @param Points: Pointer to the points array
+ * @param PointCount: Number of points
+ * @retval None
+ */
+void BSP_LCD_FillPolygon(pPoint Points, uint16_t PointCount)
+{
+ int16_t X = 0, Y = 0, X2 = 0, Y2 = 0, X_center = 0, Y_center = 0, X_first = 0, Y_first = 0, pixelX = 0, pixelY = 0, counter = 0;
+ uint16_t IMAGE_LEFT = 0, IMAGE_RIGHT = 0, IMAGE_TOP = 0, IMAGE_BOTTOM = 0;
+
+ IMAGE_LEFT = IMAGE_RIGHT = Points->X;
+ IMAGE_TOP= IMAGE_BOTTOM = Points->Y;
+
+ for(counter = 1; counter < PointCount; counter++)
+ {
+ pixelX = POLY_X(counter);
+ if(pixelX < IMAGE_LEFT)
+ {
+ IMAGE_LEFT = pixelX;
+ }
+ if(pixelX > IMAGE_RIGHT)
+ {
+ IMAGE_RIGHT = pixelX;
+ }
+
+ pixelY = POLY_Y(counter);
+ if(pixelY < IMAGE_TOP)
+ {
+ IMAGE_TOP = pixelY;
+ }
+ if(pixelY > IMAGE_BOTTOM)
+ {
+ IMAGE_BOTTOM = pixelY;
+ }
+ }
+
+ if(PointCount < 2)
+ {
+ return;
+ }
+
+ X_center = (IMAGE_LEFT + IMAGE_RIGHT)/2;
+ Y_center = (IMAGE_BOTTOM + IMAGE_TOP)/2;
+
+ X_first = Points->X;
+ Y_first = Points->Y;
+
+ while(--PointCount)
+ {
+ X = Points->X;
+ Y = Points->Y;
+ Points++;
+ X2 = Points->X;
+ Y2 = Points->Y;
+
+ FillTriangle(X, X2, X_center, Y, Y2, Y_center);
+ FillTriangle(X, X_center, X2, Y, Y_center, Y2);
+ FillTriangle(X_center, X2, X, Y_center, Y2, Y);
+ }
+
+ FillTriangle(X_first, X2, X_center, Y_first, Y2, Y_center);
+ FillTriangle(X_first, X_center, X2, Y_first, Y_center, Y2);
+ FillTriangle(X_center, X2, X_first, Y_center, Y2, Y_first);
+}
+
+/**
+ * @brief Draws a full ellipse in currently active layer.
+ * @param Xpos: X position
+ * @param Ypos: Y position
+ * @param XRadius: Ellipse X radius
+ * @param YRadius: Ellipse Y radius
+ * @retval None
+ */
+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 Switch back on the display if was switched off by previous call of BSP_LCD_DisplayOff().
+ * Exit DSI ULPM mode if was allowed and configured in Dsi Configuration.
+ * @retval None
+ */
+void BSP_LCD_DisplayOn(void)
+{
+#if defined(USE_LCD_HDMI)
+ if(ADV7533_ID == adv7533_drv.ReadID(ADV7533_CEC_DSI_I2C_ADDR))
+ {
+ return ; /* Not supported for HDMI display */
+ }
+ else
+#endif /* USE_LCD_HDMI */
+ {
+
+ /* Send Display on DCS command to display */
+ HAL_DSI_ShortWrite(&(hdsi_discovery),
+ hdsivideo_handle.VirtualChannelID,
+ DSI_DCS_SHORT_PKT_WRITE_P1,
+ OTM8009A_CMD_DISPON,
+ 0x00);
+ }
+
+}
+
+/**
+ * @brief Switch Off the display.
+ * Enter DSI ULPM mode if was allowed and configured in Dsi Configuration.
+ * @retval None
+ */
+void BSP_LCD_DisplayOff(void)
+{
+#if defined(USE_LCD_HDMI)
+ if(ADV7533_ID == adv7533_drv.ReadID(ADV7533_CEC_DSI_I2C_ADDR))
+ {
+ return ; /* Not supported for HDMI yet */
+ }
+ else
+#endif /* USE_LCD_HDMI */
+ {
+ /* Send Display off DCS Command to display */
+ HAL_DSI_ShortWrite(&(hdsi_discovery),
+ hdsivideo_handle.VirtualChannelID,
+ DSI_DCS_SHORT_PKT_WRITE_P1,
+ OTM8009A_CMD_DISPOFF,
+ 0x00);
+ }
+
+}
+
+/**
+ * @brief Set the brightness value
+ * @param BrightnessValue: [00: Min (black), 100 Max]
+ * @retval None
+ */
+void BSP_LCD_SetBrightness(uint8_t BrightnessValue)
+{
+#if defined(USE_LCD_HDMI)
+ if(ADV7533_ID == adv7533_drv.ReadID(ADV7533_CEC_DSI_I2C_ADDR))
+ {
+ return ; /* Not supported for HDMI display */
+ }
+ else
+#endif /* USE_LCD_HDMI */
+ {
+ /* Send Display on DCS command to display */
+ HAL_DSI_ShortWrite(&hdsi_discovery,
+ LCD_OTM8009A_ID,
+ DSI_DCS_SHORT_PKT_WRITE_P1,
+ OTM8009A_CMD_WRDISBV, (uint16_t)(BrightnessValue * 255)/100);
+ }
+
+}
+
+/**
+ * @brief DCS or Generic short/long write command
+ * @param NbrParams: Number of parameters. It indicates the write command mode:
+ * If inferior to 2, a long write command is performed else short.
+ * @param pParams: Pointer to parameter values table.
+ * @retval None
+ */
+void DSI_IO_WriteCmd(uint32_t NbrParams, uint8_t *pParams)
+{
+ if(NbrParams <= 1)
+ {
+ HAL_DSI_ShortWrite(&hdsi_discovery, LCD_OTM8009A_ID, DSI_DCS_SHORT_PKT_WRITE_P1, pParams[0], pParams[1]);
+ }
+ else
+ {
+ HAL_DSI_LongWrite(&hdsi_discovery, LCD_OTM8009A_ID, DSI_DCS_LONG_PKT_WRITE, NbrParams, pParams[NbrParams], pParams);
+ }
+}
+
+/**
+ * @brief Returns the ID of connected screen by checking the HDMI
+ * (adv7533 component) ID or LCD DSI (via TS ID) ID.
+ * @retval LCD ID
+ */
+static uint16_t LCD_IO_GetID(void)
+{
+#if defined(USE_LCD_HDMI)
+ HDMI_IO_Init();
+
+ HDMI_IO_Delay(120);
+
+ if(ADV7533_ID == adv7533_drv.ReadID(ADV7533_CEC_DSI_I2C_ADDR))
+ {
+ return ADV7533_ID;
+ }
+ else if(((HDMI_IO_Read(LCD_DSI_ADDRESS, LCD_DSI_ID_REG) == LCD_DSI_ID)) || \
+ (HDMI_IO_Read(LCD_DSI_ADDRESS_A02, LCD_DSI_ID_REG) == LCD_DSI_ID))
+ {
+ return LCD_DSI_ID;
+ }
+ else
+ {
+ return 0;
+ }
+#else
+ return LCD_DSI_ID;
+#endif /* USE_LCD_HDMI */
+
+}
+
+/*******************************************************************************
+ LTDC, DMA2D and DSI BSP Routines
+*******************************************************************************/
+/**
+ * @brief De-Initializes the BSP LCD Msp
+ * Application can surcharge if needed this function implementation.
+ * @retval None
+ */
+__weak void BSP_LCD_MspDeInit(void)
+{
+ /** @brief Disable IRQ of LTDC IP */
+ HAL_NVIC_DisableIRQ(LTDC_IRQn);
+
+ /** @brief Disable IRQ of DMA2D IP */
+ HAL_NVIC_DisableIRQ(DMA2D_IRQn);
+
+ /** @brief Disable IRQ of DSI IP */
+ HAL_NVIC_DisableIRQ(DSI_IRQn);
+
+ /** @brief Force and let in reset state LTDC, DMA2D and DSI Host + Wrapper IPs */
+ __HAL_RCC_LTDC_FORCE_RESET();
+ __HAL_RCC_DMA2D_FORCE_RESET();
+ __HAL_RCC_DSI_FORCE_RESET();
+
+ /** @brief Disable the LTDC, DMA2D and DSI Host and Wrapper clocks */
+ __HAL_RCC_LTDC_CLK_DISABLE();
+ __HAL_RCC_DMA2D_CLK_DISABLE();
+ __HAL_RCC_DSI_CLK_DISABLE();
+}
+
+/**
+ * @brief Initialize the BSP LCD Msp.
+ * Application can surcharge if needed this function implementation
+ * @retval None
+ */
+__weak void BSP_LCD_MspInit(void)
+{
+ /** @brief Enable the LTDC clock */
+ __HAL_RCC_LTDC_CLK_ENABLE();
+
+ /** @brief Toggle Sw reset of LTDC IP */
+ __HAL_RCC_LTDC_FORCE_RESET();
+ __HAL_RCC_LTDC_RELEASE_RESET();
+
+ /** @brief Enable the DMA2D clock */
+ __HAL_RCC_DMA2D_CLK_ENABLE();
+
+ /** @brief Toggle Sw reset of DMA2D IP */
+ __HAL_RCC_DMA2D_FORCE_RESET();
+ __HAL_RCC_DMA2D_RELEASE_RESET();
+
+ /** @brief Enable DSI Host and wrapper clocks */
+ __HAL_RCC_DSI_CLK_ENABLE();
+
+ /** @brief Soft Reset the DSI Host and wrapper */
+ __HAL_RCC_DSI_FORCE_RESET();
+ __HAL_RCC_DSI_RELEASE_RESET();
+
+ /** @brief NVIC configuration for LTDC interrupt that is now enabled */
+ HAL_NVIC_SetPriority(LTDC_IRQn, 0x0F, 0);
+ HAL_NVIC_EnableIRQ(LTDC_IRQn);
+
+ /** @brief NVIC configuration for DMA2D interrupt that is now enabled */
+ HAL_NVIC_SetPriority(DMA2D_IRQn, 0x0F, 0);
+ HAL_NVIC_EnableIRQ(DMA2D_IRQn);
+
+ /** @brief NVIC configuration for DSI interrupt that is now enabled */
+ HAL_NVIC_SetPriority(DSI_IRQn, 0x0F, 0);
+ HAL_NVIC_EnableIRQ(DSI_IRQn);
+}
+
+/**
+ * @brief Draws a pixel on LCD.
+ * @param Xpos: X position
+ * @param Ypos: Y position
+ * @param RGB_Code: Pixel color in ARGB mode (8-8-8-8)
+ * @retval None
+ */
+void BSP_LCD_DrawPixel(uint16_t Xpos, uint16_t Ypos, uint32_t RGB_Code)
+{
+ /* Write data value to all SDRAM memory */
+ *(__IO uint32_t*) (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress + (4*(Ypos*BSP_LCD_GetXSize() + Xpos))) = RGB_Code;
+}
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LCD_Private_Functions Private Functions
+ * @{
+ */
+
+/**
+ * @brief Draws a character on LCD.
+ * @param Xpos: Line where to display the character shape
+ * @param Ypos: Start column address
+ * @param c: Pointer to the character data
+ * @retval None
+ */
+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;
+
+ 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 a triangle (between 3 points).
+ * @param x1: Point 1 X position
+ * @param y1: Point 1 Y position
+ * @param x2: Point 2 X position
+ * @param y2: Point 2 Y position
+ * @param x3: Point 3 X position
+ * @param y3: Point 3 Y position
+ * @retval None
+ */
+static void 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 Fills a buffer.
+ * @param LayerIndex: Layer index
+ * @param pDst: Pointer to destination buffer
+ * @param xSize: Buffer width
+ * @param ySize: Buffer height
+ * @param OffLine: Offset
+ * @param ColorIndex: Color index
+ * @retval None
+ */
+static void LL_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 */
+ hdma2d_discovery.Init.Mode = DMA2D_R2M;
+ hdma2d_discovery.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
+ hdma2d_discovery.Init.OutputOffset = OffLine;
+
+ hdma2d_discovery.Instance = DMA2D;
+
+ /* DMA2D Initialization */
+ if(HAL_DMA2D_Init(&hdma2d_discovery) == HAL_OK)
+ {
+ if(HAL_DMA2D_ConfigLayer(&hdma2d_discovery, 1) == HAL_OK)
+ {
+ if (HAL_DMA2D_Start(&hdma2d_discovery, ColorIndex, (uint32_t)pDst, xSize, ySize) == HAL_OK)
+ {
+ /* Polling For DMA transfer */
+ HAL_DMA2D_PollForTransfer(&hdma2d_discovery, 25);
+ }
+ }
+ }
+}
+
+/**
+ * @brief Converts a line to an ARGB8888 pixel format.
+ * @param pSrc: Pointer to source buffer
+ * @param pDst: Output color
+ * @param xSize: Buffer width
+ * @param ColorMode: Input color mode
+ * @retval None
+ */
+static void LL_ConvertLineToARGB8888(void *pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode)
+{
+ /* Configure the DMA2D Mode, Color Mode and output offset */
+ hdma2d_discovery.Init.Mode = DMA2D_M2M_PFC;
+ hdma2d_discovery.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
+ hdma2d_discovery.Init.OutputOffset = 0;
+
+ /* Foreground Configuration */
+ hdma2d_discovery.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
+ hdma2d_discovery.LayerCfg[1].InputAlpha = 0xFF;
+ hdma2d_discovery.LayerCfg[1].InputColorMode = ColorMode;
+ hdma2d_discovery.LayerCfg[1].InputOffset = 0;
+
+ hdma2d_discovery.Instance = DMA2D;
+
+ /* DMA2D Initialization */
+ if(HAL_DMA2D_Init(&hdma2d_discovery) == HAL_OK)
+ {
+ if(HAL_DMA2D_ConfigLayer(&hdma2d_discovery, 1) == HAL_OK)
+ {
+ if (HAL_DMA2D_Start(&hdma2d_discovery, (uint32_t)pSrc, (uint32_t)pDst, xSize, 1) == HAL_OK)
+ {
+ /* Polling For DMA transfer */
+ HAL_DMA2D_PollForTransfer(&hdma2d_discovery, 25);
+ }
+ }
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery_lcd.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,402 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery_lcd.h
+ * @author MCD Application Team
+ * @brief This file contains the common defines and functions prototypes for
+ * the stm32h747i_discovery_lcd.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32H747I_DISCOVERY_LCD_H
+#define __STM32H747I_DISCOVERY_LCD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+/* Include LCD component Driver */
+
+/* Include OTM8009A LCD Driver IC driver code */
+#include "../Components/otm8009a/otm8009a.h"
+
+#if defined(USE_LCD_HDMI)
+/* Include ADV7533 HDMI Driver IC driver code */
+#include "../Components/adv7533/adv7533.h"
+#endif /* USE_LCD_HDMI */
+
+/* Include SDRAM Driver */
+#include "stm32h747i_discovery_sdram.h"
+#include "stm32h747i_discovery.h"
+
+#include "../Utilities/Fonts/fonts.h"
+
+#include <string.h> /* use of memset() */
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY_LCD
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LCD_Exported_Constants Exported Constants
+ * @{
+ */
+#define BSP_LCD_DMA2D_IRQHandler DMA2D_IRQHandler
+#define BSP_LCD_DSI_IRQHandler DSI_IRQHandler
+#define BSP_LCD_LTDC_IRQHandler LTDC_IRQHandler
+#define BSP_LCD_LTDC_ER_IRQHandler LTDC_ER_IRQHandler
+
+
+#define LCD_LayerCfgTypeDef LTDC_LayerCfgTypeDef
+/**
+ * @brief LCD FB_StartAddress
+ */
+#define LCD_FB_START_ADDRESS ((uint32_t)0xD0000000)
+
+/** @brief Maximum number of LTDC layers
+ */
+#define LTDC_MAX_LAYER_NUMBER ((uint32_t) 2)
+
+/** @brief LTDC Background layer index
+ */
+#define LTDC_ACTIVE_LAYER_BACKGROUND ((uint32_t) 0)
+
+/** @brief LTDC Foreground layer index
+ */
+#define LTDC_ACTIVE_LAYER_FOREGROUND ((uint32_t) 1)
+
+/** @brief Number of LTDC layers
+ */
+#define LTDC_NB_OF_LAYERS ((uint32_t) 2)
+
+/** @brief LTDC Default used layer index
+ */
+#define LTDC_DEFAULT_ACTIVE_LAYER LTDC_ACTIVE_LAYER_FOREGROUND
+
+/**
+ * @brief LCD status structure definition
+ */
+#define LCD_OK 0x00
+#define LCD_ERROR 0x01
+#define LCD_TIMEOUT 0x02
+
+/**
+ * @brief LCD Display OTM8009A ID
+ */
+#define LCD_OTM8009A_ID ((uint32_t) 0)
+
+#if defined(USE_LCD_HDMI)
+/**
+ * @brief HDMI ADV7533 DSI Virtual Channel ID
+ */
+#define HDMI_ADV7533_ID ((uint32_t) 0)
+
+/**
+ * @brief HDMI Foramt
+ */
+#define HDMI_FORMAT_720_480 ((uint8_t) 0x00) /*720_480 format choice of HDMI display */
+#define HDMI_FORMAT_720_576 ((uint8_t) 0x01) /*720_576 format choice of HDMI display*/
+
+#endif /* USE_LCD_HDMI */
+
+/**
+ * @brief LCD color definitions values
+ * in ARGB8888 format.
+ */
+
+/** @brief Blue value in ARGB8888 format
+ */
+#define LCD_COLOR_BLUE ((uint32_t) 0xFF0000FF)
+
+/** @brief Green value in ARGB8888 format
+ */
+#define LCD_COLOR_GREEN ((uint32_t) 0xFF00FF00)
+
+/** @brief Red value in ARGB8888 format
+ */
+#define LCD_COLOR_RED ((uint32_t) 0xFFFF0000)
+
+/** @brief Cyan value in ARGB8888 format
+ */
+#define LCD_COLOR_CYAN ((uint32_t) 0xFF00FFFF)
+
+/** @brief Magenta value in ARGB8888 format
+ */
+#define LCD_COLOR_MAGENTA ((uint32_t) 0xFFFF00FF)
+
+/** @brief Yellow value in ARGB8888 format
+ */
+#define LCD_COLOR_YELLOW ((uint32_t) 0xFFFFFF00)
+
+/** @brief Light Blue value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTBLUE ((uint32_t) 0xFF8080FF)
+
+/** @brief Light Green value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTGREEN ((uint32_t) 0xFF80FF80)
+
+/** @brief Light Red value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTRED ((uint32_t) 0xFFFF8080)
+
+/** @brief Light Cyan value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTCYAN ((uint32_t) 0xFF80FFFF)
+
+/** @brief Light Magenta value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTMAGENTA ((uint32_t) 0xFFFF80FF)
+
+/** @brief Light Yellow value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTYELLOW ((uint32_t) 0xFFFFFF80)
+
+/** @brief Dark Blue value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKBLUE ((uint32_t) 0xFF000080)
+
+/** @brief Light Dark Green value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKGREEN ((uint32_t) 0xFF008000)
+
+/** @brief Light Dark Red value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKRED ((uint32_t) 0xFF800000)
+
+/** @brief Dark Cyan value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKCYAN ((uint32_t) 0xFF008080)
+
+/** @brief Dark Magenta value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKMAGENTA ((uint32_t) 0xFF800080)
+
+/** @brief Dark Yellow value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKYELLOW ((uint32_t) 0xFF808000)
+
+/** @brief White value in ARGB8888 format
+ */
+#define LCD_COLOR_WHITE ((uint32_t) 0xFFFFFFFF)
+
+/** @brief Light Gray value in ARGB8888 format
+ */
+#define LCD_COLOR_LIGHTGRAY ((uint32_t) 0xFFD3D3D3)
+
+/** @brief Gray value in ARGB8888 format
+ */
+#define LCD_COLOR_GRAY ((uint32_t) 0xFF808080)
+
+/** @brief Dark Gray value in ARGB8888 format
+ */
+#define LCD_COLOR_DARKGRAY ((uint32_t) 0xFF404040)
+
+/** @brief Black value in ARGB8888 format
+ */
+#define LCD_COLOR_BLACK ((uint32_t) 0xFF000000)
+
+/** @brief Brown value in ARGB8888 format
+ */
+#define LCD_COLOR_BROWN ((uint32_t) 0xFFA52A2A)
+
+/** @brief Orange value in ARGB8888 format
+ */
+#define LCD_COLOR_ORANGE ((uint32_t) 0xFFFFA500)
+
+/** @brief Transparent value in ARGB8888 format
+ */
+#define LCD_COLOR_TRANSPARENT ((uint32_t) 0xFF000000)
+
+/**
+ * @brief LCD default font
+ */
+#define LCD_DEFAULT_FONT Font24
+
+/**
+ * @brief Possible values of
+ * pixel data format (ie color coding) transmitted on DSI Data lane in DSI packets
+ */
+
+#define LCD_DSI_PIXEL_DATA_FMT_RBG888 DSI_RGB888 /*!< DSI packet pixel format chosen is RGB888 : 24 bpp */
+#define LCD_DSI_PIXEL_DATA_FMT_RBG565 DSI_RGB565 /*!< DSI packet pixel format chosen is RGB565 : 16 bpp */
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_LCD_Exported_Types Exported Types
+ * @{
+ */
+
+/**
+ * @brief LCD Drawing main properties
+ */
+typedef struct
+{
+ uint32_t TextColor; /*!< Specifies the color of text */
+ uint32_t BackColor; /*!< Specifies the background color below the text */
+ sFONT *pFont; /*!< Specifies the font used for the text */
+
+} LCD_DrawPropTypeDef;
+
+/**
+ * @brief LCD Drawing point (pixel) geometric definition
+ */
+typedef struct
+{
+ int16_t X; /*!< geometric X position of drawing */
+ int16_t Y; /*!< geometric Y position of drawing */
+
+} Point;
+
+/**
+ * @brief Pointer on LCD Drawing point (pixel) geometric definition
+ */
+typedef Point * pPoint;
+
+/**
+ * @brief LCD drawing Line alignment mode definitions
+ */
+typedef enum
+{
+ CENTER_MODE = 0x01, /*!< Center mode */
+ RIGHT_MODE = 0x02, /*!< Right mode */
+ LEFT_MODE = 0x03 /*!< Left mode */
+
+} Text_AlignModeTypdef;
+
+
+/**
+ * @brief LCD_OrientationTypeDef
+ * Possible values of Display Orientation
+ */
+typedef enum
+{
+ LCD_ORIENTATION_PORTRAIT = 0x00, /*!< Portrait orientation choice of LCD screen */
+ LCD_ORIENTATION_LANDSCAPE = 0x01, /*!< Landscape orientation choice of LCD screen */
+ LCD_ORIENTATION_INVALID = 0x02 /*!< Invalid orientation choice of LCD screen */
+} LCD_OrientationTypeDef;
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY_LCD_Exported_Functions
+ * @{
+ */
+uint8_t BSP_LCD_Init(void);
+uint8_t BSP_LCD_InitEx(LCD_OrientationTypeDef orientation);
+
+#if defined(USE_LCD_HDMI)
+uint8_t BSP_LCD_HDMIInitEx(uint8_t format);
+#endif /* USE_LCD_HDMI */
+
+void BSP_LCD_MspDeInit(void);
+void BSP_LCD_MspInit(void);
+void BSP_LCD_Reset(void);
+
+uint32_t BSP_LCD_GetXSize(void);
+uint32_t BSP_LCD_GetYSize(void);
+void BSP_LCD_SetXSize(uint32_t imageWidthPixels);
+void BSP_LCD_SetYSize(uint32_t imageHeightPixels);
+
+void BSP_LCD_LayerDefaultInit(uint16_t LayerIndex, uint32_t FB_Address);
+void BSP_LCD_SetTransparency(uint32_t LayerIndex, uint8_t Transparency);
+void BSP_LCD_SetLayerAddress(uint32_t LayerIndex, uint32_t Address);
+void BSP_LCD_SetColorKeying(uint32_t LayerIndex, uint32_t RGBValue);
+void BSP_LCD_ResetColorKeying(uint32_t LayerIndex);
+void BSP_LCD_SetLayerWindow(uint16_t LayerIndex, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+
+void BSP_LCD_SelectLayer(uint32_t LayerIndex);
+void BSP_LCD_SetLayerVisible(uint32_t LayerIndex, FunctionalState State);
+
+void BSP_LCD_SetTextColor(uint32_t Color);
+uint32_t BSP_LCD_GetTextColor(void);
+void BSP_LCD_SetBackColor(uint32_t Color);
+uint32_t BSP_LCD_GetBackColor(void);
+void BSP_LCD_SetFont(sFONT *fonts);
+sFONT *BSP_LCD_GetFont(void);
+
+uint32_t BSP_LCD_ReadPixel(uint16_t Xpos, uint16_t Ypos);
+void BSP_LCD_DrawPixel(uint16_t Xpos, uint16_t Ypos, uint32_t pixel);
+void BSP_LCD_Clear(uint32_t Color);
+void BSP_LCD_ClearStringLine(uint32_t Line);
+void BSP_LCD_DisplayStringAtLine(uint16_t Line, uint8_t *ptr);
+void BSP_LCD_DisplayStringAt(uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Text_AlignModeTypdef Mode);
+void BSP_LCD_DisplayChar(uint16_t Xpos, uint16_t Ypos, uint8_t Ascii);
+
+void BSP_LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+void BSP_LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length);
+void BSP_LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+void BSP_LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+void BSP_LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+void BSP_LCD_DrawPolygon(pPoint Points, uint16_t PointCount);
+void BSP_LCD_DrawEllipse(int Xpos, int Ypos, int XRadius, int YRadius);
+void BSP_LCD_DrawBitmap(uint32_t Xpos, uint32_t Ypos, uint8_t *pbmp);
+
+void BSP_LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
+void BSP_LCD_FillCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
+void BSP_LCD_FillPolygon(pPoint Points, uint16_t PointCount);
+void BSP_LCD_FillEllipse(int Xpos, int Ypos, int XRadius, int YRadius);
+
+void BSP_LCD_DisplayOff(void);
+void BSP_LCD_DisplayOn(void);
+void BSP_LCD_SetBrightness(uint8_t BrightnessValue);
+/**
+ * @}
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY_LCD_Exported_Variables
+ * @{
+ */
+
+/* @brief DMA2D handle variable */
+extern DMA2D_HandleTypeDef hdma2d_discovery;
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32H747I_DISCOVERY_LCD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery_qspi.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,893 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery_qspi.c
+ * @author MCD Application Team
+ * @brief This file includes a standard driver for the MT25TL01G QSPI
+ * memory mounted on STM32H747I-DISCOVERY board.
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) This driver is used to drive the MT25TL01G QSPI external
+ memory mounted on STM32H747I-DISCOVERY board.
+
+ (#) This driver need a specific component driver (MT25TL01G) to be included with.
+
+ (#) Initialization steps:
+ (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ QSPI interface with the external memory.
+
+ (#) QSPI memory operations
+ (++) QSPI memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_QSPI_Read()/BSP_QSPI_Write().
+ (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory.
+ (see the QSPI memory data sheet)
+ (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by
+ specifying the block address. You can perform an erase operation of the whole
+ chip by calling the function BSP_QSPI_Erase_Chip().
+ (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory.
+ (see the QSPI memory data sheet)
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h747i_discovery_qspi.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_QSPI STM32H747I_DISCOVERY_QSPI
+ * @{
+ */
+
+
+/* Private variables ---------------------------------------------------------*/
+
+/** @defgroup STM32H747I_DISCOVERY_QSPI_Private_Variables Private Variables
+ * @{
+ */
+QSPI_HandleTypeDef QSPIHandle;
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup STM32H747I_DISCOVERY_QSPI_Private_Functions Private Functions
+ * @{
+ */
+static uint8_t QSPI_ResetMemory (QSPI_HandleTypeDef *hqspi);
+static uint8_t QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi);
+static uint8_t QSPI_DummyCyclesCfg (QSPI_HandleTypeDef *hqspi);
+static uint8_t QSPI_WriteEnable (QSPI_HandleTypeDef *hqspi);
+static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout);
+static uint8_t QSPI_EnterQPI(QSPI_HandleTypeDef *hqspi);
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_QSPI_Exported_Functions Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes the QSPI interface.
+ * @retval QSPI memory status
+ */
+uint8_t BSP_QSPI_Init(void)
+{
+ QSPIHandle.Instance = QUADSPI;
+
+ /* Call the DeInit function to reset the driver */
+ if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* System level initialization */
+ BSP_QSPI_MspInit(&QSPIHandle, NULL);
+
+ /* QSPI initialization */
+ /* ClockPrescaler set to 1, so QSPI clock = 200MHz / (1+3) = 50MHz */
+ QSPIHandle.Init.ClockPrescaler = 3;
+ QSPIHandle.Init.FifoThreshold = 1;
+ QSPIHandle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
+ QSPIHandle.Init.FlashSize = POSITION_VAL(MT25TL01G_FLASH_SIZE) - 1;
+ QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_3_CYCLE;
+ QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0;
+ QSPIHandle.Init.FlashID = QSPI_FLASH_ID_2;
+ QSPIHandle.Init.DualFlash = QSPI_DUALFLASH_ENABLE;
+
+ if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* QSPI memory reset */
+ if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK)
+ {
+ return QSPI_NOT_SUPPORTED;
+ }
+
+ /* Set the QSPI memory in 4-bytes address mode */
+ if (QSPI_EnterFourBytesAddress(&QSPIHandle) != QSPI_OK)
+ {
+ return QSPI_NOT_SUPPORTED;
+ }
+
+ /* Configuration of the dummy cycles on QSPI memory side */
+ if (QSPI_DummyCyclesCfg(&QSPIHandle) != QSPI_OK)
+ {
+ return QSPI_NOT_SUPPORTED;
+ }
+
+ return QSPI_OK;
+}
+
+/**
+ * @brief De-Initializes the QSPI interface.
+ * @retval QSPI memory status
+ */
+uint8_t BSP_QSPI_DeInit(void)
+{
+ QSPIHandle.Instance = QUADSPI;
+
+ /* Call the DeInit function to reset the driver */
+ if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* System level De-initialization */
+ BSP_QSPI_MspDeInit(&QSPIHandle, NULL);
+
+ return QSPI_OK;
+}
+
+/**
+ * @brief Reads an amount of data from the QSPI memory.
+ * @param pData: Pointer to data to be read
+ * @param ReadAddr: Read start address
+ * @param Size: Size of data to read
+ * @retval QSPI memory status
+ */
+uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
+{
+ QSPI_CommandTypeDef s_command;
+
+ /* Initialize the read command */
+ s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
+ s_command.Instruction = QUAD_INOUT_FAST_READ_DTR_CMD; /* DTR QUAD INPUT/OUTPUT FAST READ and 4-BYTE DTR FAST READ commands */
+ s_command.AddressMode = QSPI_ADDRESS_4_LINES;
+ s_command.AddressSize = QSPI_ADDRESS_32_BITS;
+ s_command.Address = ReadAddr;
+ s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+ s_command.DataMode = QSPI_DATA_4_LINES;
+ s_command.DummyCycles = MT25TL01G_DUMMY_CYCLES_READ_QUAD_DTR - 1;
+ s_command.NbData = Size;
+ s_command.DdrMode = QSPI_DDR_MODE_ENABLE;
+ s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_HALF_CLK_DELAY;
+ s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
+
+ /* Configure the command */
+ if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Reception of the data */
+ if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ return QSPI_OK;
+}
+
+/**
+ * @brief Writes an amount of data to the QSPI memory.
+ * @param pData: Pointer to data to be written
+ * @param WriteAddr: Write start address
+ * @param Size: Size of data to write
+ * @retval QSPI memory status
+ */
+uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
+{
+ QSPI_CommandTypeDef s_command;
+ uint32_t end_addr, current_size, current_addr;
+
+ /* Calculation of the size between the write address and the end of the page */
+ current_size = MT25TL01G_PAGE_SIZE - (WriteAddr % MT25TL01G_PAGE_SIZE);
+
+ /* Check if the size of the data is less than the remaining place in the page */
+ if (current_size > Size)
+ {
+ current_size = Size;
+ }
+
+ /* Initialize the address variables */
+ current_addr = WriteAddr;
+ end_addr = WriteAddr + Size;
+
+ /* Initialize the program command */
+ s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
+ s_command.Instruction = QUAD_IN_FAST_PROG_4_BYTE_ADDR_CMD;
+ s_command.AddressMode = QSPI_ADDRESS_4_LINES;
+ s_command.AddressSize = QSPI_ADDRESS_32_BITS;
+ s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+ s_command.DataMode = QSPI_DATA_4_LINES;
+ s_command.DummyCycles = 0;
+ s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
+ s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
+ s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
+
+ /* Perform the write page by page */
+ do
+ {
+ s_command.Address = current_addr;
+ s_command.NbData = current_size;
+
+ /* Enable write operations */
+ if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Configure the command */
+ if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Transmission of the data */
+ if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Configure automatic polling mode to wait for end of program */
+ if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Update the address and size variables for next page programming */
+ current_addr += current_size;
+ pData += current_size;
+ current_size = ((current_addr + MT25TL01G_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : MT25TL01G_PAGE_SIZE;
+ } while (current_addr < end_addr);
+
+ return QSPI_OK;
+}
+
+/**
+ * @brief Erases the specified block of the QSPI memory.
+ * @param BlockAddress: Block address to erase
+ * @retval QSPI memory status
+ */
+uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress)
+{
+ QSPI_CommandTypeDef s_command;
+
+ /* Initialize the erase command */
+ s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
+ s_command.Instruction = SUBSECTOR_ERASE_4_BYTE_ADDR_CMD;
+ s_command.AddressMode = QSPI_ADDRESS_4_LINES;
+ s_command.AddressSize = QSPI_ADDRESS_32_BITS;
+ s_command.Address = BlockAddress;
+ s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+ s_command.DataMode = QSPI_DATA_NONE;
+ s_command.DummyCycles = 0;
+ s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
+ s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
+ s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
+
+ /* Enable write operations */
+ if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Send the command */
+ if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Configure automatic polling mode to wait for end of erase */
+ if (QSPI_AutoPollingMemReady(&QSPIHandle, MT25TL01G_SUBSECTOR_ERASE_MAX_TIME) != QSPI_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ return QSPI_OK;
+}
+
+/**
+ * @brief Erases the entire QSPI memory.
+ * @retval QSPI memory status
+ */
+uint8_t BSP_QSPI_Erase_Chip(void)
+{
+ QSPI_CommandTypeDef s_command;
+
+ /* Initialize the erase command */
+ s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
+ s_command.Instruction = DIE_ERASE_CMD;
+ s_command.AddressMode = QSPI_ADDRESS_NONE;
+ s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+ s_command.DataMode = QSPI_DATA_NONE;
+ s_command.DummyCycles = 0;
+ s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
+ s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
+ s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
+
+ /* Enable write operations */
+ if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Send the command */
+ if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Configure automatic polling mode to wait for end of erase */
+ if (QSPI_AutoPollingMemReady(&QSPIHandle, MT25TL01G_DIE_ERASE_MAX_TIME) != QSPI_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ return QSPI_OK;
+}
+
+/**
+ * @brief Reads current status of the QSPI memory.
+ * @retval QSPI memory status
+ */
+uint8_t BSP_QSPI_GetStatus(void)
+{
+ QSPI_CommandTypeDef s_command;
+ uint16_t reg;
+
+ /* Initialize the read flag status register command */
+ s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
+ s_command.Instruction = READ_FLAG_STATUS_REG_CMD;
+ s_command.AddressMode = QSPI_ADDRESS_NONE;
+ s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+ s_command.DataMode = QSPI_DATA_4_LINES;
+ s_command.DummyCycles = 0;
+ s_command.NbData = 1;
+ s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
+ s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
+ s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
+
+ /* Configure the command */
+ if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Reception of the data */
+ if (HAL_QSPI_Receive(&QSPIHandle, (uint8_t*)(®), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Check the value of the register */
+ if ((reg & (MT25TL01G_FSR_PRERR | MT25TL01G_FSR_PGERR | MT25TL01G_FSR_ERERR)) != 0)
+ {
+ return QSPI_ERROR;
+ }
+ else if ((reg & (MT25TL01G_FSR_PGSUS | MT25TL01G_FSR_ERSUS)) != 0)
+ {
+ return QSPI_SUSPENDED;
+ }
+ else if ((reg & MT25TL01G_FSR_READY) != 0)
+ {
+ return QSPI_OK;
+ }
+ else
+ {
+ return QSPI_BUSY;
+ }
+}
+
+/**
+ * @brief Return the configuration of the QSPI memory.
+ * @param pInfo: pointer on the configuration structure
+ * @retval QSPI memory status
+ */
+uint8_t BSP_QSPI_GetInfo(QSPI_Info* pInfo)
+{
+ /* Configure the structure with the memory configuration */
+ pInfo->FlashSize = MT25TL01G_FLASH_SIZE;
+ pInfo->EraseSectorSize = (2 * MT25TL01G_SUBSECTOR_SIZE);
+ pInfo->ProgPageSize = MT25TL01G_PAGE_SIZE;
+ pInfo->EraseSectorsNumber = (MT25TL01G_FLASH_SIZE/pInfo->EraseSectorSize);
+ pInfo->ProgPagesNumber = (MT25TL01G_FLASH_SIZE/pInfo->ProgPageSize);
+
+ return QSPI_OK;
+}
+
+/**
+ * @brief Configure the QSPI in memory-mapped mode
+ * @retval QSPI memory status
+ */
+uint8_t BSP_QSPI_EnableMemoryMappedMode(void)
+{
+ QSPI_CommandTypeDef s_command;
+ QSPI_MemoryMappedTypeDef s_mem_mapped_cfg;
+
+ /* Configure the command for the read instruction */
+ s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
+ s_command.Instruction = QUAD_INOUT_FAST_READ_DTR_CMD; /* DTR QUAD INPUT/OUTPUT FAST READ and 4-BYTE DTR FAST READ commands */
+ s_command.AddressMode = QSPI_ADDRESS_4_LINES;
+ s_command.AddressSize = QSPI_ADDRESS_32_BITS;
+ s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+ s_command.DataMode = QSPI_DATA_4_LINES;
+ s_command.DummyCycles = MT25TL01G_DUMMY_CYCLES_READ_QUAD_DTR - 1;
+
+ s_command.DdrMode = QSPI_DDR_MODE_ENABLE;
+ s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_HALF_CLK_DELAY;
+ s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
+
+ /* Configure the memory mapped mode */
+ s_mem_mapped_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;
+ s_mem_mapped_cfg.TimeOutPeriod = 0;
+
+ if (HAL_QSPI_MemoryMapped(&QSPIHandle, &s_command, &s_mem_mapped_cfg) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ return QSPI_OK;
+}
+
+/**
+ * @brief QSPI MSP Initialization
+ * This function configures the hardware resources used in this example:
+ * - Peripheral's clock enable
+ * - Peripheral's GPIO Configuration
+ * - NVIC configuration for QSPI interrupt
+ * @retval None
+ */
+__weak void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params)
+{
+ GPIO_InitTypeDef gpio_init_structure;
+
+ /*##-1- Enable peripherals and GPIO Clocks #################################*/
+ /* Enable the QuadSPI memory interface clock */
+ QSPI_CLK_ENABLE();
+ /* Reset the QuadSPI memory interface */
+ QSPI_FORCE_RESET();
+ QSPI_RELEASE_RESET();
+ /* Enable GPIO clocks */
+ QSPI_CLK_GPIO_CLK_ENABLE();
+ QSPI_BK1_CS_GPIO_CLK_ENABLE();
+ QSPI_BK1_D0_GPIO_CLK_ENABLE();
+ QSPI_BK1_D1_GPIO_CLK_ENABLE();
+ QSPI_BK1_D2_GPIO_CLK_ENABLE();
+ QSPI_BK1_D3_GPIO_CLK_ENABLE();
+
+ QSPI_BK2_CS_GPIO_CLK_ENABLE();
+ QSPI_BK2_D0_GPIO_CLK_ENABLE();
+ QSPI_BK2_D1_GPIO_CLK_ENABLE();
+ QSPI_BK2_D2_GPIO_CLK_ENABLE();
+ QSPI_BK2_D3_GPIO_CLK_ENABLE();
+
+ /*##-2- Configure peripheral GPIO ##########################################*/
+ /* QSPI CLK GPIO pin configuration */
+ gpio_init_structure.Pin = QSPI_CLK_PIN;
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
+ HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure);
+
+ /* QSPI CS GPIO pin configuration */
+ gpio_init_structure.Pin = QSPI_BK1_CS_PIN;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Alternate = GPIO_AF10_QUADSPI;
+ HAL_GPIO_Init(QSPI_BK1_CS_GPIO_PORT, &gpio_init_structure);
+
+ /* QSPI D0 GPIO pin configuration */
+ gpio_init_structure.Pin = QSPI_BK1_D0_PIN;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
+ HAL_GPIO_Init(QSPI_BK1_D0_GPIO_PORT, &gpio_init_structure);
+
+ gpio_init_structure.Pin = QSPI_BK2_D0_PIN;
+ gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
+ HAL_GPIO_Init(QSPI_BK2_D0_GPIO_PORT, &gpio_init_structure);
+
+ /* QSPI D1 GPIO pin configuration */
+ gpio_init_structure.Pin = QSPI_BK1_D1_PIN;
+ gpio_init_structure.Alternate = GPIO_AF10_QUADSPI;
+ HAL_GPIO_Init(QSPI_BK1_D1_GPIO_PORT, &gpio_init_structure);
+
+ gpio_init_structure.Pin = QSPI_BK2_D1_PIN;
+ gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
+ HAL_GPIO_Init(QSPI_BK2_D1_GPIO_PORT, &gpio_init_structure);
+
+ /* QSPI D2 GPIO pin configuration */
+ gpio_init_structure.Pin = QSPI_BK1_D2_PIN;
+ gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
+ HAL_GPIO_Init(QSPI_BK1_D2_GPIO_PORT, &gpio_init_structure);
+
+ gpio_init_structure.Pin = QSPI_BK2_D2_PIN;
+ HAL_GPIO_Init(QSPI_BK2_D2_GPIO_PORT, &gpio_init_structure);
+
+ /* QSPI D3 GPIO pin configuration */
+ gpio_init_structure.Pin = QSPI_BK1_D3_PIN;
+ HAL_GPIO_Init(QSPI_BK1_D3_GPIO_PORT, &gpio_init_structure);
+
+ gpio_init_structure.Pin = QSPI_BK2_D3_PIN;
+ HAL_GPIO_Init(QSPI_BK2_D3_GPIO_PORT, &gpio_init_structure);
+
+ /*##-3- Configure the NVIC for QSPI #########################################*/
+ /* NVIC configuration for QSPI interrupt */
+ HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0);
+ HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
+
+}
+
+/**
+ * @brief QSPI MSP De-Initialization
+ * This function frees the hardware resources used in this example:
+ * - Disable the Peripheral's clock
+ * - Revert GPIO and NVIC configuration to their default state
+ * @retval None
+ */
+__weak void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params)
+{
+ /*##-1- Disable the NVIC for QSPI ###########################################*/
+ HAL_NVIC_DisableIRQ(QUADSPI_IRQn);
+
+ /*##-2- Disable peripherals and GPIO Clocks ################################*/
+ /* De-Configure QSPI pins */
+ HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN);
+ HAL_GPIO_DeInit(QSPI_BK1_CS_GPIO_PORT, QSPI_BK1_CS_PIN);
+ HAL_GPIO_DeInit(QSPI_BK1_D0_GPIO_PORT, QSPI_BK1_D0_PIN);
+ HAL_GPIO_DeInit(QSPI_BK1_D1_GPIO_PORT, QSPI_BK1_D1_PIN);
+ HAL_GPIO_DeInit(QSPI_BK1_D2_GPIO_PORT, QSPI_BK1_D2_PIN);
+ HAL_GPIO_DeInit(QSPI_BK1_D3_GPIO_PORT, QSPI_BK1_D3_PIN);
+
+ HAL_GPIO_DeInit(QSPI_BK2_CS_GPIO_PORT, QSPI_BK2_CS_PIN);
+ HAL_GPIO_DeInit(QSPI_BK2_D0_GPIO_PORT, QSPI_BK2_D0_PIN);
+ HAL_GPIO_DeInit(QSPI_BK2_D1_GPIO_PORT, QSPI_BK2_D1_PIN);
+ HAL_GPIO_DeInit(QSPI_BK2_D2_GPIO_PORT, QSPI_BK2_D2_PIN);
+ HAL_GPIO_DeInit(QSPI_BK2_D3_GPIO_PORT, QSPI_BK2_D3_PIN);
+
+ /*##-3- Reset peripherals ##################################################*/
+ /* Reset the QuadSPI memory interface */
+ QSPI_FORCE_RESET();
+ QSPI_RELEASE_RESET();
+
+ /* Disable the QuadSPI memory interface clock */
+ QSPI_CLK_DISABLE();
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_QSPI_Private_Functions Private Functions
+ * @{
+ */
+
+/**
+ * @brief This function reset the QSPI memory.
+ * @param hqspi: QSPI handle
+ * @retval None
+ */
+static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi)
+{
+ QSPI_CommandTypeDef s_command;
+
+ /* Initialize the reset enable command */
+ s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
+ s_command.Instruction = RESET_ENABLE_CMD;
+ s_command.AddressMode = QSPI_ADDRESS_NONE;
+ s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+ s_command.DataMode = QSPI_DATA_NONE;
+ s_command.DummyCycles = 0;
+ s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
+ s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
+ s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
+
+ /* Send the command */
+ if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Send the reset memory command */
+ s_command.Instruction = RESET_MEMORY_CMD;
+ if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
+ s_command.Instruction = RESET_ENABLE_CMD;
+ /* Send the command */
+ if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Send the reset memory command */
+ s_command.Instruction = RESET_MEMORY_CMD;
+ if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Enter QSPI memory in QPI mode */
+ if(QSPI_EnterQPI(&QSPIHandle) != QSPI_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Configure automatic polling mode to wait the memory is ready */
+ if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ return QSPI_OK;
+}
+
+/**
+ * @brief This function set the QSPI memory in 4-byte address mode
+ * @param hqspi: QSPI handle
+ * @retval None
+ */
+static uint8_t QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi)
+{
+ QSPI_CommandTypeDef s_command;
+
+ /* Initialize the command */
+ s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
+ s_command.Instruction = ENTER_4_BYTE_ADDR_MODE_CMD;
+ s_command.AddressMode = QSPI_ADDRESS_NONE;
+ s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+ s_command.DataMode = QSPI_DATA_NONE;
+ s_command.DummyCycles = 0;
+ s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
+ s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
+ s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
+
+ /* Enable write operations */
+ if (QSPI_WriteEnable(hqspi) != QSPI_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Send the command */
+ if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Configure automatic polling mode to wait the memory is ready */
+ if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ return QSPI_OK;
+}
+
+/**
+ * @brief This function configure the dummy cycles on memory side.
+ * @param hqspi: QSPI handle
+ * @retval None
+ */
+static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
+{
+ QSPI_CommandTypeDef s_command;
+ uint16_t reg = 0;
+
+ /* Initialize the read volatile configuration register command */
+ s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
+ s_command.Instruction = READ_VOL_CFG_REG_CMD;
+ s_command.AddressMode = QSPI_ADDRESS_NONE;
+ s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+ s_command.DataMode = QSPI_DATA_4_LINES;
+ s_command.DummyCycles = 0;
+ s_command.NbData = 2;
+ s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
+ s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
+ s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
+
+ /* Configure the command */
+ if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Reception of the data */
+ if (HAL_QSPI_Receive(hqspi, (uint8_t *)(®), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Enable write operations */
+ if (QSPI_WriteEnable(hqspi) != QSPI_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Update volatile configuration register (with new dummy cycles) */
+ s_command.Instruction = WRITE_VOL_CFG_REG_CMD;
+ MODIFY_REG(reg, 0xF0F0, ((MT25TL01G_DUMMY_CYCLES_READ_QUAD << 4) |
+ (MT25TL01G_DUMMY_CYCLES_READ_QUAD << 12)));
+
+ /* Configure the write volatile configuration register command */
+ if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Transmission of the data */
+ if (HAL_QSPI_Transmit(hqspi, (uint8_t *)(®), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ return QSPI_OK;
+}
+
+/**
+ * @brief This function send a Write Enable and wait it is effective.
+ * @param hqspi: QSPI handle
+ * @retval None
+ */
+static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
+{
+ QSPI_CommandTypeDef s_command;
+ QSPI_AutoPollingTypeDef s_config;
+
+ /* Enable write operations */
+ s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
+ s_command.Instruction = WRITE_ENABLE_CMD;
+ s_command.AddressMode = QSPI_ADDRESS_NONE;
+ s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+ s_command.DataMode = QSPI_DATA_NONE;
+ s_command.DummyCycles = 0;
+ s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
+ s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
+ s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
+
+ if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ /* Configure automatic polling mode to wait for write enabling */
+ s_config.Match = MT25TL01G_SR_WREN | (MT25TL01G_SR_WREN << 8);
+ s_config.Mask = MT25TL01G_SR_WREN | (MT25TL01G_SR_WREN << 8);
+ s_config.MatchMode = QSPI_MATCH_MODE_AND;
+ s_config.StatusBytesSize = 2;
+ s_config.Interval = 0x10;
+ s_config.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
+
+ s_command.Instruction = READ_STATUS_REG_CMD;
+ s_command.DataMode = QSPI_DATA_4_LINES;
+
+ if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ return QSPI_OK;
+}
+
+/**
+ * @brief This function read the SR of the memory and wait the EOP.
+ * @param hqspi: QSPI handle
+ * @param Timeout: timeout in ms
+ * @retval None
+ */
+static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
+{
+ QSPI_CommandTypeDef s_command;
+ QSPI_AutoPollingTypeDef s_config;
+
+ /* Configure automatic polling mode to wait for memory ready */
+ s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
+ s_command.Instruction = READ_STATUS_REG_CMD;
+ s_command.AddressMode = QSPI_ADDRESS_NONE;
+ s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+ s_command.DataMode = QSPI_DATA_4_LINES;
+ s_command.DummyCycles = 2;
+ s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
+ s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
+ s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
+
+ s_config.Match = 0;
+ s_config.MatchMode = QSPI_MATCH_MODE_AND;
+ s_config.Interval = 0x10;
+ s_config.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
+ s_config.Mask = MT25TL01G_SR_WIP | (MT25TL01G_SR_WIP <<8);
+ s_config.StatusBytesSize = 2;
+
+ if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, Timeout) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ return QSPI_OK;
+}
+
+/**
+ * @brief This function enter the QPSI memory in QPI mode
+ * @param hqspi QSPI handle
+ * @retval QSPI status
+ */
+static uint8_t QSPI_EnterQPI(QSPI_HandleTypeDef *hqspi)
+{
+ QSPI_CommandTypeDef s_command;
+
+ s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
+ s_command.Instruction = ENTER_QUAD_CMD;
+ s_command.AddressMode = QSPI_ADDRESS_NONE;
+ s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
+ s_command.DataMode = QSPI_DATA_NONE;
+ s_command.DummyCycles = 0;
+ s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
+ s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
+ s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
+
+ if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
+ {
+ return QSPI_ERROR;
+ }
+
+ return QSPI_OK;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery_qspi.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,174 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery_qspi.h
+ * @author MCD Application Team
+ * @brief This file contains the common defines and functions prototypes for
+ * the stm32h747i_discovery_qspi.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY
+ * @{
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32H747I_DISCOVERY_QSPI_H
+#define __STM32H747I_DISCOVERY_QSPI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+#include "../Components/mt25tl01g/mt25tl01g.h"
+
+/** @addtogroup STM32H747I_DISCOVERY_QSPI
+ * @{
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup STM32H747I_DISCOVERY_QSPI_Exported_Constants Exported Constants
+ * @{
+ */
+/* QSPI Error codes */
+#define QSPI_OK ((uint8_t)0x00)
+#define QSPI_ERROR ((uint8_t)0x01)
+#define QSPI_BUSY ((uint8_t)0x02)
+#define QSPI_NOT_SUPPORTED ((uint8_t)0x04)
+#define QSPI_SUSPENDED ((uint8_t)0x08)
+#define QSPI_PROTECTED ((uint8_t)0x10)
+
+/* Definition for QSPI clock resources */
+#define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE()
+#define QSPI_CLK_DISABLE() __HAL_RCC_QSPI_CLK_DISABLE()
+#define QSPI_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define QSPI_BK1_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
+#define QSPI_BK1_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
+#define QSPI_BK1_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
+#define QSPI_BK1_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
+#define QSPI_BK1_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
+#define QSPI_BK2_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
+#define QSPI_BK2_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+#define QSPI_BK2_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
+#define QSPI_BK2_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
+#define QSPI_BK2_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
+
+
+#define QSPI_FORCE_RESET() __HAL_RCC_QSPI_FORCE_RESET()
+#define QSPI_RELEASE_RESET() __HAL_RCC_QSPI_RELEASE_RESET()
+
+/* Definition for QSPI Pins */
+#define QSPI_CLK_PIN GPIO_PIN_2
+#define QSPI_CLK_GPIO_PORT GPIOB
+/* Bank 1 */
+#define QSPI_BK1_CS_PIN GPIO_PIN_6
+#define QSPI_BK1_CS_GPIO_PORT GPIOG
+#define QSPI_BK1_D0_PIN GPIO_PIN_11
+#define QSPI_BK1_D0_GPIO_PORT GPIOD
+#define QSPI_BK1_D1_PIN GPIO_PIN_9
+#define QSPI_BK1_D1_GPIO_PORT GPIOF
+#define QSPI_BK1_D2_PIN GPIO_PIN_7
+#define QSPI_BK1_D2_GPIO_PORT GPIOF
+#define QSPI_BK1_D3_PIN GPIO_PIN_6
+#define QSPI_BK1_D3_GPIO_PORT GPIOF
+
+/* Bank 2 */
+#define QSPI_BK2_CS_PIN GPIO_PIN_6
+#define QSPI_BK2_CS_GPIO_PORT GPIOG
+#define QSPI_BK2_D0_PIN GPIO_PIN_2
+#define QSPI_BK2_D0_GPIO_PORT GPIOH
+#define QSPI_BK2_D1_PIN GPIO_PIN_3
+#define QSPI_BK2_D1_GPIO_PORT GPIOH
+#define QSPI_BK2_D2_PIN GPIO_PIN_9
+#define QSPI_BK2_D2_GPIO_PORT GPIOG
+#define QSPI_BK2_D3_PIN GPIO_PIN_14
+#define QSPI_BK2_D3_GPIO_PORT GPIOG
+
+
+/* MT25TL01G Micron memory */
+/* Size of the flash */
+#define QSPI_FLASH_SIZE 26 /* Address bus width to access whole memory space */
+#define QSPI_PAGE_SIZE 256
+
+/* QSPI Base Address */
+#define QSPI_BASE_ADDRESS 0x90000000
+
+/**
+ * @}
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup STM32H747I_DISCOVERY_QSPI_Exported_Types Exported Types
+ * @{
+ */
+/* QSPI Info */
+typedef struct {
+ uint32_t FlashSize; /*!< Size of the flash */
+ uint32_t EraseSectorSize; /*!< Size of sectors for the erase operation */
+ uint32_t EraseSectorsNumber; /*!< Number of sectors for the erase operation */
+ uint32_t ProgPageSize; /*!< Size of pages for the program operation */
+ uint32_t ProgPagesNumber; /*!< Number of pages for the program operation */
+} QSPI_Info;
+
+/**
+ * @}
+ */
+
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup STM32H747I_DISCOVERY_QSPI_Exported_Functions
+ * @{
+ */
+uint8_t BSP_QSPI_Init (void);
+uint8_t BSP_QSPI_DeInit (void);
+uint8_t BSP_QSPI_Read (uint8_t* pData, uint32_t ReadAddr, uint32_t Size);
+uint8_t BSP_QSPI_Write (uint8_t* pData, uint32_t WriteAddr, uint32_t Size);
+uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress);
+uint8_t BSP_QSPI_Erase_Chip (void);
+uint8_t BSP_QSPI_GetStatus (void);
+uint8_t BSP_QSPI_GetInfo (QSPI_Info* pInfo);
+uint8_t BSP_QSPI_EnableMemoryMappedMode(void);
+
+/* These functions can be modified in case the current settings
+ need to be changed for specific application needs */
+void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params);
+void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32H747I_DISCOVERY_QSPI_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery_sd.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,494 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery_sd.c
+ * @author MCD Application Team
+ * @brief This file includes the uSD card driver mounted on STM32H747I-DISCOVERY
+ * board.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* File Info : -----------------------------------------------------------------
+ User NOTES
+1. How To use this driver:
+--------------------------
+ - This driver is used to drive the micro SD external card mounted on STM32412G-DISCOVERY
+ board.
+ - This driver does not need a specific component driver for the micro SD device
+ to be included with.
+
+2. Driver description:
+---------------------
+ + Initialization steps:
+ o Initialize the micro SD card using the BSP_SD_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ SDIO interface configuration to interface with the external micro SD. It
+ also includes the micro SD initialization sequence.
+ o To check the SD card presence you can use the function BSP_SD_IsDetected() which
+ returns the detection status
+ o If SD presence detection interrupt mode is desired, you must configure the
+ SD detection interrupt mode by calling the function BSP_SD_ITConfig(). The interrupt
+ is generated as an external interrupt whenever the micro SD card is
+ plugged/unplugged in/from the board.
+ o The function BSP_SD_GetCardInfo() is used to get the micro SD card information
+ which is stored in the structure "HAL_SD_CardInfoTypedef".
+
+ + Micro SD card operations
+ o The micro SD card can be accessed with read/write block(s) operations once
+ it is ready for access. The access can be performed whether using the polling
+ mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks(), or by DMA
+ transfer using the functions BSP_SD_ReadBlocks_DMA()/BSP_SD_WriteBlocks_DMA()
+ o The DMA transfer complete is used with interrupt mode. Once the SD transfer
+ is complete, the SD interrupt is handled using the function BSP_SD_IRQHandler(),
+ the DMA Tx/Rx transfer complete are handled using the functions
+ SD_DMA_Tx_IRQHandler()/SD_DMA_Rx_IRQHandler() that should be defined by user.
+ The corresponding user callbacks are implemented by the user at application level.
+ o The SD erase block(s) is performed using the function BSP_SD_Erase() with specifying
+ the number of blocks to erase.
+ o The SD runtime status is returned when calling the function BSP_SD_GetStatus().
+
+------------------------------------------------------------------------------*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h747i_discovery_sd.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_SD STM32H747I_DISCOVERY_SD
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_SD_Exported_Variables Exported Variables
+ * @{
+ */
+SD_HandleTypeDef uSdHandle;
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_SD_Exported_Functions Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes the SD card device.
+ * @retval SD status
+ */
+uint8_t BSP_SD_Init(void)
+{
+ uint8_t sd_state = MSD_OK;
+
+ /* uSD device interface configuration */
+ uSdHandle.Instance = SDMMC1;
+
+ /* if CLKDIV = 0 then SDMMC Clock frequency = SDMMC Kernel Clock
+ else SDMMC Clock frequency = SDMMC Kernel Clock / [2 * CLKDIV].
+ */
+#if ! defined (BSP_SD_HIGH_PERFORMANCE_CONFIG)
+ uSdHandle.Init.ClockDiv = 4;
+#else
+ /* Code for high performance */
+ uSdHandle.Init.ClockDiv = 2;
+#endif /* BSP_SD_HIGH_PERFORMANCE_CONFIG */
+ uSdHandle.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
+ uSdHandle.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
+ uSdHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
+ uSdHandle.Init.BusWide = SDMMC_BUS_WIDE_4B;
+
+ /* Msp SD initialization */
+ BSP_SD_MspInit(&uSdHandle, NULL);
+
+ /* Check if SD card is present */
+ if(BSP_SD_IsDetected() != SD_PRESENT)
+ {
+ BSP_SD_MspDeInit(&uSdHandle, NULL);
+ return MSD_ERROR_SD_NOT_PRESENT;
+ }
+
+ /* HAL SD initialization */
+ if(HAL_SD_Init(&uSdHandle) != HAL_OK)
+ {
+ sd_state = MSD_ERROR;
+ }
+
+ return sd_state;
+}
+
+/**
+ * @brief DeInitializes the SD card device.
+ * @retval SD status
+ */
+uint8_t BSP_SD_DeInit(void)
+{
+ uint8_t sd_state = MSD_OK;
+
+ uSdHandle.Instance = SDMMC1;
+
+ /* HAL SD deinitialization */
+ if(HAL_SD_DeInit(&uSdHandle) != HAL_OK)
+ {
+ sd_state = MSD_ERROR;
+ }
+
+ /* Msp SD deinitialization */
+ uSdHandle.Instance = SDMMC1;
+ BSP_SD_MspDeInit(&uSdHandle, NULL);
+
+ return sd_state;
+}
+
+/**
+ * @brief Configures Interrupt mode for SD1 detection pin.
+ * @retval Returns 0
+ */
+uint8_t BSP_SD_ITConfig(void)
+{
+ GPIO_InitTypeDef gpio_init_structure;
+
+ /* Configure Interrupt mode for SD detection pin */
+ gpio_init_structure.Pin = SD_DETECT_PIN;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
+ gpio_init_structure.Mode = GPIO_MODE_IT_RISING_FALLING;
+ HAL_GPIO_Init(SD_DETECT_GPIO_PORT, &gpio_init_structure);
+
+ /* Enable and set SD detect EXTI Interrupt to the lowest priority */
+ HAL_NVIC_SetPriority((IRQn_Type)(SD_DETECT_EXTI_IRQn), 0x0F, 0x00);
+ HAL_NVIC_EnableIRQ((IRQn_Type)(SD_DETECT_EXTI_IRQn));
+
+ return MSD_OK;
+}
+
+/**
+ * @brief Detects if SD card is correctly plugged in the memory slot or not.
+ * @retval Returns if SD is detected or not
+ */
+uint8_t BSP_SD_IsDetected(void)
+{
+ __IO uint8_t status = SD_PRESENT;
+
+
+ /* Check SD card detect pin */
+ if (HAL_GPIO_ReadPin(SD_DETECT_GPIO_PORT, SD_DETECT_PIN) == GPIO_PIN_SET)
+ {
+ status = SD_NOT_PRESENT;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Reads block(s) from a specified address in an SD card, in polling mode.
+ * @param pData: Pointer to the buffer that will contain the data to transmit
+ * @param ReadAddr: Address from where data is to be read
+ * @param NumOfBlocks: Number of SD blocks to read
+ * @param Timeout: Timeout for read operation
+ * @retval SD status
+ */
+uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout)
+{
+
+ if( HAL_SD_ReadBlocks(&uSdHandle, (uint8_t *)pData, ReadAddr, NumOfBlocks, Timeout) == HAL_OK)
+ {
+ return MSD_OK;
+ }
+ else
+ {
+ return MSD_ERROR;
+ }
+
+}
+
+/**
+ * @brief Writes block(s) to a specified address in an SD card, in polling mode.
+ * @param pData: Pointer to the buffer that will contain the data to transmit
+ * @param WriteAddr: Address from where data is to be written
+ * @param NumOfBlocks: Number of SD blocks to write
+ * @param Timeout: Timeout for write operation
+ * @retval SD status
+ */
+uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout)
+{
+
+ if( HAL_SD_WriteBlocks(&uSdHandle, (uint8_t *)pData, WriteAddr, NumOfBlocks, Timeout) == HAL_OK)
+ {
+ return MSD_OK;
+ }
+ else
+ {
+ return MSD_ERROR;
+ }
+}
+
+/**
+ * @brief Reads block(s) from a specified address in an SD card, in DMA mode.
+ * @param pData: Pointer to the buffer that will contain the data to transmit
+ * @param ReadAddr: Address from where data is to be read
+ * @param NumOfBlocks: Number of SD blocks to read
+ * @retval SD status
+ */
+uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks)
+{
+
+ if( HAL_SD_ReadBlocks_DMA(&uSdHandle, (uint8_t *)pData, ReadAddr, NumOfBlocks) == HAL_OK)
+ {
+ return MSD_OK;
+ }
+ else
+ {
+ return MSD_ERROR;
+ }
+}
+
+/**
+ * @brief Writes block(s) to a specified address in an SD card, in DMA mode.
+ * @param pData: Pointer to the buffer that will contain the data to transmit
+ * @param WriteAddr: Address from where data is to be written
+ * @param NumOfBlocks: Number of SD blocks to write
+ * @retval SD status
+ */
+uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)
+{
+
+ if( HAL_SD_WriteBlocks_DMA(&uSdHandle, (uint8_t *)pData, WriteAddr, NumOfBlocks) == HAL_OK)
+ {
+ return MSD_OK;
+ }
+ else
+ {
+ return MSD_ERROR;
+ }
+
+}
+
+/**
+ * @brief Erases the specified memory area of the given SD card.
+ * @param StartAddr: Start byte address
+ * @param EndAddr: End byte address
+ * @retval SD status
+ */
+uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr)
+{
+
+ if( HAL_SD_Erase(&uSdHandle, StartAddr, EndAddr) == HAL_OK)
+ {
+ return MSD_OK;
+ }
+ else
+ {
+ return MSD_ERROR;
+ }
+}
+
+/**
+ * @brief Initializes the SD MSP.
+ * @param hsd SD handle
+ * @param Params User parameters
+ * @retval None
+ */
+__weak void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params)
+{
+ /* __weak function can be modified by the application */
+
+ GPIO_InitTypeDef gpio_init_structure;
+
+ /* SD pins are in conflict with Camera pins on the Disco board
+ therefore Camera must be power down before using the BSP SD
+ To power down the camera , Set GPIOJ pin 14 to high
+ */
+
+ /* Enable GPIO J clock */
+ __HAL_RCC_GPIOJ_CLK_ENABLE();
+
+ gpio_init_structure.Pin = GPIO_PIN_14;
+ gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ HAL_GPIO_Init(GPIOJ, &gpio_init_structure);
+
+ /* Set the camera POWER_DOWN pin (active high) */
+ HAL_GPIO_WritePin(GPIOJ, GPIO_PIN_14, GPIO_PIN_SET);
+
+ /* Enable SDIO clock */
+ __HAL_RCC_SDMMC1_CLK_ENABLE();
+
+
+ /* Enable GPIOs clock */
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOD_CLK_ENABLE();
+
+
+ /* Common GPIO configuration */
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ gpio_init_structure.Alternate = GPIO_AF12_SDIO1;
+
+ /* SDMMC GPIO CLKIN PB8, D0 PC8, D1 PC9, D2 PC10, D3 PC11, CK PC12, CMD PD2 */
+ /* GPIOC configuration */
+ gpio_init_structure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
+
+ HAL_GPIO_Init(GPIOC, &gpio_init_structure);
+
+ /* GPIOD configuration */
+ gpio_init_structure.Pin = GPIO_PIN_2;
+ HAL_GPIO_Init(GPIOD, &gpio_init_structure);
+
+ /* Configure Input mode for SD detection pin */
+ SD_DETECT_GPIO_CLK_ENABLE();
+ gpio_init_structure.Pin = SD_DETECT_PIN;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
+ gpio_init_structure.Mode = GPIO_MODE_INPUT;
+ HAL_GPIO_Init(SD_DETECT_GPIO_PORT, &gpio_init_structure);
+
+ /* NVIC configuration for SDIO interrupts */
+ HAL_NVIC_SetPriority(SDMMC1_IRQn, 5, 0);
+ HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
+
+}
+
+/**
+ * @brief DeInitializes the SD MSP.
+ * @param hsd SD handle
+ * @param Params User parameters
+ * @retval None
+ */
+__weak void BSP_SD_MspDeInit(SD_HandleTypeDef *hsd, void *Params)
+{
+ /* Disable NVIC for SDIO interrupts */
+ HAL_NVIC_DisableIRQ(SDMMC1_IRQn);
+
+ /* DeInit GPIO pins can be done in the application
+ (by surcharging this __weak function) */
+
+ /* Disable SDMMC1 clock */
+ __HAL_RCC_SDMMC1_CLK_DISABLE();
+
+ /* GPIO pins clock and DMA clocks can be shut down in the application
+ by surcharging this __weak function */
+}
+
+/**
+ * @brief Handles SD card interrupt request.
+ * @retval None
+ */
+void BSP_SD_IRQHandler(void)
+{
+ HAL_SD_IRQHandler(&uSdHandle);
+}
+
+/**
+ * @brief Gets the current SD card data status.
+ * @retval Data transfer state.
+ * This value can be one of the following values:
+ * @arg SD_TRANSFER_OK: No data transfer is acting
+ * @arg SD_TRANSFER_BUSY: Data transfer is acting
+ * @arg SD_TRANSFER_ERROR: Data transfer error
+ */
+uint8_t BSP_SD_GetCardState(void)
+{
+ return((HAL_SD_GetCardState(&uSdHandle) == HAL_SD_CARD_TRANSFER ) ? SD_TRANSFER_OK : SD_TRANSFER_BUSY);
+}
+
+/**
+ * @brief Get SD information about specific SD card.
+ * @param CardInfo: Pointer to HAL_SD_CardInfoTypedef structure
+ * @retval None
+ */
+void BSP_SD_GetCardInfo(BSP_SD_CardInfo *CardInfo)
+{
+ HAL_SD_GetCardInfo(&uSdHandle, CardInfo);
+}
+
+/**
+ * @brief SD Abort callbacks
+ * @param hsd SD handle
+ * @retval None
+ */
+void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd)
+{
+ BSP_SD_AbortCallback();
+}
+
+
+/**
+ * @brief Tx Transfer completed callbacks
+ * @param hsd SD handle
+ * @retval None
+ */
+void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
+{
+ BSP_SD_WriteCpltCallback();
+}
+
+/**
+ * @brief Rx Transfer completed callbacks
+ * @param hsd SD handle
+ * @retval None
+ */
+void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
+{
+ BSP_SD_ReadCpltCallback();
+}
+
+/**
+ * @brief BSP SD Abort callbacks
+ * @retval None
+ */
+__weak void BSP_SD_AbortCallback(void)
+{
+
+}
+
+/**
+ * @brief BSP Tx Transfer completed callbacks
+ * @retval None
+ */
+__weak void BSP_SD_WriteCpltCallback(void)
+{
+
+}
+
+/**
+ * @brief BSP Rx Transfer completed callbacks
+ * @retval None
+ */
+__weak void BSP_SD_ReadCpltCallback(void)
+{
+
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery_sd.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,132 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery_sd.h
+ * @author MCD Application Team
+ * @brief This file contains the common defines and functions prototypes for
+ * the stm32h747i_discovery_sd.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32H747I_DISCOVERY_SD_H
+#define __STM32H747I_DISCOVERY_SD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+#include "stm32h747i_discovery.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY_SD
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_SD_Exported_Types Exported Types
+ * @{
+ */
+
+/**
+ * @brief SD Card information structure
+ */
+#define BSP_SD_CardInfo HAL_SD_CardInfoTypeDef
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_SD_ Exported_Constants Exported Constants
+ * @{
+ */
+/**
+ * @brief SD status structure definition
+ */
+#define MSD_OK ((uint8_t)0x00)
+#define MSD_ERROR ((uint8_t)0x01)
+#define MSD_ERROR_SD_NOT_PRESENT ((uint8_t)0x02)
+
+/**
+ * @brief SD transfer state definition
+ */
+#define SD_TRANSFER_OK ((uint8_t)0x00)
+#define SD_TRANSFER_BUSY ((uint8_t)0x01)
+
+
+#define SD_PRESENT ((uint8_t)0x01)
+#define SD_NOT_PRESENT ((uint8_t)0x00)
+
+#define SD_DATATIMEOUT ((uint32_t)100000000)
+
+/**
+ * @}
+ */
+
+
+/** @addtogroup STM32H747I_DISCOVERY_SD_Exported_Functions
+ * @{
+ */
+uint8_t BSP_SD_Init(void);
+uint8_t BSP_SD_DeInit(void);
+uint8_t BSP_SD_ITConfig(void);
+
+uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout);
+uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout);
+uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks);
+uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks);
+uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr);
+uint8_t BSP_SD_GetCardState(void);
+void BSP_SD_GetCardInfo(BSP_SD_CardInfo *CardInfo);
+uint8_t BSP_SD_IsDetected(void);
+void BSP_SD_IRQHandler(void);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params);
+void BSP_SD_MspDeInit(SD_HandleTypeDef *hsd, void *Params);
+void BSP_SD_AbortCallback(void);
+void BSP_SD_WriteCpltCallback(void);
+void BSP_SD_ReadCpltCallback(void);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32H747I_DISCOVERY_SD_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery_sdram.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,456 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery_sdram.c
+ * @author MCD Application Team
+ * @brief This file includes the SDRAM driver for the MT48LC4M32B2B5-6A memory
+ * device mounted on STM32H747I-DISCOVERY boards.
+ @verbatim
+ How To use this driver:
+ -----------------------
+ - This driver is used to drive the MT48LC4M32B2B5-6A SDRAM external memory mounted
+ on STM32H747I-DISCOVERY board.
+ - This driver does not need a specific component driver for the SDRAM device
+ to be included with.
+
+ Driver description:
+ ------------------
+ + Initialization steps:
+ o Initialize the SDRAM external memory using the BSP_SDRAM_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ FMC controller configuration to interface with the external SDRAM memory.
+ o It contains the SDRAM initialization sequence to program the SDRAM external
+ device using the function BSP_SDRAM_Initialization_sequence(). Note that this
+ sequence is standard for all SDRAM devices, but can include some differences
+ from a device to another. If it is the case, the right sequence should be
+ implemented separately.
+
+ + SDRAM read/write operations
+ o SDRAM external memory can be accessed with read/write operations once it is
+ initialized.
+ Read/write operation can be performed with AHB access using the functions
+ BSP_SDRAM_ReadData()/BSP_SDRAM_WriteData(), or by MDMA transfer using the functions
+ BSP_SDRAM_ReadData_DMA()/BSP_SDRAM_WriteData_DMA().
+ o The AHB access is performed with 32-bit width transaction, the MDMA transfer
+ configuration is fixed at single (no burst) word transfer (see the
+ SDRAM_MspInit() static function).
+ o User can implement his own functions for read/write access with his desired
+ configurations.
+ o If interrupt mode is used for MDMA transfer, the function BSP_SDRAM_MDMA_IRQHandler()
+ is called in IRQ handler file, to serve the generated interrupt once the MDMA
+ transfer is complete.
+ o You can send a command to the SDRAM device in runtime using the function
+ BSP_SDRAM_Sendcmd(), and giving the desired command as parameter chosen between
+ the predefined commands of the "FMC_SDRAM_CommandTypeDef" structure.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h747i_discovery_sdram.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_SDRAM STM32H747I_DISCOVERY_SDRAM
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_SDRAM_Exported_Variables Exported Variables
+ * @{
+ */
+SDRAM_HandleTypeDef sdramHandle;
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_SDRAM_Private_Variables Private Variables
+ * @{
+ */
+static FMC_SDRAM_TimingTypeDef Timing;
+static FMC_SDRAM_CommandTypeDef Command;
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_SDRAM_Exported_Functions Exported_Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes the SDRAM device.
+ * @retval SDRAM status
+ */
+uint8_t BSP_SDRAM_Init(void)
+{
+ static uint8_t sdramstatus = SDRAM_OK;
+ /* SDRAM device configuration */
+ sdramHandle.Instance = FMC_SDRAM_DEVICE;
+
+ /* Timing configuration for 100Mhz as SDRAM clock frequency (System clock is up to 200Mhz) */
+ Timing.LoadToActiveDelay = 2;
+ Timing.ExitSelfRefreshDelay = 7;
+ Timing.SelfRefreshTime = 4;
+ Timing.RowCycleDelay = 7;
+ Timing.WriteRecoveryTime = 2;
+ Timing.RPDelay = 2;
+ Timing.RCDDelay = 2;
+
+ sdramHandle.Init.SDBank = FMC_SDRAM_BANK2;
+ sdramHandle.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
+ 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 = FMC_SDRAM_CAS_LATENCY_3;
+ sdramHandle.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
+ sdramHandle.Init.SDClockPeriod = SDCLOCK_PERIOD;
+ sdramHandle.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
+ sdramHandle.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
+
+ /* SDRAM controller initialization */
+
+ BSP_SDRAM_MspInit(&sdramHandle, NULL); /* __weak function can be rewritten by the application */
+
+ if(HAL_SDRAM_Init(&sdramHandle, &Timing) != HAL_OK)
+ {
+ sdramstatus = SDRAM_ERROR;
+ }
+ else
+ {
+ /* SDRAM initialization sequence */
+ BSP_SDRAM_Initialization_sequence(REFRESH_COUNT);
+ }
+
+ return sdramstatus;
+}
+
+/**
+ * @brief DeInitializes the SDRAM device.
+ * @retval SDRAM status
+ */
+uint8_t BSP_SDRAM_DeInit(void)
+{
+ static uint8_t sdramstatus = SDRAM_OK;
+ /* SDRAM device de-initialization */
+ sdramHandle.Instance = FMC_SDRAM_DEVICE;
+
+ if(HAL_SDRAM_DeInit(&sdramHandle) != HAL_OK)
+ {
+ sdramstatus = SDRAM_ERROR;
+ }
+ else
+ {
+ /* SDRAM controller de-initialization */
+ BSP_SDRAM_MspDeInit(&sdramHandle, NULL);
+ }
+
+ return sdramstatus;
+}
+
+/**
+ * @brief Programs the SDRAM device.
+ * @param RefreshCount: SDRAM refresh counter value
+ * @retval None
+ */
+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 = 8;
+ 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 amount 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
+ * @retval SDRAM status
+ */
+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 amount 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
+ * @retval SDRAM status
+ */
+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 amount 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
+ * @retval SDRAM status
+ */
+uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)
+{
+ if(HAL_SDRAM_Write_32b(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
+ {
+ return SDRAM_ERROR;
+ }
+ else
+ {
+ return SDRAM_OK;
+ }
+}
+
+/**
+ * @brief Writes an amount 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
+ * @retval SDRAM status
+ */
+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 SDRAM 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 Initializes SDRAM MSP.
+ * @param hsdram SDRAM handle
+ * @param Params User parameters
+ * @retval None
+ */
+__weak void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram, void *Params)
+{
+ static MDMA_HandleTypeDef mdma_handle;
+ GPIO_InitTypeDef gpio_init_structure;
+
+ /* Enable FMC clock */
+ __HAL_RCC_FMC_CLK_ENABLE();
+
+ /* Enable chosen MDMAx clock */
+ __MDMAx_CLK_ENABLE();
+
+ /* Enable GPIOs clock */
+ __HAL_RCC_GPIOD_CLK_ENABLE();
+ __HAL_RCC_GPIOE_CLK_ENABLE();
+ __HAL_RCC_GPIOF_CLK_ENABLE();
+ __HAL_RCC_GPIOG_CLK_ENABLE();
+ __HAL_RCC_GPIOH_CLK_ENABLE();
+ __HAL_RCC_GPIOI_CLK_ENABLE();
+
+ /* Common GPIO configuration */
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ gpio_init_structure.Alternate = GPIO_AF12_FMC;
+
+ /* GPIOD configuration */
+ gpio_init_structure.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_init_structure);
+
+ /* GPIOE configuration */
+ gpio_init_structure.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_init_structure);
+
+ /* GPIOF configuration */
+ gpio_init_structure.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_init_structure);
+
+ /* GPIOG configuration */
+ gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 /*| GPIO_PIN_3 */|\
+ GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15;
+ HAL_GPIO_Init(GPIOG, &gpio_init_structure);
+
+ /* GPIOH configuration */
+ gpio_init_structure.Pin = GPIO_PIN_5 | GPIO_PIN_6 | 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(GPIOH, &gpio_init_structure);
+
+ /* GPIOI configuration */
+ gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 |\
+ GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_9 | GPIO_PIN_10;
+ HAL_GPIO_Init(GPIOI, &gpio_init_structure);
+
+ /* Configure common MDMA parameters */
+ mdma_handle.Init.Request = MDMA_REQUEST_SW;
+ mdma_handle.Init.TransferTriggerMode = MDMA_BLOCK_TRANSFER;
+ mdma_handle.Init.Priority = MDMA_PRIORITY_HIGH;
+ mdma_handle.Init.Endianness = MDMA_LITTLE_ENDIANNESS_PRESERVE;
+ mdma_handle.Init.SourceInc = MDMA_SRC_INC_WORD;
+ mdma_handle.Init.DestinationInc = MDMA_DEST_INC_WORD;
+ mdma_handle.Init.SourceDataSize = MDMA_SRC_DATASIZE_WORD;
+ mdma_handle.Init.DestDataSize = MDMA_DEST_DATASIZE_WORD;
+ mdma_handle.Init.DataAlignment = MDMA_DATAALIGN_PACKENABLE;
+ mdma_handle.Init.SourceBurst = MDMA_SOURCE_BURST_SINGLE;
+ mdma_handle.Init.DestBurst = MDMA_DEST_BURST_SINGLE;
+ mdma_handle.Init.BufferTransferLength = 128;
+ mdma_handle.Init.SourceBlockAddressOffset = 0;
+ mdma_handle.Init.DestBlockAddressOffset = 0;
+
+
+ mdma_handle.Instance = SDRAM_MDMAx_CHANNEL;
+
+ /* Associate the DMA handle */
+ __HAL_LINKDMA(hsdram, hmdma, mdma_handle);
+
+ /* Deinitialize the stream for new transfer */
+ HAL_MDMA_DeInit(&mdma_handle);
+
+ /* Configure the DMA stream */
+ HAL_MDMA_Init(&mdma_handle);
+
+ /* NVIC configuration for DMA transfer complete interrupt */
+ HAL_NVIC_SetPriority(SDRAM_MDMAx_IRQn, 0x0F, 0);
+ HAL_NVIC_EnableIRQ(SDRAM_MDMAx_IRQn);
+}
+
+/**
+ * @brief DeInitializes SDRAM MSP.
+ * @param hsdram SDRAM handle
+ * @param Params User parameters
+ * @retval None
+ */
+__weak void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram, void *Params)
+{
+ static MDMA_HandleTypeDef mdma_handle;
+
+ /* Disable NVIC configuration for DMA interrupt */
+ HAL_NVIC_DisableIRQ(SDRAM_MDMAx_IRQn);
+
+ /* Deinitialize the stream for new transfer */
+ mdma_handle.Instance = SDRAM_MDMAx_CHANNEL;
+ HAL_MDMA_DeInit(&mdma_handle);
+
+ /* GPIO pins clock, FMC clock and MDMA clock can be shut down in the applications
+ by surcharging this __weak function */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery_sdram.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,133 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery_sdram.h
+ * @author MCD Application Team
+ * @brief This file contains the common defines and functions prototypes for
+ * the stm32h747i_discovery_sdram.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32H747I_DISCOVERY_SDRAM_H
+#define __STM32H747I_DISCOVERY_SDRAM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY_SDRAM
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_SDRAM_Exported_Constants Exported Constants
+ * @{
+ */
+/**
+ * @brief SDRAM status structure definition
+ */
+#define SDRAM_OK ((uint8_t)0x00)
+#define SDRAM_ERROR ((uint8_t)0x01)
+
+#define SDRAM_DEVICE_ADDR ((uint32_t)0xD0000000)
+#define SDRAM_DEVICE_SIZE ((uint32_t)0x2000000) /* SDRAM device size in MBytes */
+
+/* #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_8 */
+/* #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16 */
+#define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_32
+
+#define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_2
+/* #define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_3 */
+
+#define REFRESH_COUNT ((uint32_t)0x0603) /* SDRAM refresh counter (100Mhz SD clock) */
+
+#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
+
+/* DMA definitions for SDRAM DMA transfer */
+#define __MDMAx_CLK_ENABLE __HAL_RCC_MDMA_CLK_ENABLE
+#define __MDMAx_CLK_DISABLE __HAL_RCC_MDMA_CLK_DISABLE
+#define SDRAM_MDMAx_CHANNEL MDMA_Channel0
+#define SDRAM_MDMAx_IRQn MDMA_IRQn
+
+
+/**
+ * @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)
+/**
+ * @}
+ */
+
+
+/** @addtogroup STM32H747I_DISCOVERY_SDRAM_Exported_Functions
+ * @{
+ */
+uint8_t BSP_SDRAM_Init(void);
+uint8_t BSP_SDRAM_DeInit(void);
+void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount);
+uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize);
+uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd);
+
+/* These functions can be modified in case the current settings (e.g. DMA stream)
+ need to be changed for specific application needs */
+void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram, void *Params);
+void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram, void *Params);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32H747I_DISCOVERY_SDRAM_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery_ts.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,419 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery_ts.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the Touch
+ * Screen on STM32H747I_DISCOVERY discovery board.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* File Info : -----------------------------------------------------------------
+ User NOTES
+1. How To use this driver:
+--------------------------
+ - This driver is used to drive the touch screen module of the STM32H747I_DISCOVERY
+ discovery board on the K.O.D Optica Technology 480x800 TFT-LCD mounted on
+ MB1166 daughter board. The touch screen driver IC inside the K.O.D module KM-040TMP-02
+ is a FT6206 by Focal Tech.
+
+2. Driver description:
+---------------------
+ + Initialization steps:
+ o Initialize the TS module using the BSP_TS_Init() function. This
+ function includes the MSP layer hardware resources initialization and the
+ communication layer configuration to start the TS use. The LCD size properties
+ (x and y) are passed as parameters.
+ o If TS interrupt mode is desired, you must configure the TS interrupt mode
+ by calling the function BSP_TS_ITConfig(). The TS interrupt mode is generated
+ as an external interrupt whenever a touch is detected.
+ The interrupt mode internally uses the IO functionalities driver driven by
+ the IO expander, to configure the IT line.
+
+ + Touch screen use
+ o The touch screen state is captured whenever the function BSP_TS_GetState() is
+ used. This function returns information about the last LCD touch occurred
+ in the TS_StateTypeDef structure.
+ o The IT is handled using the corresponding external interrupt IRQ handler,
+ the user IT callback treatment is implemented on the same external interrupt
+ callback.
+
+------------------------------------------------------------------------------*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h747i_discovery.h"
+#include "stm32h747i_discovery_ts.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_TS STM32H747I_DISCOVERY_TS
+ * @{
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_TS_Private_Variables Private Variables
+ * @{
+ */
+static TS_DrvTypeDef *ts_driver;
+static uint8_t ts_orientation;
+static uint8_t I2C_Address = 0;
+
+/* Table for touchscreen event information display on LCD : table indexed on enum @ref TS_TouchEventTypeDef information */
+char * ts_event_string_tab[TOUCH_EVENT_NB_MAX] = { "None",
+ "Press down",
+ "Lift up",
+ "Contact"
+ };
+
+/* Table for touchscreen gesture Id information display on LCD : table indexed on enum @ref TS_GestureIdTypeDef information */
+char * ts_gesture_id_string_tab[GEST_ID_NB_MAX] = { "None",
+ "Move Up",
+ "Move Right",
+ "Move Down",
+ "Move Left",
+ "Zoom In",
+ "Zoom Out"
+ };
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_TS_Exported_Functions Exported Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes and configures the touch screen functionalities and
+ * configures all necessary hardware resources (GPIOs, I2C, clocks..).
+ * @param ts_SizeX : Maximum X size of the TS area on LCD
+ * @param ts_SizeY : Maximum Y size of the TS area on LCD
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_Init(uint16_t ts_SizeX, uint16_t ts_SizeY)
+{
+ uint8_t ts_status = TS_OK;
+ uint8_t ts_id1, ts_id2 = 0;
+ /* Note : I2C_Address is un-initialized here, but is not used at all in init function */
+ /* but the prototype of Init() is like that in template and should be respected */
+
+ /* Initialize the communication channel to sensor (I2C) if necessary */
+ /* that is initialization is done only once after a power up */
+ ft6x06_ts_drv.Init(I2C_Address);
+
+ ts_id1 = ft6x06_ts_drv.ReadID(TS_I2C_ADDRESS);
+ if(ts_id1 != FT6206_ID_VALUE)
+ {
+ ts_id2 = ft6x06_ts_drv.ReadID(TS_I2C_ADDRESS_A02);
+ I2C_Address = TS_I2C_ADDRESS_A02;
+ }
+ else
+ {
+ I2C_Address = TS_I2C_ADDRESS;
+ }
+
+ /* Scan FT6xx6 TouchScreen IC controller ID register by I2C Read */
+ /* Verify this is a FT6206 or FT6336G, otherwise this is an error case */
+ if((ts_id1 == FT6206_ID_VALUE) || (ts_id2 == FT6206_ID_VALUE))
+ {
+ /* Found FT6206 : Initialize the TS driver structure */
+ ts_driver = &ft6x06_ts_drv;
+
+ /* Get LCD chosen orientation */
+ if(ts_SizeX < ts_SizeY)
+ {
+ ts_orientation = TS_SWAP_NONE;
+ }
+ else
+ {
+ ts_orientation = TS_SWAP_XY | TS_SWAP_Y;
+ }
+
+ if(ts_status == TS_OK)
+ {
+ /* Software reset the TouchScreen */
+ ts_driver->Reset(I2C_Address);
+
+ /* Calibrate, Configure and Start the TouchScreen driver */
+ ts_driver->Start(I2C_Address);
+
+ } /* of if(ts_status == TS_OK) */
+ }
+ else
+ {
+ ts_status = TS_DEVICE_NOT_FOUND;
+ }
+
+ return (ts_status);
+}
+
+/**
+ * @brief Configures and enables the touch screen interrupts.
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_ITConfig(void)
+{
+ uint8_t ts_status = TS_OK;
+ GPIO_InitTypeDef gpio_init_structure;
+
+ /* Msp Init of GPIO used for TS_INT pin coming from TouchScreen driver IC FT6x06 */
+ /* When touchscreen is operated in interrupt mode */
+ BSP_TS_INT_MspInit();
+
+ /* Configure Interrupt mode for TS_INT pin falling edge : when a new touch is available */
+ /* TS_INT pin is active on low level on new touch available */
+ gpio_init_structure.Pin = TS_INT_PIN;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
+ gpio_init_structure.Mode = GPIO_MODE_IT_FALLING;
+ HAL_GPIO_Init(TS_INT_GPIO_PORT, &gpio_init_structure);
+
+ /* Enable and set the TS_INT EXTI Interrupt to an intermediate priority */
+ HAL_NVIC_SetPriority((IRQn_Type)(TS_INT_EXTI_IRQn), 0x0F, 0x00);
+ HAL_NVIC_EnableIRQ((IRQn_Type)(TS_INT_EXTI_IRQn));
+
+ /* Enable the TS in interrupt mode */
+ /* In that case the INT output of FT6206 when new touch is available */
+ /* is active on low level and directed on EXTI */
+ ts_driver->EnableIT(I2C_Address);
+
+ return (ts_status);
+}
+
+/**
+ * @brief Returns status and positions of the touch screen.
+ * @param TS_State: Pointer to touch screen current state structure
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_GetState(TS_StateTypeDef *TS_State)
+{
+ static uint32_t _x[TS_MAX_NB_TOUCH] = {0, 0};
+ static uint32_t _y[TS_MAX_NB_TOUCH] = {0, 0};
+ uint8_t ts_status = TS_OK;
+ uint16_t tmp;
+ uint16_t Raw_x[TS_MAX_NB_TOUCH];
+ uint16_t Raw_y[TS_MAX_NB_TOUCH];
+ uint16_t xDiff;
+ uint16_t yDiff;
+ uint32_t index;
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+ uint32_t weight = 0;
+ uint32_t area = 0;
+ uint32_t event = 0;
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+ /* Check and update the number of touches active detected */
+ TS_State->touchDetected = ts_driver->DetectTouch(I2C_Address);
+ if(TS_State->touchDetected)
+ {
+ for(index=0; index < TS_State->touchDetected; index++)
+ {
+ /* Get each touch coordinates */
+ ts_driver->GetXY(I2C_Address, &(Raw_x[index]), &(Raw_y[index]));
+
+ if(ts_orientation & TS_SWAP_XY)
+ {
+ tmp = Raw_x[index];
+ Raw_x[index] = Raw_y[index];
+ Raw_y[index] = tmp;
+ }
+
+ if(ts_orientation & TS_SWAP_X)
+ {
+ Raw_x[index] = FT_6206_MAX_WIDTH - 1 - Raw_x[index];
+ }
+
+ if(ts_orientation & TS_SWAP_Y)
+ {
+ Raw_y[index] = FT_6206_MAX_HEIGHT - 1 - Raw_y[index];
+ }
+
+ xDiff = Raw_x[index] > _x[index]? (Raw_x[index] - _x[index]): (_x[index] - Raw_x[index]);
+ yDiff = Raw_y[index] > _y[index]? (Raw_y[index] - _y[index]): (_y[index] - Raw_y[index]);
+
+ if ((xDiff + yDiff) > 5)
+ {
+ _x[index] = Raw_x[index];
+ _y[index] = Raw_y[index];
+ }
+
+
+ TS_State->touchX[index] = _x[index];
+ TS_State->touchY[index] = _y[index];
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+
+ /* Get touch info related to the current touch */
+ ft6x06_TS_GetTouchInfo(I2C_Address, index, &weight, &area, &event);
+
+ /* Update TS_State structure */
+ TS_State->touchWeight[index] = weight;
+ TS_State->touchArea[index] = area;
+
+ /* Remap touch event */
+ switch(event)
+ {
+ case FT6206_TOUCH_EVT_FLAG_PRESS_DOWN :
+ TS_State->touchEventId[index] = TOUCH_EVENT_PRESS_DOWN;
+ break;
+ case FT6206_TOUCH_EVT_FLAG_LIFT_UP :
+ TS_State->touchEventId[index] = TOUCH_EVENT_LIFT_UP;
+ break;
+ case FT6206_TOUCH_EVT_FLAG_CONTACT :
+ TS_State->touchEventId[index] = TOUCH_EVENT_CONTACT;
+ break;
+ case FT6206_TOUCH_EVT_FLAG_NO_EVENT :
+ TS_State->touchEventId[index] = TOUCH_EVENT_NO_EVT;
+ break;
+ default :
+ ts_status = TS_ERROR;
+ break;
+ } /* of switch(event) */
+
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+ } /* of for(index=0; index < TS_State->touchDetected; index++) */
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+ /* Get gesture Id */
+ ts_status = BSP_TS_Get_GestureId(TS_State);
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+ } /* end of if(TS_State->touchDetected != 0) */
+
+ return (ts_status);
+}
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+/**
+ * @brief Update gesture Id following a touch detected.
+ * @param TS_State: Pointer to touch screen current state structure
+ * @retval TS_OK if all initializations are OK. Other value if error.
+ */
+uint8_t BSP_TS_Get_GestureId(TS_StateTypeDef *TS_State)
+{
+ uint32_t gestureId = 0;
+ uint8_t ts_status = TS_OK;
+
+ /* Get gesture Id */
+ ft6x06_TS_GetGestureID(I2C_Address, &gestureId);
+
+ /* Remap gesture Id to a TS_GestureIdTypeDef value */
+ switch(gestureId)
+ {
+ case FT6206_GEST_ID_NO_GESTURE :
+ TS_State->gestureId = GEST_ID_NO_GESTURE;
+ break;
+ case FT6206_GEST_ID_MOVE_UP :
+ TS_State->gestureId = GEST_ID_MOVE_UP;
+ break;
+ case FT6206_GEST_ID_MOVE_RIGHT :
+ TS_State->gestureId = GEST_ID_MOVE_RIGHT;
+ break;
+ case FT6206_GEST_ID_MOVE_DOWN :
+ TS_State->gestureId = GEST_ID_MOVE_DOWN;
+ break;
+ case FT6206_GEST_ID_MOVE_LEFT :
+ TS_State->gestureId = GEST_ID_MOVE_LEFT;
+ break;
+ case FT6206_GEST_ID_ZOOM_IN :
+ TS_State->gestureId = GEST_ID_ZOOM_IN;
+ break;
+ case FT6206_GEST_ID_ZOOM_OUT :
+ TS_State->gestureId = GEST_ID_ZOOM_OUT;
+ break;
+ default :
+ ts_status = TS_ERROR;
+ break;
+ } /* of switch(gestureId) */
+
+ return(ts_status);
+}
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+/**
+ * @brief Function used to reset all touch data before a new acquisition
+ * of touch information.
+ * @param TS_State: Pointer to touch screen current state structure
+ * @retval TS_OK if OK, TE_ERROR if problem found.
+ */
+uint8_t BSP_TS_ResetTouchData(TS_StateTypeDef *TS_State)
+{
+ uint8_t ts_status = TS_ERROR;
+ uint32_t index;
+
+ if (TS_State != (TS_StateTypeDef *)NULL)
+ {
+ TS_State->gestureId = GEST_ID_NO_GESTURE;
+ TS_State->touchDetected = 0;
+
+ for(index = 0; index < TS_MAX_NB_TOUCH; index++)
+ {
+ TS_State->touchX[index] = 0;
+ TS_State->touchY[index] = 0;
+ TS_State->touchArea[index] = 0;
+ TS_State->touchEventId[index] = TOUCH_EVENT_NO_EVT;
+ TS_State->touchWeight[index] = 0;
+ }
+
+ ts_status = TS_OK;
+
+ } /* of if (TS_State != (TS_StateTypeDef *)NULL) */
+
+ return (ts_status);
+}
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+/**
+ * @brief Initializes the TS_INT pin MSP.
+ * @retval None
+ */
+__weak void BSP_TS_INT_MspInit(void)
+{
+ GPIO_InitTypeDef gpio_init_structure;
+
+ TS_INT_GPIO_CLK_ENABLE();
+
+ /* GPIO configuration in input for TouchScreen interrupt signal on TS_INT pin */
+ gpio_init_structure.Pin = TS_INT_PIN;
+
+ gpio_init_structure.Mode = GPIO_MODE_INPUT;
+ gpio_init_structure.Pull = GPIO_PULLUP;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ HAL_GPIO_Init(TS_INT_GPIO_PORT, &gpio_init_structure);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/STM32H747I-Discovery/stm32h747i_discovery_ts.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,195 @@
+/**
+ ******************************************************************************
+ * @file stm32h747i_discovery_ts.h
+ * @author MCD Application Team
+ * @brief This file contains the common defines and functions prototypes for
+ * the stm32h747i_discovery_ts.c driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32H747I_DISCOVERY_TS_H
+#define __STM32H747I_DISCOVERY_TS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h747i_discovery.h"
+#include "stm32h747i_discovery_lcd.h"
+
+/* Include TouchScreen component driver */
+#include "../Components/ft6x06/ft6x06.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY
+ * @{
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY_TS
+ * @{
+ */
+
+ /** @defgroup STM32H747I_DISCOVERY_TS_Exported_Constants Exported Constants
+ * @{
+ */
+/** @brief With FT6206 : maximum 2 touches detected simultaneously
+ */
+#define TS_MAX_NB_TOUCH ((uint32_t) FT6206_MAX_DETECTABLE_TOUCH)
+
+#define TS_NO_IRQ_PENDING ((uint8_t) 0)
+#define TS_IRQ_PENDING ((uint8_t) 1)
+
+#define TS_SWAP_NONE ((uint8_t) 0x01)
+#define TS_SWAP_X ((uint8_t) 0x02)
+#define TS_SWAP_Y ((uint8_t) 0x04)
+#define TS_SWAP_XY ((uint8_t) 0x08)
+
+ /**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_TS_Exported_Types Exported Types
+ * @{
+ */
+/**
+* @brief TS_StateTypeDef
+* Define TS State structure
+*/
+typedef struct
+{
+ uint8_t touchDetected; /*!< Total number of active touches detected at last scan */
+ uint16_t touchX[TS_MAX_NB_TOUCH]; /*!< Touch X[0], X[1] coordinates on 12 bits */
+ uint16_t touchY[TS_MAX_NB_TOUCH]; /*!< Touch Y[0], Y[1] coordinates on 12 bits */
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+ uint8_t touchWeight[TS_MAX_NB_TOUCH]; /*!< Touch_Weight[0], Touch_Weight[1] : weight property of touches */
+ uint8_t touchEventId[TS_MAX_NB_TOUCH]; /*!< Touch_EventId[0], Touch_EventId[1] : take value of type @ref TS_TouchEventTypeDef */
+ uint8_t touchArea[TS_MAX_NB_TOUCH]; /*!< Touch_Area[0], Touch_Area[1] : touch area of each touch */
+ uint32_t gestureId; /*!< type of gesture detected : take value of type @ref TS_GestureIdTypeDef */
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+} TS_StateTypeDef;
+
+/**
+ * @brief TS_StatusTypeDef
+ * Define BSP_TS_xxx() functions possible return value,
+ * when status is returned by those functions.
+ */
+typedef enum
+{
+ TS_OK = 0x00, /*!< Touch Ok */
+ TS_ERROR = 0x01, /*!< Touch Error */
+ TS_TIMEOUT = 0x02, /*!< Touch Timeout */
+ TS_DEVICE_NOT_FOUND = 0x03 /*!< Touchscreen device not found */
+} TS_StatusTypeDef;
+
+/**
+ * @brief TS_GestureIdTypeDef
+ * Define Possible managed gesture identification values returned by touch screen
+ * driver.
+ */
+typedef enum
+{
+ GEST_ID_NO_GESTURE = 0x00, /*!< Gesture not defined / recognized */
+ GEST_ID_MOVE_UP = 0x01, /*!< Gesture Move Up */
+ GEST_ID_MOVE_RIGHT = 0x02, /*!< Gesture Move Right */
+ GEST_ID_MOVE_DOWN = 0x03, /*!< Gesture Move Down */
+ GEST_ID_MOVE_LEFT = 0x04, /*!< Gesture Move Left */
+ GEST_ID_ZOOM_IN = 0x05, /*!< Gesture Zoom In */
+ GEST_ID_ZOOM_OUT = 0x06, /*!< Gesture Zoom Out */
+ GEST_ID_NB_MAX = 0x07 /*!< max number of gesture id */
+} TS_GestureIdTypeDef;
+
+/**
+ * @brief TS_TouchEventTypeDef
+ * Define Possible touch events kind as returned values
+ * by touch screen IC Driver.
+ */
+typedef enum
+{
+ TOUCH_EVENT_NO_EVT = 0x00, /*!< Touch Event : undetermined */
+ TOUCH_EVENT_PRESS_DOWN = 0x01, /*!< Touch Event Press Down */
+ TOUCH_EVENT_LIFT_UP = 0x02, /*!< Touch Event Lift Up */
+ TOUCH_EVENT_CONTACT = 0x03, /*!< Touch Event Contact */
+ TOUCH_EVENT_NB_MAX = 0x04 /*!< max number of touch events kind */
+} TS_TouchEventTypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32H747I_DISCOVERY_TS_Imported_Variables Imported Variables
+ * @{
+ */
+/**
+ * @brief Table for touchscreen event information display on LCD :
+ * table indexed on enum @ref TS_TouchEventTypeDef information
+ */
+extern char * ts_event_string_tab[TOUCH_EVENT_NB_MAX];
+
+/**
+ * @brief Table for touchscreen gesture Id information display on LCD : table indexed
+ * on enum @ref TS_GestureIdTypeDef information
+ */
+extern char * ts_gesture_id_string_tab[GEST_ID_NB_MAX];
+/**
+ * @}
+ */
+
+/** @addtogroup STM32H747I_DISCOVERY_TS_Exported_Functions
+ * @{
+ */
+uint8_t BSP_TS_Init(uint16_t ts_SizeX, uint16_t ts_SizeY);
+uint8_t BSP_TS_GetState(TS_StateTypeDef *TS_State);
+
+#if (TS_MULTI_TOUCH_SUPPORTED == 1)
+uint8_t BSP_TS_Get_GestureId(TS_StateTypeDef *TS_State);
+uint8_t BSP_TS_ResetTouchData(TS_StateTypeDef *TS_State);
+#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
+
+uint8_t BSP_TS_ITConfig(void);
+
+/* These __weak function can be surcharged by application code in case the current settings
+ need to be changed for specific (example GPIO allocation) */
+void BSP_TS_INT_MspInit(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32H747I_DISCOVERY_TS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Utilities/Fonts/Release_Notes.html Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,163 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40"><head>
+
+
+
+
+
+
+
+
+
+
+
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+
+
+ <link rel="File-List" href="Library_files/filelist.xml">
+
+
+ <link rel="Edit-Time-Data" href="Library_files/editdata.mso"><!--[if !mso]> <style> v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]--><title>Release Notes for STM32Cube Fonts Utilities Driver</title><!--[if gte mso 9]><xml> <o:DocumentProperties> <o:Author>STMicroelectronics</o:Author> <o:LastAuthor>STMicroelectronics</o:LastAuthor> <o:Revision>37</o:Revision> <o:TotalTime>136</o:TotalTime> <o:Created>2009-02-27T19:26:00Z</o:Created> <o:LastSaved>2009-03-01T17:56:00Z</o:LastSaved> <o:Pages>1</o:Pages> <o:Words>522</o:Words> <o:Characters>2977</o:Characters> <o:Company>STMicroelectronics</o:Company> <o:Lines>24</o:Lines> <o:Paragraphs>6</o:Paragraphs> <o:CharactersWithSpaces>3493</o:CharactersWithSpaces> <o:Version>11.6568</o:Version> </o:DocumentProperties> </xml><![endif]--><!--[if gte mso 9]><xml> <w:WordDocument> <w:Zoom>110</w:Zoom> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]-->
+
+
+
+
+
+
+
+ <style>
+<!--
+/* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+{mso-style-parent:"";
+margin:0in;
+margin-bottom:.0001pt;
+mso-pagination:widow-orphan;
+font-size:12.0pt;
+font-family:"Times New Roman";
+mso-fareast-font-family:"Times New Roman";}
+h2
+{mso-style-next:Normal;
+margin-top:12.0pt;
+margin-right:0in;
+margin-bottom:3.0pt;
+margin-left:0in;
+mso-pagination:widow-orphan;
+page-break-after:avoid;
+mso-outline-level:2;
+font-size:14.0pt;
+font-family:Arial;
+font-weight:bold;
+font-style:italic;}
+a:link, span.MsoHyperlink
+{color:blue;
+text-decoration:underline;
+text-underline:single;}
+a:visited, span.MsoHyperlinkFollowed
+{color:blue;
+text-decoration:underline;
+text-underline:single;}
+p
+{mso-margin-top-alt:auto;
+margin-right:0in;
+mso-margin-bottom-alt:auto;
+margin-left:0in;
+mso-pagination:widow-orphan;
+font-size:12.0pt;
+font-family:"Times New Roman";
+mso-fareast-font-family:"Times New Roman";}
+@page Section1
+{size:8.5in 11.0in;
+margin:1.0in 1.25in 1.0in 1.25in;
+mso-header-margin:.5in;
+mso-footer-margin:.5in;
+mso-paper-source:0;}
+div.Section1
+{page:Section1;}
+-->
+ </style><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin:0in; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} </style> <![endif]--><!--[if gte mso 9]><xml> <o:shapedefaults v:ext="edit" spidmax="5122"/> </xml><![endif]--><!--[if gte mso 9]><xml> <o:shapelayout v:ext="edit"> <o:idmap v:ext="edit" data="1"/> </o:shapelayout></xml><![endif]-->
+ <meta content="MCD Application Team" name="author"></head><body link="blue" vlink="blue">
+<div class="Section1">
+<p class="MsoNormal"><span style="font-family: Arial;"><o:p><br>
+</o:p></span></p>
+<div align="center">
+<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900">
+ <tbody>
+ <tr>
+ <td style="padding: 0cm;" valign="top">
+ <table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900">
+ <tbody>
+ <tr>
+ <td style="vertical-align: top;">
+ <p class="MsoNormal"><span style="font-size: 8pt; font-family: Arial; color: blue;"><a href="../../Release_Notes.html">Back to Release page</a><o:p></o:p></span></p>
+ </td>
+ </tr>
+ <tr style="">
+ <td style="padding: 1.5pt;">
+ <h1 style="margin-bottom: 18pt; text-align: center;" align="center"><span style="font-size: 20pt; font-family: Verdana; color: rgb(51, 102, 255);">Release
+Notes for STM32Cube Fonts Utilities Driver</span><span style="font-size: 20pt; font-family: Verdana;"><o:p></o:p></span></h1>
+ <p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: Arial; color: black;">Copyright
+2014 STMicroelectronics</span><span style="color: black;"><u1:p></u1:p><o:p></o:p></span></p>
+ <p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: Arial; color: black;"><img alt="" id="_x0000_i1025" src="../../_htmresc/st_logo.png" style="border: 0px solid ; width: 86px; height: 65px;"></span><span style="font-size: 10pt;"><o:p></o:p></span></p>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <p class="MsoNormal"><span style="font-family: Arial; display: none;"><o:p> </o:p></span></p>
+ <table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" width="900">
+ <tbody>
+ <tr style="">
+ <td style="padding: 0cm;" valign="top">
+ <span style="font-family: "Times New Roman";"></span><h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a name="History"></a><span style="font-size: 12pt; color: white;">Update History</span></h2><br>
+ <h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; margin-right: 500pt; width: 180px;"><span style="font-size: 10pt; font-family: Arial; color: white;">V1.0.0 / 18-February-2014 <o:p></o:p></span></h3>
+
+
+
+
+ <p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"><b style=""><u><span style="font-size: 10pt; font-family: Verdana; color: black;">Main
+Changes<o:p></o:p></span></u></b></p>
+ <span style="font-size: 10pt; font-family: Verdana;"></span><p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"><b style=""><u><span style="font-size: 10pt; font-family: Verdana; color: black;"><o:p></o:p></span></u></b></p>
+
+
+
+ <ul style="list-style-type: square;">
+ <li><span style="font-size: 10pt; font-family: Verdana;">First official release</span><span style="font-size: 10pt; font-family: Verdana;"><br>
+ </span></li>
+ </ul><span style="font-size: 10pt; font-family: Verdana;"><span style="font-style: italic; font-weight: bold;"></span></span><span style="font-size: 10pt; font-family: Verdana;"><span style="font-style: italic; font-weight: bold;"></span></span><span style="font-size: 10pt; font-family: Verdana;"><span style="font-style: italic; font-weight: bold;"></span></span><span style="font-size: 10pt; font-family: Verdana;"><span style="font-style: italic; font-weight: bold;"></span></span><span style="font-size: 10pt; font-family: Verdana;"><span style="font-style: italic; font-weight: bold;"></span></span><span style="font-size: 10pt; font-family: Verdana;"></span><h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a name="License"></a><span style="font-size: 12pt; color: white;">License<o:p></o:p></span><br></h2>
+ <div style="text-align: justify;"><font size="-1"><span style="font-family: "Verdana","sans-serif";">
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:</span><br>
+ </font>
+ <ol><li><font size="-1"><span style="font-family: "Verdana","sans-serif";">Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.</span><span style="font-family: "Verdana","sans-serif";"></span></font></li><li><font size="-1"><span style="font-family: "Verdana","sans-serif";">Redistributions
+in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in </span><span style="font-family: "Verdana","sans-serif";">the documentation and/or other materials provided with the distribution.</span><span style="font-family: "Verdana","sans-serif";"></span></font></li><li><font size="-1"><span style="font-family: "Verdana","sans-serif";">Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived </span><br>
+ </font>
+ </li></ol>
+ <font size="-1"><span style="font-family: "Verdana","sans-serif";"> from this software without specific prior written permission.</span><br>
+ <span style="font-family: "Verdana","sans-serif";"></span><br>
+ <span style="font-family: "Verdana","sans-serif";">THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED</span><span style="font-family: "Verdana","sans-serif";"> WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A </span><span style="font-family: "Verdana","sans-serif";">PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY </span><span style="font-family: "Verdana","sans-serif";">DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, </span><span style="font-family: "Verdana","sans-serif";">PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER</span><span style="font-family: "Verdana","sans-serif";"> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR </span><span style="font-family: "Verdana","sans-serif";">OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span></font>
+
+ </div>
+<p class="MsoNormal"><span style="font-size: 10pt; font-family: "Verdana","sans-serif"; color: black;"><o:p></o:p></span></p>
+<b><span style="font-size: 10pt; font-family: Verdana; color: black;"></span></b>
+
+ <div class="MsoNormal" style="text-align: center;" align="center"><span style="color: black;">
+ <hr align="center" size="2" width="100%"></span></div>
+ <p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt; text-align: center;" align="center"><span style="font-size: 10pt; font-family: Verdana; color: black;">For
+complete documentation on </span><span style="font-size: 10pt; font-family: Verdana;">STM32<span style="color: black;"> Microcontrollers
+visit </span><u><span style="color: blue;"><a href="http://www.st.com/internet/mcu/class/1734.jsp" target="_blank">www.st.com/STM32</a></span></u></span><span style="font-size: 10pt; font-family: Verdana;"><a target="_blank" href="http://www.st.com/internet/mcu/family/141.jsp"><u><span style="color: blue;"></span></u></a></span><span style="font-size: 10pt; font-family: Verdana;"><u><span style="color: blue;"></span></u></span><span style="color: black;"><o:p></o:p></span></p>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <p class="MsoNormal"><span style="font-size: 10pt;"><o:p></o:p></span></p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<p class="MsoNormal"><o:p> </o:p></p>
+</div>
+
+</body></html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Utilities/Fonts/font12.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,1464 @@
+/**
+ ******************************************************************************
+ * @file Font12.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 18-February-2014
+ * @brief This file provides text Font12 for STM32xx-EVAL's LCD driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "fonts.h"
+
+/** @addtogroup Utilities
+ * @{
+ */
+
+/** @addtogroup STM32_EVAL
+ * @{
+ */
+
+/** @addtogroup Common
+ * @{
+ */
+
+/** @addtogroup FONTS
+ * @brief This file provides text Font12 for STM32xx-EVAL's LCD driver.
+ * @{
+ */
+
+/** @defgroup FONTS_Private_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Variables
+ * @{
+ */
+//
+// Font data for Courier New 12pt
+//
+
+const uint8_t Font12_Table[] =
+{
+ // @0 ' ' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @12 '!' (7 pixels wide)
+ 0x00, //
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x00, //
+ 0x00, //
+ 0x10, // #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @24 '"' (7 pixels wide)
+ 0x00, //
+ 0x6C, // ## ##
+ 0x48, // # #
+ 0x48, // # #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @36 '#' (7 pixels wide)
+ 0x00, //
+ 0x14, // # #
+ 0x14, // # #
+ 0x28, // # #
+ 0x7C, // #####
+ 0x28, // # #
+ 0x7C, // #####
+ 0x28, // # #
+ 0x50, // # #
+ 0x50, // # #
+ 0x00, //
+ 0x00, //
+
+ // @48 '$' (7 pixels wide)
+ 0x00, //
+ 0x10, // #
+ 0x38, // ###
+ 0x40, // #
+ 0x40, // #
+ 0x38, // ###
+ 0x48, // # #
+ 0x70, // ###
+ 0x10, // #
+ 0x10, // #
+ 0x00, //
+ 0x00, //
+
+ // @60 '%' (7 pixels wide)
+ 0x00, //
+ 0x20, // #
+ 0x50, // # #
+ 0x20, // #
+ 0x0C, // ##
+ 0x70, // ###
+ 0x08, // #
+ 0x14, // # #
+ 0x08, // #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @72 '&' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x18, // ##
+ 0x20, // #
+ 0x20, // #
+ 0x54, // # # #
+ 0x48, // # #
+ 0x34, // ## #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @84 ''' (7 pixels wide)
+ 0x00, //
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @96 '(' (7 pixels wide)
+ 0x00, //
+ 0x08, // #
+ 0x08, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x08, // #
+ 0x08, // #
+ 0x00, //
+
+ // @108 ')' (7 pixels wide)
+ 0x00, //
+ 0x20, // #
+ 0x20, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x20, // #
+ 0x20, // #
+ 0x00, //
+
+ // @120 '*' (7 pixels wide)
+ 0x00, //
+ 0x10, // #
+ 0x7C, // #####
+ 0x10, // #
+ 0x28, // # #
+ 0x28, // # #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @132 '+' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0xFE, // #######
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @144 ',' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x18, // ##
+ 0x10, // #
+ 0x30, // ##
+ 0x20, // #
+ 0x00, //
+
+ // @156 '-' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x7C, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @168 '.' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x30, // ##
+ 0x30, // ##
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @180 '/' (7 pixels wide)
+ 0x00, //
+ 0x04, // #
+ 0x04, // #
+ 0x08, // #
+ 0x08, // #
+ 0x10, // #
+ 0x10, // #
+ 0x20, // #
+ 0x20, // #
+ 0x40, // #
+ 0x00, //
+ 0x00, //
+
+ // @192 '0' (7 pixels wide)
+ 0x00, //
+ 0x38, // ###
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @204 '1' (7 pixels wide)
+ 0x00, //
+ 0x30, // ##
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x7C, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @216 '2' (7 pixels wide)
+ 0x00, //
+ 0x38, // ###
+ 0x44, // # #
+ 0x04, // #
+ 0x08, // #
+ 0x10, // #
+ 0x20, // #
+ 0x44, // # #
+ 0x7C, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @228 '3' (7 pixels wide)
+ 0x00, //
+ 0x38, // ###
+ 0x44, // # #
+ 0x04, // #
+ 0x18, // ##
+ 0x04, // #
+ 0x04, // #
+ 0x44, // # #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @240 '4' (7 pixels wide)
+ 0x00, //
+ 0x0C, // ##
+ 0x14, // # #
+ 0x14, // # #
+ 0x24, // # #
+ 0x44, // # #
+ 0x7E, // ######
+ 0x04, // #
+ 0x0E, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @252 '5' (7 pixels wide)
+ 0x00, //
+ 0x3C, // ####
+ 0x20, // #
+ 0x20, // #
+ 0x38, // ###
+ 0x04, // #
+ 0x04, // #
+ 0x44, // # #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @264 '6' (7 pixels wide)
+ 0x00, //
+ 0x1C, // ###
+ 0x20, // #
+ 0x40, // #
+ 0x78, // ####
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @276 '7' (7 pixels wide)
+ 0x00, //
+ 0x7C, // #####
+ 0x44, // # #
+ 0x04, // #
+ 0x08, // #
+ 0x08, // #
+ 0x08, // #
+ 0x10, // #
+ 0x10, // #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @288 '8' (7 pixels wide)
+ 0x00, //
+ 0x38, // ###
+ 0x44, // # #
+ 0x44, // # #
+ 0x38, // ###
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @300 '9' (7 pixels wide)
+ 0x00, //
+ 0x38, // ###
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x3C, // ####
+ 0x04, // #
+ 0x08, // #
+ 0x70, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @312 ':' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x30, // ##
+ 0x30, // ##
+ 0x00, //
+ 0x00, //
+ 0x30, // ##
+ 0x30, // ##
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @324 ';' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x18, // ##
+ 0x18, // ##
+ 0x00, //
+ 0x00, //
+ 0x18, // ##
+ 0x30, // ##
+ 0x20, // #
+ 0x00, //
+ 0x00, //
+
+ // @336 '<' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x0C, // ##
+ 0x10, // #
+ 0x60, // ##
+ 0x80, // #
+ 0x60, // ##
+ 0x10, // #
+ 0x0C, // ##
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @348 '=' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x7C, // #####
+ 0x00, //
+ 0x7C, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @360 '>' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0xC0, // ##
+ 0x20, // #
+ 0x18, // ##
+ 0x04, // #
+ 0x18, // ##
+ 0x20, // #
+ 0xC0, // ##
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @372 '?' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x18, // ##
+ 0x24, // # #
+ 0x04, // #
+ 0x08, // #
+ 0x10, // #
+ 0x00, //
+ 0x30, // ##
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @384 '@' (7 pixels wide)
+ 0x38, // ###
+ 0x44, // # #
+ 0x44, // # #
+ 0x4C, // # ##
+ 0x54, // # # #
+ 0x54, // # # #
+ 0x4C, // # ##
+ 0x40, // #
+ 0x44, // # #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+
+ // @396 'A' (7 pixels wide)
+ 0x00, //
+ 0x30, // ##
+ 0x10, // #
+ 0x28, // # #
+ 0x28, // # #
+ 0x28, // # #
+ 0x7C, // #####
+ 0x44, // # #
+ 0xEE, // ### ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @408 'B' (7 pixels wide)
+ 0x00, //
+ 0xF8, // #####
+ 0x44, // # #
+ 0x44, // # #
+ 0x78, // ####
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0xF8, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @420 'C' (7 pixels wide)
+ 0x00, //
+ 0x3C, // ####
+ 0x44, // # #
+ 0x40, // #
+ 0x40, // #
+ 0x40, // #
+ 0x40, // #
+ 0x44, // # #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @432 'D' (7 pixels wide)
+ 0x00, //
+ 0xF0, // ####
+ 0x48, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x48, // # #
+ 0xF0, // ####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @444 'E' (7 pixels wide)
+ 0x00, //
+ 0xFC, // ######
+ 0x44, // # #
+ 0x50, // # #
+ 0x70, // ###
+ 0x50, // # #
+ 0x40, // #
+ 0x44, // # #
+ 0xFC, // ######
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @456 'F' (7 pixels wide)
+ 0x00, //
+ 0x7E, // ######
+ 0x22, // # #
+ 0x28, // # #
+ 0x38, // ###
+ 0x28, // # #
+ 0x20, // #
+ 0x20, // #
+ 0x70, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @468 'G' (7 pixels wide)
+ 0x00, //
+ 0x3C, // ####
+ 0x44, // # #
+ 0x40, // #
+ 0x40, // #
+ 0x4E, // # ###
+ 0x44, // # #
+ 0x44, // # #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @480 'H' (7 pixels wide)
+ 0x00, //
+ 0xEE, // ### ###
+ 0x44, // # #
+ 0x44, // # #
+ 0x7C, // #####
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0xEE, // ### ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @492 'I' (7 pixels wide)
+ 0x00, //
+ 0x7C, // #####
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x7C, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @504 'J' (7 pixels wide)
+ 0x00, //
+ 0x3C, // ####
+ 0x08, // #
+ 0x08, // #
+ 0x08, // #
+ 0x48, // # #
+ 0x48, // # #
+ 0x48, // # #
+ 0x30, // ##
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @516 'K' (7 pixels wide)
+ 0x00, //
+ 0xEE, // ### ###
+ 0x44, // # #
+ 0x48, // # #
+ 0x50, // # #
+ 0x70, // ###
+ 0x48, // # #
+ 0x44, // # #
+ 0xE6, // ### ##
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @528 'L' (7 pixels wide)
+ 0x00, //
+ 0x70, // ###
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x24, // # #
+ 0x24, // # #
+ 0x7C, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @540 'M' (7 pixels wide)
+ 0x00, //
+ 0xEE, // ### ###
+ 0x6C, // ## ##
+ 0x6C, // ## ##
+ 0x54, // # # #
+ 0x54, // # # #
+ 0x44, // # #
+ 0x44, // # #
+ 0xEE, // ### ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @552 'N' (7 pixels wide)
+ 0x00, //
+ 0xEE, // ### ###
+ 0x64, // ## #
+ 0x64, // ## #
+ 0x54, // # # #
+ 0x54, // # # #
+ 0x54, // # # #
+ 0x4C, // # ##
+ 0xEC, // ### ##
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @564 'O' (7 pixels wide)
+ 0x00, //
+ 0x38, // ###
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @576 'P' (7 pixels wide)
+ 0x00, //
+ 0x78, // ####
+ 0x24, // # #
+ 0x24, // # #
+ 0x24, // # #
+ 0x38, // ###
+ 0x20, // #
+ 0x20, // #
+ 0x70, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @588 'Q' (7 pixels wide)
+ 0x00, //
+ 0x38, // ###
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x38, // ###
+ 0x1C, // ###
+ 0x00, //
+ 0x00, //
+
+ // @600 'R' (7 pixels wide)
+ 0x00, //
+ 0xF8, // #####
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x78, // ####
+ 0x48, // # #
+ 0x44, // # #
+ 0xE2, // ### #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @612 'S' (7 pixels wide)
+ 0x00, //
+ 0x34, // ## #
+ 0x4C, // # ##
+ 0x40, // #
+ 0x38, // ###
+ 0x04, // #
+ 0x04, // #
+ 0x64, // ## #
+ 0x58, // # ##
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @624 'T' (7 pixels wide)
+ 0x00, //
+ 0xFE, // #######
+ 0x92, // # # #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @636 'U' (7 pixels wide)
+ 0x00, //
+ 0xEE, // ### ###
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @648 'V' (7 pixels wide)
+ 0x00, //
+ 0xEE, // ### ###
+ 0x44, // # #
+ 0x44, // # #
+ 0x28, // # #
+ 0x28, // # #
+ 0x28, // # #
+ 0x10, // #
+ 0x10, // #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @660 'W' (7 pixels wide)
+ 0x00, //
+ 0xEE, // ### ###
+ 0x44, // # #
+ 0x44, // # #
+ 0x54, // # # #
+ 0x54, // # # #
+ 0x54, // # # #
+ 0x54, // # # #
+ 0x28, // # #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @672 'X' (7 pixels wide)
+ 0x00, //
+ 0xC6, // ## ##
+ 0x44, // # #
+ 0x28, // # #
+ 0x10, // #
+ 0x10, // #
+ 0x28, // # #
+ 0x44, // # #
+ 0xC6, // ## ##
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @684 'Y' (7 pixels wide)
+ 0x00, //
+ 0xEE, // ### ###
+ 0x44, // # #
+ 0x28, // # #
+ 0x28, // # #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @696 'Z' (7 pixels wide)
+ 0x00, //
+ 0x7C, // #####
+ 0x44, // # #
+ 0x08, // #
+ 0x10, // #
+ 0x10, // #
+ 0x20, // #
+ 0x44, // # #
+ 0x7C, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @708 '[' (7 pixels wide)
+ 0x00, //
+ 0x38, // ###
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x38, // ###
+ 0x00, //
+
+ // @720 '\' (7 pixels wide)
+ 0x00, //
+ 0x40, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x10, // #
+ 0x10, // #
+ 0x08, // #
+ 0x08, // #
+ 0x08, // #
+ 0x00, //
+ 0x00, //
+
+ // @732 ']' (7 pixels wide)
+ 0x00, //
+ 0x38, // ###
+ 0x08, // #
+ 0x08, // #
+ 0x08, // #
+ 0x08, // #
+ 0x08, // #
+ 0x08, // #
+ 0x08, // #
+ 0x08, // #
+ 0x38, // ###
+ 0x00, //
+
+ // @744 '^' (7 pixels wide)
+ 0x00, //
+ 0x10, // #
+ 0x10, // #
+ 0x28, // # #
+ 0x44, // # #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @756 '_' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0xFE, // #######
+
+ // @768 '`' (7 pixels wide)
+ 0x00, //
+ 0x10, // #
+ 0x08, // #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @780 'a' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x38, // ###
+ 0x44, // # #
+ 0x3C, // ####
+ 0x44, // # #
+ 0x44, // # #
+ 0x3E, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @792 'b' (7 pixels wide)
+ 0x00, //
+ 0xC0, // ##
+ 0x40, // #
+ 0x58, // # ##
+ 0x64, // ## #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0xF8, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @804 'c' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x3C, // ####
+ 0x44, // # #
+ 0x40, // #
+ 0x40, // #
+ 0x44, // # #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @816 'd' (7 pixels wide)
+ 0x00, //
+ 0x0C, // ##
+ 0x04, // #
+ 0x34, // ## #
+ 0x4C, // # ##
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x3E, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @828 'e' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x38, // ###
+ 0x44, // # #
+ 0x7C, // #####
+ 0x40, // #
+ 0x40, // #
+ 0x3C, // ####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @840 'f' (7 pixels wide)
+ 0x00, //
+ 0x1C, // ###
+ 0x20, // #
+ 0x7C, // #####
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x7C, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @852 'g' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x36, // ## ##
+ 0x4C, // # ##
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x3C, // ####
+ 0x04, // #
+ 0x38, // ###
+ 0x00, //
+
+ // @864 'h' (7 pixels wide)
+ 0x00, //
+ 0xC0, // ##
+ 0x40, // #
+ 0x58, // # ##
+ 0x64, // ## #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0xEE, // ### ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @876 'i' (7 pixels wide)
+ 0x00, //
+ 0x10, // #
+ 0x00, //
+ 0x70, // ###
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x7C, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @888 'j' (7 pixels wide)
+ 0x00, //
+ 0x10, // #
+ 0x00, //
+ 0x78, // ####
+ 0x08, // #
+ 0x08, // #
+ 0x08, // #
+ 0x08, // #
+ 0x08, // #
+ 0x08, // #
+ 0x70, // ###
+ 0x00, //
+
+ // @900 'k' (7 pixels wide)
+ 0x00, //
+ 0xC0, // ##
+ 0x40, // #
+ 0x5C, // # ###
+ 0x48, // # #
+ 0x70, // ###
+ 0x50, // # #
+ 0x48, // # #
+ 0xDC, // ## ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @912 'l' (7 pixels wide)
+ 0x00, //
+ 0x30, // ##
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x7C, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @924 'm' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0xE8, // ### #
+ 0x54, // # # #
+ 0x54, // # # #
+ 0x54, // # # #
+ 0x54, // # # #
+ 0xFE, // #######
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @936 'n' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0xD8, // ## ##
+ 0x64, // ## #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0xEE, // ### ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @948 'o' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x38, // ###
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @960 'p' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0xD8, // ## ##
+ 0x64, // ## #
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x78, // ####
+ 0x40, // #
+ 0xE0, // ###
+ 0x00, //
+
+ // @972 'q' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x36, // ## ##
+ 0x4C, // # ##
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x3C, // ####
+ 0x04, // #
+ 0x0E, // ###
+ 0x00, //
+
+ // @984 'r' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x6C, // ## ##
+ 0x30, // ##
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x7C, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @996 's' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x3C, // ####
+ 0x44, // # #
+ 0x38, // ###
+ 0x04, // #
+ 0x44, // # #
+ 0x78, // ####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @1008 't' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x20, // #
+ 0x7C, // #####
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x22, // # #
+ 0x1C, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @1020 'u' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0xCC, // ## ##
+ 0x44, // # #
+ 0x44, // # #
+ 0x44, // # #
+ 0x4C, // # ##
+ 0x36, // ## ##
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @1032 'v' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0xEE, // ### ###
+ 0x44, // # #
+ 0x44, // # #
+ 0x28, // # #
+ 0x28, // # #
+ 0x10, // #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @1044 'w' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0xEE, // ### ###
+ 0x44, // # #
+ 0x54, // # # #
+ 0x54, // # # #
+ 0x54, // # # #
+ 0x28, // # #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @1056 'x' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0xCC, // ## ##
+ 0x48, // # #
+ 0x30, // ##
+ 0x30, // ##
+ 0x48, // # #
+ 0xCC, // ## ##
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @1068 'y' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0xEE, // ### ###
+ 0x44, // # #
+ 0x24, // # #
+ 0x28, // # #
+ 0x18, // ##
+ 0x10, // #
+ 0x10, // #
+ 0x78, // ####
+ 0x00, //
+
+ // @1080 'z' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x7C, // #####
+ 0x48, // # #
+ 0x10, // #
+ 0x20, // #
+ 0x44, // # #
+ 0x7C, // #####
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @1092 '{' (7 pixels wide)
+ 0x00, //
+ 0x08, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x20, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x08, // #
+ 0x00, //
+
+ // @1104 '|' (7 pixels wide)
+ 0x00, //
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x00, //
+ 0x00, //
+
+ // @1116 '}' (7 pixels wide)
+ 0x00, //
+ 0x20, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x08, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x20, // #
+ 0x00, //
+
+ // @1128 '~' (7 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x24, // # #
+ 0x58, // # ##
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+};
+
+sFONT Font12 = {
+ Font12_Table,
+ 7, /* Width */
+ 12, /* Height */
+};
+
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Function_Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Utilities/Fonts/font16.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,1844 @@
+/**
+ ******************************************************************************
+ * @file font16.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 18-February-2014
+ * @brief This file provides text font16 for STM32xx-EVAL's LCD driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "fonts.h"
+
+/** @addtogroup Utilities
+ * @{
+ */
+
+/** @addtogroup STM32_EVAL
+ * @{
+ */
+
+/** @addtogroup Common
+ * @{
+ */
+
+/** @addtogroup FONTS
+ * @brief This file provides text font16 for STM32xx-EVAL's LCD driver.
+ * @{
+ */
+
+/** @defgroup FONTS_Private_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Variables
+ * @{
+ */
+//
+// Font data for Courier New 12pt
+//
+
+const uint8_t Font16_Table[] =
+{
+ // @0 ' ' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @32 '!' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x00, 0x00, //
+ 0x0C, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @64 '"' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1D, 0xC0, // ### ###
+ 0x1D, 0xC0, // ### ###
+ 0x08, 0x80, // # #
+ 0x08, 0x80, // # #
+ 0x08, 0x80, // # #
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @96 '#' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x0D, 0x80, // ## ##
+ 0x0D, 0x80, // ## ##
+ 0x0D, 0x80, // ## ##
+ 0x0D, 0x80, // ## ##
+ 0x3F, 0xC0, // ########
+ 0x1B, 0x00, // ## ##
+ 0x3F, 0xC0, // ########
+ 0x1B, 0x00, // ## ##
+ 0x1B, 0x00, // ## ##
+ 0x1B, 0x00, // ## ##
+ 0x1B, 0x00, // ## ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @128 '$' (11 pixels wide)
+ 0x04, 0x00, // #
+ 0x1F, 0x80, // ######
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x38, 0x00, // ###
+ 0x1E, 0x00, // ####
+ 0x0F, 0x00, // ####
+ 0x03, 0x80, // ###
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x3F, 0x00, // ######
+ 0x04, 0x00, // #
+ 0x04, 0x00, // #
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @160 '%' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x18, 0x00, // ##
+ 0x24, 0x00, // # #
+ 0x24, 0x00, // # #
+ 0x18, 0xC0, // ## ##
+ 0x07, 0x80, // ####
+ 0x1E, 0x00, // ####
+ 0x31, 0x80, // ## ##
+ 0x02, 0x40, // # #
+ 0x02, 0x40, // # #
+ 0x01, 0x80, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @192 '&' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x0F, 0x00, // ####
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x1D, 0x80, // ### ##
+ 0x37, 0x00, // ## ###
+ 0x33, 0x00, // ## ##
+ 0x1D, 0x80, // ### ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @224 ''' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x07, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x02, 0x00, // #
+ 0x02, 0x00, // #
+ 0x02, 0x00, // #
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @256 '(' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x0E, 0x00, // ###
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0E, 0x00, // ###
+ 0x06, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @288 ')' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x1C, 0x00, // ###
+ 0x18, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @320 '*' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x3F, 0xC0, // ########
+ 0x3F, 0xC0, // ########
+ 0x0F, 0x00, // ####
+ 0x1F, 0x80, // ######
+ 0x19, 0x80, // ## ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @352 '+' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x04, 0x00, // #
+ 0x04, 0x00, // #
+ 0x04, 0x00, // #
+ 0x3F, 0x80, // #######
+ 0x04, 0x00, // #
+ 0x04, 0x00, // #
+ 0x04, 0x00, // #
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @384 ',' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x06, 0x00, // ##
+ 0x04, 0x00, // #
+ 0x0C, 0x00, // ##
+ 0x08, 0x00, // #
+ 0x08, 0x00, // #
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @416 '-' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3F, 0x80, // #######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @448 '.' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @480 '/' (11 pixels wide)
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @512 '0' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x0E, 0x00, // ###
+ 0x1B, 0x00, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x1B, 0x00, // ## ##
+ 0x0E, 0x00, // ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @544 '1' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x06, 0x00, // ##
+ 0x3E, 0x00, // #####
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x3F, 0xC0, // ########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @576 '2' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x0F, 0x00, // ####
+ 0x19, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x03, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x3F, 0x80, // #######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @608 '3' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x3F, 0x00, // ######
+ 0x61, 0x80, // ## ##
+ 0x01, 0x80, // ##
+ 0x03, 0x00, // ##
+ 0x1F, 0x00, // #####
+ 0x03, 0x80, // ###
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x61, 0x80, // ## ##
+ 0x3F, 0x00, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @640 '4' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x07, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x0F, 0x00, // ####
+ 0x0B, 0x00, // # ##
+ 0x1B, 0x00, // ## ##
+ 0x13, 0x00, // # ##
+ 0x33, 0x00, // ## ##
+ 0x3F, 0x80, // #######
+ 0x03, 0x00, // ##
+ 0x0F, 0x80, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @672 '5' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x1F, 0x80, // ######
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x1F, 0x00, // #####
+ 0x11, 0x80, // # ##
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x21, 0x80, // # ##
+ 0x1F, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @704 '6' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x07, 0x80, // ####
+ 0x1C, 0x00, // ###
+ 0x18, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x37, 0x00, // ## ###
+ 0x39, 0x80, // ### ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x19, 0x80, // ## ##
+ 0x0F, 0x00, // ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @736 '7' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x7F, 0x00, // #######
+ 0x43, 0x00, // # ##
+ 0x03, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @768 '8' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x1F, 0x00, // #####
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x1F, 0x00, // #####
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x1F, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @800 '9' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x1E, 0x00, // ####
+ 0x33, 0x00, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x33, 0x80, // ## ###
+ 0x1D, 0x80, // ### ##
+ 0x01, 0x80, // ##
+ 0x03, 0x00, // ##
+ 0x07, 0x00, // ###
+ 0x3C, 0x00, // ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @832 ':' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @864 ';' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x06, 0x00, // ##
+ 0x04, 0x00, // #
+ 0x08, 0x00, // #
+ 0x08, 0x00, // #
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @896 '<' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0xC0, // ##
+ 0x03, 0x00, // ##
+ 0x04, 0x00, // #
+ 0x18, 0x00, // ##
+ 0x60, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x04, 0x00, // #
+ 0x03, 0x00, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @928 '=' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7F, 0xC0, // #########
+ 0x00, 0x00, //
+ 0x7F, 0xC0, // #########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @960 '>' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x60, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x04, 0x00, // #
+ 0x03, 0x00, // ##
+ 0x00, 0xC0, // ##
+ 0x03, 0x00, // ##
+ 0x04, 0x00, // #
+ 0x18, 0x00, // ##
+ 0x60, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @992 '?' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0x00, // #####
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x01, 0x80, // ##
+ 0x07, 0x00, // ###
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x00, 0x00, //
+ 0x0C, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1024 '@' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x0E, 0x00, // ###
+ 0x11, 0x00, // # #
+ 0x21, 0x00, // # #
+ 0x21, 0x00, // # #
+ 0x27, 0x00, // # ###
+ 0x29, 0x00, // # # #
+ 0x29, 0x00, // # # #
+ 0x27, 0x00, // # ###
+ 0x20, 0x00, // #
+ 0x11, 0x00, // # #
+ 0x0E, 0x00, // ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1056 'A' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3F, 0x00, // ######
+ 0x0F, 0x00, // ####
+ 0x09, 0x00, // # #
+ 0x19, 0x80, // ## ##
+ 0x19, 0x80, // ## ##
+ 0x1F, 0x80, // ######
+ 0x30, 0xC0, // ## ##
+ 0x30, 0xC0, // ## ##
+ 0x79, 0xE0, // #### ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1088 'B' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7F, 0x00, // #######
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x3F, 0x00, // ######
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x7F, 0x00, // #######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1120 'C' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0x40, // ##### #
+ 0x30, 0xC0, // ## ##
+ 0x60, 0x40, // ## #
+ 0x60, 0x00, // ##
+ 0x60, 0x00, // ##
+ 0x60, 0x00, // ##
+ 0x60, 0x40, // ## #
+ 0x30, 0x80, // ## #
+ 0x1F, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1152 'D' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7F, 0x00, // #######
+ 0x31, 0x80, // ## ##
+ 0x30, 0xC0, // ## ##
+ 0x30, 0xC0, // ## ##
+ 0x30, 0xC0, // ## ##
+ 0x30, 0xC0, // ## ##
+ 0x30, 0xC0, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x7F, 0x00, // #######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1184 'E' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7F, 0x80, // ########
+ 0x30, 0x80, // ## #
+ 0x30, 0x80, // ## #
+ 0x32, 0x00, // ## #
+ 0x3E, 0x00, // #####
+ 0x32, 0x00, // ## #
+ 0x30, 0x80, // ## #
+ 0x30, 0x80, // ## #
+ 0x7F, 0x80, // ########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1216 'F' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7F, 0xC0, // #########
+ 0x30, 0x40, // ## #
+ 0x30, 0x40, // ## #
+ 0x32, 0x00, // ## #
+ 0x3E, 0x00, // #####
+ 0x32, 0x00, // ## #
+ 0x30, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x7C, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1248 'G' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1E, 0x80, // #### #
+ 0x31, 0x80, // ## ##
+ 0x60, 0x80, // ## #
+ 0x60, 0x00, // ##
+ 0x60, 0x00, // ##
+ 0x67, 0xC0, // ## #####
+ 0x61, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x1F, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1280 'H' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7B, 0xC0, // #### ####
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x3F, 0x80, // #######
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x7B, 0xC0, // #### ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1312 'I' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3F, 0xC0, // ########
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x3F, 0xC0, // ########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1344 'J' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0xC0, // #######
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x63, 0x00, // ## ##
+ 0x63, 0x00, // ## ##
+ 0x63, 0x00, // ## ##
+ 0x3E, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1376 'K' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7B, 0xC0, // #### ####
+ 0x31, 0x80, // ## ##
+ 0x33, 0x00, // ## ##
+ 0x36, 0x00, // ## ##
+ 0x3C, 0x00, // ####
+ 0x3E, 0x00, // #####
+ 0x33, 0x00, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x79, 0xC0, // #### ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1408 'L' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7E, 0x00, // ######
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x18, 0x40, // ## #
+ 0x18, 0x40, // ## #
+ 0x18, 0x40, // ## #
+ 0x7F, 0xC0, // #########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1440 'M' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0xE0, 0xE0, // ### ###
+ 0x60, 0xC0, // ## ##
+ 0x71, 0xC0, // ### ###
+ 0x7B, 0xC0, // #### ####
+ 0x6A, 0xC0, // ## # # ##
+ 0x6E, 0xC0, // ## ### ##
+ 0x64, 0xC0, // ## # ##
+ 0x60, 0xC0, // ## ##
+ 0xFB, 0xE0, // ##### #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1472 'N' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x73, 0xC0, // ### ####
+ 0x31, 0x80, // ## ##
+ 0x39, 0x80, // ### ##
+ 0x3D, 0x80, // #### ##
+ 0x35, 0x80, // ## # ##
+ 0x37, 0x80, // ## ####
+ 0x33, 0x80, // ## ###
+ 0x31, 0x80, // ## ##
+ 0x79, 0x80, // #### ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1504 'O' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0x00, // #####
+ 0x31, 0x80, // ## ##
+ 0x60, 0xC0, // ## ##
+ 0x60, 0xC0, // ## ##
+ 0x60, 0xC0, // ## ##
+ 0x60, 0xC0, // ## ##
+ 0x60, 0xC0, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x1F, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1536 'P' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7F, 0x00, // #######
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x3F, 0x00, // ######
+ 0x30, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x7E, 0x00, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1568 'Q' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0x00, // #####
+ 0x31, 0x80, // ## ##
+ 0x60, 0xC0, // ## ##
+ 0x60, 0xC0, // ## ##
+ 0x60, 0xC0, // ## ##
+ 0x60, 0xC0, // ## ##
+ 0x60, 0xC0, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x1F, 0x00, // #####
+ 0x0C, 0xC0, // ## ##
+ 0x1F, 0x80, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1600 'R' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7F, 0x00, // #######
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x3E, 0x00, // #####
+ 0x33, 0x00, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x7C, 0xE0, // ##### ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1632 'S' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0x80, // ######
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x38, 0x00, // ###
+ 0x1F, 0x00, // #####
+ 0x03, 0x80, // ###
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x3F, 0x00, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1664 'T' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7F, 0x80, // ########
+ 0x4C, 0x80, // # ## #
+ 0x4C, 0x80, // # ## #
+ 0x4C, 0x80, // # ## #
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x3F, 0x00, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1696 'U' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7B, 0xC0, // #### ####
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x1F, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1728 'V' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7B, 0xC0, // #### ####
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x1B, 0x00, // ## ##
+ 0x1B, 0x00, // ## ##
+ 0x1B, 0x00, // ## ##
+ 0x0A, 0x00, // # #
+ 0x0E, 0x00, // ###
+ 0x0E, 0x00, // ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1760 'W' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0xFB, 0xE0, // ##### #####
+ 0x60, 0xC0, // ## ##
+ 0x64, 0xC0, // ## # ##
+ 0x6E, 0xC0, // ## ### ##
+ 0x6E, 0xC0, // ## ### ##
+ 0x2A, 0x80, // # # # #
+ 0x3B, 0x80, // ### ###
+ 0x3B, 0x80, // ### ###
+ 0x31, 0x80, // ## ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1792 'X' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7B, 0xC0, // #### ####
+ 0x31, 0x80, // ## ##
+ 0x1B, 0x00, // ## ##
+ 0x0E, 0x00, // ###
+ 0x0E, 0x00, // ###
+ 0x0E, 0x00, // ###
+ 0x1B, 0x00, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x7B, 0xC0, // #### ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1824 'Y' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x79, 0xE0, // #### ####
+ 0x30, 0xC0, // ## ##
+ 0x19, 0x80, // ## ##
+ 0x0F, 0x00, // ####
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x1F, 0x80, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1856 'Z' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3F, 0x80, // #######
+ 0x21, 0x80, // # ##
+ 0x23, 0x00, // # ##
+ 0x06, 0x00, // ##
+ 0x04, 0x00, // #
+ 0x0C, 0x00, // ##
+ 0x18, 0x80, // ## #
+ 0x30, 0x80, // ## #
+ 0x3F, 0x80, // #######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1888 '[' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x07, 0x80, // ####
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x07, 0x80, // ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1920 '\' (11 pixels wide)
+ 0x30, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1952 ']' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x1E, 0x00, // ####
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x1E, 0x00, // ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1984 '^' (11 pixels wide)
+ 0x04, 0x00, // #
+ 0x0A, 0x00, // # #
+ 0x0A, 0x00, // # #
+ 0x11, 0x00, // # #
+ 0x20, 0x80, // # #
+ 0x20, 0x80, // # #
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2016 '_' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0xFF, 0xE0, // ###########
+
+ // @2048 '`' (11 pixels wide)
+ 0x08, 0x00, // #
+ 0x04, 0x00, // #
+ 0x02, 0x00, // #
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2080 'a' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0x00, // #####
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x1F, 0x80, // ######
+ 0x31, 0x80, // ## ##
+ 0x33, 0x80, // ## ###
+ 0x1D, 0xC0, // ### ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2112 'b' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x70, 0x00, // ###
+ 0x30, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x37, 0x00, // ## ###
+ 0x39, 0x80, // ### ##
+ 0x30, 0xC0, // ## ##
+ 0x30, 0xC0, // ## ##
+ 0x30, 0xC0, // ## ##
+ 0x39, 0x80, // ### ##
+ 0x77, 0x00, // ### ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2144 'c' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1E, 0x80, // #### #
+ 0x31, 0x80, // ## ##
+ 0x60, 0x80, // ## #
+ 0x60, 0x00, // ##
+ 0x60, 0x80, // ## #
+ 0x31, 0x80, // ## ##
+ 0x1F, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2176 'd' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x03, 0x80, // ###
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x1D, 0x80, // ### ##
+ 0x33, 0x80, // ## ###
+ 0x61, 0x80, // ## ##
+ 0x61, 0x80, // ## ##
+ 0x61, 0x80, // ## ##
+ 0x33, 0x80, // ## ###
+ 0x1D, 0xC0, // ### ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2208 'e' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0x00, // #####
+ 0x31, 0x80, // ## ##
+ 0x60, 0xC0, // ## ##
+ 0x7F, 0xC0, // #########
+ 0x60, 0x00, // ##
+ 0x30, 0xC0, // ## ##
+ 0x1F, 0x80, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2240 'f' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x07, 0xE0, // ######
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x3F, 0x80, // #######
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x3F, 0x80, // #######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2272 'g' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1D, 0xC0, // ### ###
+ 0x33, 0x80, // ## ###
+ 0x61, 0x80, // ## ##
+ 0x61, 0x80, // ## ##
+ 0x61, 0x80, // ## ##
+ 0x33, 0x80, // ## ###
+ 0x1D, 0x80, // ### ##
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x1F, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2304 'h' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x70, 0x00, // ###
+ 0x30, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x37, 0x00, // ## ###
+ 0x39, 0x80, // ### ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x7B, 0xC0, // #### ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2336 'i' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x00, 0x00, //
+ 0x1E, 0x00, // ####
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x3F, 0xC0, // ########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2368 'j' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x00, 0x00, //
+ 0x3F, 0x00, // ######
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x3E, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2400 'k' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x70, 0x00, // ###
+ 0x30, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x37, 0x80, // ## ####
+ 0x36, 0x00, // ## ##
+ 0x3C, 0x00, // ####
+ 0x3C, 0x00, // ####
+ 0x36, 0x00, // ## ##
+ 0x33, 0x00, // ## ##
+ 0x77, 0xC0, // ### #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2432 'l' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x1E, 0x00, // ####
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x3F, 0xC0, // ########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2464 'm' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7F, 0x80, // ########
+ 0x36, 0xC0, // ## ## ##
+ 0x36, 0xC0, // ## ## ##
+ 0x36, 0xC0, // ## ## ##
+ 0x36, 0xC0, // ## ## ##
+ 0x36, 0xC0, // ## ## ##
+ 0x76, 0xE0, // ### ## ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2496 'n' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x77, 0x00, // ### ###
+ 0x39, 0x80, // ### ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x7B, 0xC0, // #### ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2528 'o' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0x00, // #####
+ 0x31, 0x80, // ## ##
+ 0x60, 0xC0, // ## ##
+ 0x60, 0xC0, // ## ##
+ 0x60, 0xC0, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x1F, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2560 'p' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x77, 0x00, // ### ###
+ 0x39, 0x80, // ### ##
+ 0x30, 0xC0, // ## ##
+ 0x30, 0xC0, // ## ##
+ 0x30, 0xC0, // ## ##
+ 0x39, 0x80, // ### ##
+ 0x37, 0x00, // ## ###
+ 0x30, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x7C, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2592 'q' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1D, 0xC0, // ### ###
+ 0x33, 0x80, // ## ###
+ 0x61, 0x80, // ## ##
+ 0x61, 0x80, // ## ##
+ 0x61, 0x80, // ## ##
+ 0x33, 0x80, // ## ###
+ 0x1D, 0x80, // ### ##
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x07, 0xC0, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2624 'r' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7B, 0x80, // #### ###
+ 0x1C, 0xC0, // ### ##
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x7F, 0x00, // #######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2656 's' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0x80, // ######
+ 0x31, 0x80, // ## ##
+ 0x3C, 0x00, // ####
+ 0x1F, 0x00, // #####
+ 0x03, 0x80, // ###
+ 0x31, 0x80, // ## ##
+ 0x3F, 0x00, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2688 't' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x7F, 0x00, // #######
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x18, 0x80, // ## #
+ 0x0F, 0x00, // ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2720 'u' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x73, 0x80, // ### ###
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x33, 0x80, // ## ###
+ 0x1D, 0xC0, // ### ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2752 'v' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7B, 0xC0, // #### ####
+ 0x31, 0x80, // ## ##
+ 0x31, 0x80, // ## ##
+ 0x1B, 0x00, // ## ##
+ 0x1B, 0x00, // ## ##
+ 0x0E, 0x00, // ###
+ 0x0E, 0x00, // ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2784 'w' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0xF1, 0xE0, // #### ####
+ 0x60, 0xC0, // ## ##
+ 0x64, 0xC0, // ## # ##
+ 0x6E, 0xC0, // ## ### ##
+ 0x3B, 0x80, // ### ###
+ 0x3B, 0x80, // ### ###
+ 0x31, 0x80, // ## ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2816 'x' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7B, 0xC0, // #### ####
+ 0x1B, 0x00, // ## ##
+ 0x0E, 0x00, // ###
+ 0x0E, 0x00, // ###
+ 0x0E, 0x00, // ###
+ 0x1B, 0x00, // ## ##
+ 0x7B, 0xC0, // #### ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2848 'y' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x79, 0xE0, // #### ####
+ 0x30, 0xC0, // ## ##
+ 0x19, 0x80, // ## ##
+ 0x19, 0x80, // ## ##
+ 0x0B, 0x00, // # ##
+ 0x0F, 0x00, // ####
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x3E, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2880 'z' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3F, 0x80, // #######
+ 0x21, 0x80, // # ##
+ 0x03, 0x00, // ##
+ 0x0E, 0x00, // ###
+ 0x18, 0x00, // ##
+ 0x30, 0x80, // ## #
+ 0x3F, 0x80, // #######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2912 '{' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x06, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2944 '|' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2976 '}' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x0C, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3008 '~' (11 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x18, 0x00, // ##
+ 0x24, 0x80, // # # #
+ 0x03, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+};
+
+sFONT Font16 = {
+ Font16_Table,
+ 11, /* Width */
+ 16, /* Height */
+};
+
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Function_Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Utilities/Fonts/font20.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,2223 @@
+/**
+ ******************************************************************************
+ * @file font20.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 18-February-2014
+ * @brief This file provides text font20 for STM32xx-EVAL's LCD driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "fonts.h"
+
+/** @addtogroup Utilities
+ * @{
+ */
+
+/** @addtogroup STM32_EVAL
+ * @{
+ */
+
+/** @addtogroup Common
+ * @{
+ */
+
+/** @addtogroup FONTS
+ * @brief This file provides text font20 for STM32xx-EVAL's LCD driver.
+ * @{
+ */
+
+/** @defgroup FONTS_Private_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Variables
+ * @{
+ */
+
+// Character bitmaps for Courier New 15pt
+const uint8_t Font20_Table[] =
+{
+ // @0 ' ' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @40 '!' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x07, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x02, 0x00, // #
+ 0x02, 0x00, // #
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x07, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @80 '"' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1C, 0xE0, // ### ###
+ 0x1C, 0xE0, // ### ###
+ 0x1C, 0xE0, // ### ###
+ 0x08, 0x40, // # #
+ 0x08, 0x40, // # #
+ 0x08, 0x40, // # #
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @120 '#' (14 pixels wide)
+ 0x0C, 0xC0, // ## ##
+ 0x0C, 0xC0, // ## ##
+ 0x0C, 0xC0, // ## ##
+ 0x0C, 0xC0, // ## ##
+ 0x0C, 0xC0, // ## ##
+ 0x3F, 0xF0, // ##########
+ 0x3F, 0xF0, // ##########
+ 0x0C, 0xC0, // ## ##
+ 0x0C, 0xC0, // ## ##
+ 0x3F, 0xF0, // ##########
+ 0x3F, 0xF0, // ##########
+ 0x0C, 0xC0, // ## ##
+ 0x0C, 0xC0, // ## ##
+ 0x0C, 0xC0, // ## ##
+ 0x0C, 0xC0, // ## ##
+ 0x0C, 0xC0, // ## ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @160 '$' (14 pixels wide)
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x07, 0xE0, // ######
+ 0x0F, 0xE0, // #######
+ 0x18, 0x60, // ## ##
+ 0x18, 0x00, // ##
+ 0x1F, 0x00, // #####
+ 0x0F, 0xC0, // ######
+ 0x00, 0xE0, // ###
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x1F, 0xC0, // #######
+ 0x1F, 0x80, // ######
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @200 '%' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x1C, 0x00, // ###
+ 0x22, 0x00, // # #
+ 0x22, 0x00, // # #
+ 0x22, 0x00, // # #
+ 0x1C, 0x60, // ### ##
+ 0x01, 0xE0, // ####
+ 0x0F, 0x80, // #####
+ 0x3C, 0x00, // ####
+ 0x31, 0xC0, // ## ###
+ 0x02, 0x20, // # #
+ 0x02, 0x20, // # #
+ 0x02, 0x20, // # #
+ 0x01, 0xC0, // ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @240 '&' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x03, 0xE0, // #####
+ 0x0F, 0xE0, // #######
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x0F, 0x30, // #### ##
+ 0x1F, 0xF0, // #########
+ 0x19, 0xE0, // ## ####
+ 0x18, 0xC0, // ## ##
+ 0x1F, 0xF0, // #########
+ 0x07, 0xB0, // #### ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @280 ''' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x03, 0x80, // ###
+ 0x03, 0x80, // ###
+ 0x03, 0x80, // ###
+ 0x01, 0x00, // #
+ 0x01, 0x00, // #
+ 0x01, 0x00, // #
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @320 '(' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @360 ')' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @400 '*' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x1B, 0x60, // ## ## ##
+ 0x1F, 0xE0, // ########
+ 0x07, 0x80, // ####
+ 0x07, 0x80, // ####
+ 0x0F, 0xC0, // ######
+ 0x0C, 0xC0, // ## ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @440 '+' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x3F, 0xF0, // ##########
+ 0x3F, 0xF0, // ##########
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @480 ',' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x03, 0x80, // ###
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x04, 0x00, // #
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @520 '-' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3F, 0xE0, // #########
+ 0x3F, 0xE0, // #########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @560 '.' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x03, 0x80, // ###
+ 0x03, 0x80, // ###
+ 0x03, 0x80, // ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @600 '/' (14 pixels wide)
+ 0x00, 0x60, // ##
+ 0x00, 0x60, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @640 '0' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x0F, 0x80, // #####
+ 0x1F, 0xC0, // #######
+ 0x18, 0xC0, // ## ##
+ 0x30, 0x60, // ## ##
+ 0x30, 0x60, // ## ##
+ 0x30, 0x60, // ## ##
+ 0x30, 0x60, // ## ##
+ 0x30, 0x60, // ## ##
+ 0x30, 0x60, // ## ##
+ 0x30, 0x60, // ## ##
+ 0x18, 0xC0, // ## ##
+ 0x1F, 0xC0, // #######
+ 0x0F, 0x80, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @680 '1' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x03, 0x00, // ##
+ 0x1F, 0x00, // #####
+ 0x1F, 0x00, // #####
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x1F, 0xE0, // ########
+ 0x1F, 0xE0, // ########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @720 '2' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x0F, 0x80, // #####
+ 0x1F, 0xC0, // #######
+ 0x38, 0xE0, // ### ###
+ 0x30, 0x60, // ## ##
+ 0x00, 0x60, // ##
+ 0x00, 0xC0, // ##
+ 0x01, 0x80, // ##
+ 0x03, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x3F, 0xE0, // #########
+ 0x3F, 0xE0, // #########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @760 '3' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x0F, 0x80, // #####
+ 0x3F, 0xC0, // ########
+ 0x30, 0xE0, // ## ###
+ 0x00, 0x60, // ##
+ 0x00, 0xE0, // ###
+ 0x07, 0xC0, // #####
+ 0x07, 0xC0, // #####
+ 0x00, 0xE0, // ###
+ 0x00, 0x60, // ##
+ 0x00, 0x60, // ##
+ 0x60, 0xE0, // ## ###
+ 0x7F, 0xC0, // #########
+ 0x3F, 0x80, // #######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @800 '4' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x01, 0xC0, // ###
+ 0x03, 0xC0, // ####
+ 0x03, 0xC0, // ####
+ 0x06, 0xC0, // ## ##
+ 0x0C, 0xC0, // ## ##
+ 0x0C, 0xC0, // ## ##
+ 0x18, 0xC0, // ## ##
+ 0x30, 0xC0, // ## ##
+ 0x3F, 0xE0, // #########
+ 0x3F, 0xE0, // #########
+ 0x00, 0xC0, // ##
+ 0x03, 0xE0, // #####
+ 0x03, 0xE0, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @840 '5' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x1F, 0xC0, // #######
+ 0x1F, 0xC0, // #######
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x1F, 0x80, // ######
+ 0x1F, 0xC0, // #######
+ 0x18, 0xE0, // ## ###
+ 0x00, 0x60, // ##
+ 0x00, 0x60, // ##
+ 0x00, 0x60, // ##
+ 0x30, 0xE0, // ## ###
+ 0x3F, 0xC0, // ########
+ 0x1F, 0x80, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @880 '6' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x03, 0xE0, // #####
+ 0x0F, 0xE0, // #######
+ 0x1E, 0x00, // ####
+ 0x18, 0x00, // ##
+ 0x38, 0x00, // ###
+ 0x37, 0x80, // ## ####
+ 0x3F, 0xC0, // ########
+ 0x38, 0xE0, // ### ###
+ 0x30, 0x60, // ## ##
+ 0x30, 0x60, // ## ##
+ 0x18, 0xE0, // ## ###
+ 0x1F, 0xC0, // #######
+ 0x07, 0x80, // ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @920 '7' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x3F, 0xE0, // #########
+ 0x3F, 0xE0, // #########
+ 0x30, 0x60, // ## ##
+ 0x00, 0x60, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @960 '8' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x0F, 0x80, // #####
+ 0x1F, 0xC0, // #######
+ 0x38, 0xE0, // ### ###
+ 0x30, 0x60, // ## ##
+ 0x38, 0xE0, // ### ###
+ 0x1F, 0xC0, // #######
+ 0x1F, 0xC0, // #######
+ 0x38, 0xE0, // ### ###
+ 0x30, 0x60, // ## ##
+ 0x30, 0x60, // ## ##
+ 0x38, 0xE0, // ### ###
+ 0x1F, 0xC0, // #######
+ 0x0F, 0x80, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1000 '9' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x0F, 0x00, // ####
+ 0x1F, 0xC0, // #######
+ 0x38, 0xC0, // ### ##
+ 0x30, 0x60, // ## ##
+ 0x30, 0x60, // ## ##
+ 0x38, 0xE0, // ### ###
+ 0x1F, 0xE0, // ########
+ 0x0F, 0x60, // #### ##
+ 0x00, 0xE0, // ###
+ 0x00, 0xC0, // ##
+ 0x03, 0xC0, // ####
+ 0x3F, 0x80, // #######
+ 0x3E, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1040 ':' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x03, 0x80, // ###
+ 0x03, 0x80, // ###
+ 0x03, 0x80, // ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x03, 0x80, // ###
+ 0x03, 0x80, // ###
+ 0x03, 0x80, // ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1080 ';' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x01, 0xC0, // ###
+ 0x01, 0xC0, // ###
+ 0x01, 0xC0, // ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x03, 0x80, // ###
+ 0x03, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x04, 0x00, // #
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1120 '<' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x30, // ##
+ 0x00, 0xF0, // ####
+ 0x03, 0xC0, // ####
+ 0x07, 0x00, // ###
+ 0x1C, 0x00, // ###
+ 0x78, 0x00, // ####
+ 0x1C, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x03, 0xC0, // ####
+ 0x00, 0xF0, // ####
+ 0x00, 0x30, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1160 '=' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7F, 0xF0, // ###########
+ 0x7F, 0xF0, // ###########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7F, 0xF0, // ###########
+ 0x7F, 0xF0, // ###########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1200 '>' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x30, 0x00, // ##
+ 0x3C, 0x00, // ####
+ 0x0F, 0x00, // ####
+ 0x03, 0x80, // ###
+ 0x00, 0xE0, // ###
+ 0x00, 0x78, // ####
+ 0x00, 0xE0, // ###
+ 0x03, 0x80, // ###
+ 0x0F, 0x00, // ####
+ 0x3C, 0x00, // ####
+ 0x30, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1240 '?' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x0F, 0x80, // #####
+ 0x1F, 0xC0, // #######
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x00, 0x60, // ##
+ 0x01, 0xC0, // ###
+ 0x03, 0x80, // ###
+ 0x03, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x07, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1280 '@' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x03, 0x80, // ###
+ 0x0C, 0x80, // ## #
+ 0x08, 0x40, // # #
+ 0x10, 0x40, // # #
+ 0x10, 0x40, // # #
+ 0x11, 0xC0, // # ###
+ 0x12, 0x40, // # # #
+ 0x12, 0x40, // # # #
+ 0x12, 0x40, // # # #
+ 0x11, 0xC0, // # ###
+ 0x10, 0x00, // #
+ 0x08, 0x00, // #
+ 0x08, 0x40, // # #
+ 0x07, 0x80, // ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1320 'A' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0x80, // ######
+ 0x1F, 0x80, // ######
+ 0x03, 0x80, // ###
+ 0x06, 0xC0, // ## ##
+ 0x06, 0xC0, // ## ##
+ 0x0C, 0xC0, // ## ##
+ 0x0C, 0x60, // ## ##
+ 0x1F, 0xE0, // ########
+ 0x1F, 0xE0, // ########
+ 0x30, 0x30, // ## ##
+ 0x78, 0x78, // #### ####
+ 0x78, 0x78, // #### ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1360 'B' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3F, 0x80, // #######
+ 0x3F, 0xC0, // ########
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0xE0, // ## ###
+ 0x1F, 0xC0, // #######
+ 0x1F, 0xE0, // ########
+ 0x18, 0x70, // ## ###
+ 0x18, 0x30, // ## ##
+ 0x18, 0x30, // ## ##
+ 0x3F, 0xF0, // ##########
+ 0x3F, 0xE0, // #########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1400 'C' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x07, 0xB0, // #### ##
+ 0x0F, 0xF0, // ########
+ 0x1C, 0x70, // ### ###
+ 0x38, 0x30, // ### ##
+ 0x30, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x38, 0x30, // ### ##
+ 0x1C, 0x70, // ### ###
+ 0x0F, 0xE0, // #######
+ 0x07, 0xC0, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1440 'D' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7F, 0x80, // ########
+ 0x7F, 0xC0, // #########
+ 0x30, 0xE0, // ## ###
+ 0x30, 0x70, // ## ###
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x70, // ## ###
+ 0x30, 0xE0, // ## ###
+ 0x7F, 0xC0, // #########
+ 0x7F, 0x80, // ########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1480 'E' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3F, 0xF0, // ##########
+ 0x3F, 0xF0, // ##########
+ 0x18, 0x30, // ## ##
+ 0x18, 0x30, // ## ##
+ 0x19, 0x80, // ## ##
+ 0x1F, 0x80, // ######
+ 0x1F, 0x80, // ######
+ 0x19, 0x80, // ## ##
+ 0x18, 0x30, // ## ##
+ 0x18, 0x30, // ## ##
+ 0x3F, 0xF0, // ##########
+ 0x3F, 0xF0, // ##########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1520 'F' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3F, 0xF0, // ##########
+ 0x3F, 0xF0, // ##########
+ 0x18, 0x30, // ## ##
+ 0x18, 0x30, // ## ##
+ 0x19, 0x80, // ## ##
+ 0x1F, 0x80, // ######
+ 0x1F, 0x80, // ######
+ 0x19, 0x80, // ## ##
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x3F, 0x00, // ######
+ 0x3F, 0x00, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1560 'G' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x07, 0xB0, // #### ##
+ 0x1F, 0xF0, // #########
+ 0x18, 0x70, // ## ###
+ 0x30, 0x30, // ## ##
+ 0x30, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x31, 0xF8, // ## ######
+ 0x31, 0xF8, // ## ######
+ 0x30, 0x30, // ## ##
+ 0x18, 0x30, // ## ##
+ 0x1F, 0xF0, // #########
+ 0x07, 0xC0, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1600 'H' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3C, 0xF0, // #### ####
+ 0x3C, 0xF0, // #### ####
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x1F, 0xE0, // ########
+ 0x1F, 0xE0, // ########
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x3C, 0xF0, // #### ####
+ 0x3C, 0xF0, // #### ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1640 'I' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0xE0, // ########
+ 0x1F, 0xE0, // ########
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x1F, 0xE0, // ########
+ 0x1F, 0xE0, // ########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1680 'J' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x03, 0xF8, // #######
+ 0x03, 0xF8, // #######
+ 0x00, 0x60, // ##
+ 0x00, 0x60, // ##
+ 0x00, 0x60, // ##
+ 0x00, 0x60, // ##
+ 0x30, 0x60, // ## ##
+ 0x30, 0x60, // ## ##
+ 0x30, 0x60, // ## ##
+ 0x30, 0xE0, // ## ###
+ 0x3F, 0xC0, // ########
+ 0x0F, 0x80, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1720 'K' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3E, 0xF8, // ##### #####
+ 0x3E, 0xF8, // ##### #####
+ 0x18, 0xE0, // ## ###
+ 0x19, 0x80, // ## ##
+ 0x1B, 0x00, // ## ##
+ 0x1F, 0x00, // #####
+ 0x1D, 0x80, // ### ##
+ 0x18, 0xC0, // ## ##
+ 0x18, 0xC0, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x3E, 0x78, // ##### ####
+ 0x3E, 0x38, // ##### ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1760 'L' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3F, 0x00, // ######
+ 0x3F, 0x00, // ######
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x30, // ## ##
+ 0x0C, 0x30, // ## ##
+ 0x0C, 0x30, // ## ##
+ 0x3F, 0xF0, // ##########
+ 0x3F, 0xF0, // ##########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1800 'M' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x78, 0x78, // #### ####
+ 0x78, 0x78, // #### ####
+ 0x38, 0x70, // ### ###
+ 0x3C, 0xF0, // #### ####
+ 0x34, 0xB0, // ## # # ##
+ 0x37, 0xB0, // ## #### ##
+ 0x37, 0xB0, // ## #### ##
+ 0x33, 0x30, // ## ## ##
+ 0x33, 0x30, // ## ## ##
+ 0x30, 0x30, // ## ##
+ 0x7C, 0xF8, // ##### #####
+ 0x7C, 0xF8, // ##### #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1840 'N' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x39, 0xF0, // ### #####
+ 0x3D, 0xF0, // #### #####
+ 0x1C, 0x60, // ### ##
+ 0x1E, 0x60, // #### ##
+ 0x1E, 0x60, // #### ##
+ 0x1B, 0x60, // ## ## ##
+ 0x1B, 0x60, // ## ## ##
+ 0x19, 0xE0, // ## ####
+ 0x19, 0xE0, // ## ####
+ 0x18, 0xE0, // ## ###
+ 0x3E, 0xE0, // ##### ###
+ 0x3E, 0x60, // ##### ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1880 'O' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x07, 0x80, // ####
+ 0x0F, 0xC0, // ######
+ 0x1C, 0xE0, // ### ###
+ 0x38, 0x70, // ### ###
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x38, 0x70, // ### ###
+ 0x1C, 0xE0, // ### ###
+ 0x0F, 0xC0, // ######
+ 0x07, 0x80, // ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1920 'P' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3F, 0xC0, // ########
+ 0x3F, 0xE0, // #########
+ 0x18, 0x70, // ## ###
+ 0x18, 0x30, // ## ##
+ 0x18, 0x30, // ## ##
+ 0x18, 0x70, // ## ###
+ 0x1F, 0xE0, // ########
+ 0x1F, 0xC0, // #######
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x3F, 0x00, // ######
+ 0x3F, 0x00, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @1960 'Q' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x07, 0x80, // ####
+ 0x0F, 0xC0, // ######
+ 0x1C, 0xE0, // ### ###
+ 0x38, 0x70, // ### ###
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x38, 0x70, // ### ###
+ 0x1C, 0xE0, // ### ###
+ 0x0F, 0xC0, // ######
+ 0x07, 0x80, // ####
+ 0x07, 0xB0, // #### ##
+ 0x0F, 0xF0, // ########
+ 0x0C, 0xE0, // ## ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2000 'R' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3F, 0xC0, // ########
+ 0x3F, 0xE0, // #########
+ 0x18, 0x70, // ## ###
+ 0x18, 0x30, // ## ##
+ 0x18, 0x70, // ## ###
+ 0x1F, 0xE0, // ########
+ 0x1F, 0xC0, // #######
+ 0x18, 0xE0, // ## ###
+ 0x18, 0x60, // ## ##
+ 0x18, 0x70, // ## ###
+ 0x3E, 0x38, // ##### ###
+ 0x3E, 0x18, // ##### ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2040 'S' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x0F, 0xB0, // ##### ##
+ 0x1F, 0xF0, // #########
+ 0x38, 0x70, // ### ###
+ 0x30, 0x30, // ## ##
+ 0x38, 0x00, // ###
+ 0x1F, 0x80, // ######
+ 0x07, 0xE0, // ######
+ 0x00, 0x70, // ###
+ 0x30, 0x30, // ## ##
+ 0x38, 0x70, // ### ###
+ 0x3F, 0xE0, // #########
+ 0x37, 0xC0, // ## #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2080 'T' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3F, 0xF0, // ##########
+ 0x3F, 0xF0, // ##########
+ 0x33, 0x30, // ## ## ##
+ 0x33, 0x30, // ## ## ##
+ 0x33, 0x30, // ## ## ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x0F, 0xC0, // ######
+ 0x0F, 0xC0, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2120 'U' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3C, 0xF0, // #### ####
+ 0x3C, 0xF0, // #### ####
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x1C, 0xE0, // ### ###
+ 0x0F, 0xC0, // ######
+ 0x07, 0x80, // ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2160 'V' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x78, 0xF0, // #### ####
+ 0x78, 0xF0, // #### ####
+ 0x30, 0x60, // ## ##
+ 0x30, 0x60, // ## ##
+ 0x18, 0xC0, // ## ##
+ 0x18, 0xC0, // ## ##
+ 0x0D, 0x80, // ## ##
+ 0x0D, 0x80, // ## ##
+ 0x0D, 0x80, // ## ##
+ 0x07, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2200 'W' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7C, 0x7C, // ##### #####
+ 0x7C, 0x7C, // ##### #####
+ 0x30, 0x18, // ## ##
+ 0x33, 0x98, // ## ### ##
+ 0x33, 0x98, // ## ### ##
+ 0x33, 0x98, // ## ### ##
+ 0x36, 0xD8, // ## ## ## ##
+ 0x16, 0xD0, // # ## ## #
+ 0x1C, 0x70, // ### ###
+ 0x1C, 0x70, // ### ###
+ 0x1C, 0x70, // ### ###
+ 0x18, 0x30, // ## ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2240 'X' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x78, 0xF0, // #### ####
+ 0x78, 0xF0, // #### ####
+ 0x30, 0x60, // ## ##
+ 0x18, 0xC0, // ## ##
+ 0x0D, 0x80, // ## ##
+ 0x07, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x0D, 0x80, // ## ##
+ 0x18, 0xC0, // ## ##
+ 0x30, 0x60, // ## ##
+ 0x78, 0xF0, // #### ####
+ 0x78, 0xF0, // #### ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2280 'Y' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3C, 0xF0, // #### ####
+ 0x3C, 0xF0, // #### ####
+ 0x18, 0x60, // ## ##
+ 0x0C, 0xC0, // ## ##
+ 0x07, 0x80, // ####
+ 0x07, 0x80, // ####
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x0F, 0xC0, // ######
+ 0x0F, 0xC0, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2320 'Z' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0xE0, // ########
+ 0x1F, 0xE0, // ########
+ 0x18, 0x60, // ## ##
+ 0x18, 0xC0, // ## ##
+ 0x01, 0x80, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x0C, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x1F, 0xE0, // ########
+ 0x1F, 0xE0, // ########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2360 '[' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x03, 0xC0, // ####
+ 0x03, 0xC0, // ####
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0xC0, // ####
+ 0x03, 0xC0, // ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2400 '\' (14 pixels wide)
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x01, 0x80, // ##
+ 0x01, 0x80, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0x60, // ##
+ 0x00, 0x60, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2440 ']' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x0F, 0x00, // ####
+ 0x0F, 0x00, // ####
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x0F, 0x00, // ####
+ 0x0F, 0x00, // ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2480 '^' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x02, 0x00, // #
+ 0x07, 0x00, // ###
+ 0x0D, 0x80, // ## ##
+ 0x18, 0xC0, // ## ##
+ 0x30, 0x60, // ## ##
+ 0x20, 0x20, // # #
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2520 '_' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0xFF, 0xFC, // ##############
+ 0xFF, 0xFC, // ##############
+
+ // @2560 '`' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x04, 0x00, // #
+ 0x03, 0x00, // ##
+ 0x00, 0x80, // #
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2600 'a' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x0F, 0xC0, // ######
+ 0x1F, 0xE0, // ########
+ 0x00, 0x60, // ##
+ 0x0F, 0xE0, // #######
+ 0x1F, 0xE0, // ########
+ 0x38, 0x60, // ### ##
+ 0x30, 0xE0, // ## ###
+ 0x3F, 0xF0, // ##########
+ 0x1F, 0x70, // ##### ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2640 'b' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x70, 0x00, // ###
+ 0x70, 0x00, // ###
+ 0x30, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x37, 0x80, // ## ####
+ 0x3F, 0xE0, // #########
+ 0x38, 0x60, // ### ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x38, 0x60, // ### ##
+ 0x7F, 0xE0, // ##########
+ 0x77, 0x80, // ### ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2680 'c' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x07, 0xB0, // #### ##
+ 0x1F, 0xF0, // #########
+ 0x18, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x38, 0x30, // ### ##
+ 0x1F, 0xF0, // #########
+ 0x0F, 0xC0, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2720 'd' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x70, // ###
+ 0x00, 0x70, // ###
+ 0x00, 0x30, // ##
+ 0x00, 0x30, // ##
+ 0x07, 0xB0, // #### ##
+ 0x1F, 0xF0, // #########
+ 0x18, 0x70, // ## ###
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x38, 0x70, // ### ###
+ 0x1F, 0xF8, // ##########
+ 0x07, 0xB8, // #### ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2760 'e' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x07, 0x80, // ####
+ 0x1F, 0xE0, // ########
+ 0x18, 0x60, // ## ##
+ 0x3F, 0xF0, // ##########
+ 0x3F, 0xF0, // ##########
+ 0x30, 0x00, // ##
+ 0x18, 0x30, // ## ##
+ 0x1F, 0xF0, // #########
+ 0x07, 0xC0, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2800 'f' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x03, 0xF0, // ######
+ 0x07, 0xF0, // #######
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x1F, 0xE0, // ########
+ 0x1F, 0xE0, // ########
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x1F, 0xE0, // ########
+ 0x1F, 0xE0, // ########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2840 'g' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x07, 0xB8, // #### ###
+ 0x1F, 0xF8, // ##########
+ 0x18, 0x70, // ## ###
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x18, 0x70, // ## ###
+ 0x1F, 0xF0, // #########
+ 0x07, 0xB0, // #### ##
+ 0x00, 0x30, // ##
+ 0x00, 0x70, // ###
+ 0x0F, 0xE0, // #######
+ 0x0F, 0xC0, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2880 'h' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x38, 0x00, // ###
+ 0x38, 0x00, // ###
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x1B, 0xC0, // ## ####
+ 0x1F, 0xE0, // ########
+ 0x1C, 0x60, // ### ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x3C, 0xF0, // #### ####
+ 0x3C, 0xF0, // #### ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2920 'i' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0x00, // #####
+ 0x1F, 0x00, // #####
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x1F, 0xE0, // ########
+ 0x1F, 0xE0, // ########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @2960 'j' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0xC0, // #######
+ 0x1F, 0xC0, // #######
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x00, 0xC0, // ##
+ 0x01, 0xC0, // ###
+ 0x3F, 0x80, // #######
+ 0x3F, 0x00, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3000 'k' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x38, 0x00, // ###
+ 0x38, 0x00, // ###
+ 0x18, 0x00, // ##
+ 0x18, 0x00, // ##
+ 0x1B, 0xE0, // ## #####
+ 0x1B, 0xE0, // ## #####
+ 0x1B, 0x00, // ## ##
+ 0x1E, 0x00, // ####
+ 0x1E, 0x00, // ####
+ 0x1B, 0x00, // ## ##
+ 0x19, 0x80, // ## ##
+ 0x39, 0xF0, // ### #####
+ 0x39, 0xF0, // ### #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3040 'l' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x1F, 0x00, // #####
+ 0x1F, 0x00, // #####
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x1F, 0xE0, // ########
+ 0x1F, 0xE0, // ########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3080 'm' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x7E, 0xE0, // ###### ###
+ 0x7F, 0xF0, // ###########
+ 0x33, 0x30, // ## ## ##
+ 0x33, 0x30, // ## ## ##
+ 0x33, 0x30, // ## ## ##
+ 0x33, 0x30, // ## ## ##
+ 0x33, 0x30, // ## ## ##
+ 0x7B, 0xB8, // #### ### ###
+ 0x7B, 0xB8, // #### ### ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3120 'n' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3B, 0xC0, // ### ####
+ 0x3F, 0xE0, // #########
+ 0x1C, 0x60, // ### ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x3C, 0xF0, // #### ####
+ 0x3C, 0xF0, // #### ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3160 'o' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x07, 0x80, // ####
+ 0x1F, 0xE0, // ########
+ 0x18, 0x60, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x1F, 0xE0, // ########
+ 0x07, 0x80, // ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3200 'p' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x77, 0x80, // ### ####
+ 0x7F, 0xE0, // ##########
+ 0x38, 0x60, // ### ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x38, 0x60, // ### ##
+ 0x3F, 0xE0, // #########
+ 0x37, 0x80, // ## ####
+ 0x30, 0x00, // ##
+ 0x30, 0x00, // ##
+ 0x7C, 0x00, // #####
+ 0x7C, 0x00, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3240 'q' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x07, 0xB8, // #### ###
+ 0x1F, 0xF8, // ##########
+ 0x18, 0x70, // ## ###
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x30, 0x30, // ## ##
+ 0x18, 0x70, // ## ###
+ 0x1F, 0xF0, // #########
+ 0x07, 0xB0, // #### ##
+ 0x00, 0x30, // ##
+ 0x00, 0x30, // ##
+ 0x00, 0xF8, // #####
+ 0x00, 0xF8, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3280 'r' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3C, 0xE0, // #### ###
+ 0x3D, 0xF0, // #### #####
+ 0x0F, 0x30, // #### ##
+ 0x0E, 0x00, // ###
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x3F, 0xC0, // ########
+ 0x3F, 0xC0, // ########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3320 's' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x07, 0xE0, // ######
+ 0x1F, 0xE0, // ########
+ 0x18, 0x60, // ## ##
+ 0x1E, 0x00, // ####
+ 0x0F, 0xC0, // ######
+ 0x01, 0xE0, // ####
+ 0x18, 0x60, // ## ##
+ 0x1F, 0xE0, // ########
+ 0x1F, 0x80, // ######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3360 't' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x3F, 0xE0, // #########
+ 0x3F, 0xE0, // #########
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x0C, 0x30, // ## ##
+ 0x0F, 0xF0, // ########
+ 0x07, 0xC0, // #####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3400 'u' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x38, 0xE0, // ### ###
+ 0x38, 0xE0, // ### ###
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0x60, // ## ##
+ 0x18, 0xE0, // ## ###
+ 0x1F, 0xF0, // #########
+ 0x0F, 0x70, // #### ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3440 'v' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x78, 0xF0, // #### ####
+ 0x78, 0xF0, // #### ####
+ 0x30, 0x60, // ## ##
+ 0x18, 0xC0, // ## ##
+ 0x18, 0xC0, // ## ##
+ 0x0D, 0x80, // ## ##
+ 0x0D, 0x80, // ## ##
+ 0x07, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3480 'w' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x78, 0xF0, // #### ####
+ 0x78, 0xF0, // #### ####
+ 0x32, 0x60, // ## # ##
+ 0x32, 0x60, // ## # ##
+ 0x37, 0xE0, // ## ######
+ 0x1D, 0xC0, // ### ###
+ 0x1D, 0xC0, // ### ###
+ 0x18, 0xC0, // ## ##
+ 0x18, 0xC0, // ## ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3520 'x' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x3C, 0xF0, // #### ####
+ 0x3C, 0xF0, // #### ####
+ 0x0C, 0xC0, // ## ##
+ 0x07, 0x80, // ####
+ 0x03, 0x00, // ##
+ 0x07, 0x80, // ####
+ 0x0C, 0xC0, // ## ##
+ 0x3C, 0xF0, // #### ####
+ 0x3C, 0xF0, // #### ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3560 'y' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x78, 0xF0, // #### ####
+ 0x78, 0xF0, // #### ####
+ 0x30, 0x60, // ## ##
+ 0x18, 0xC0, // ## ##
+ 0x18, 0xC0, // ## ##
+ 0x0D, 0x80, // ## ##
+ 0x0F, 0x80, // #####
+ 0x07, 0x00, // ###
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x0C, 0x00, // ##
+ 0x7F, 0x00, // #######
+ 0x7F, 0x00, // #######
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3600 'z' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x1F, 0xE0, // ########
+ 0x1F, 0xE0, // ########
+ 0x18, 0xC0, // ## ##
+ 0x01, 0x80, // ##
+ 0x03, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x0C, 0x60, // ## ##
+ 0x1F, 0xE0, // ########
+ 0x1F, 0xE0, // ########
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3640 '{' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x01, 0xC0, // ###
+ 0x03, 0xC0, // ####
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x07, 0x00, // ###
+ 0x0E, 0x00, // ###
+ 0x07, 0x00, // ###
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0xC0, // ####
+ 0x01, 0xC0, // ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3680 '|' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x03, 0x00, // ##
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3720 '}' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x1C, 0x00, // ###
+ 0x1E, 0x00, // ####
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x07, 0x00, // ###
+ 0x03, 0x80, // ###
+ 0x07, 0x00, // ###
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x06, 0x00, // ##
+ 0x1E, 0x00, // ####
+ 0x1C, 0x00, // ###
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // @3760 '~' (14 pixels wide)
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x0E, 0x00, // ###
+ 0x3F, 0x30, // ###### ##
+ 0x33, 0xF0, // ## ######
+ 0x01, 0xE0, // ####
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+};
+
+
+sFONT Font20 = {
+ Font20_Table,
+ 14, /* Width */
+ 20, /* Height */
+};
+
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Function_Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Utilities/Fonts/font24.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,2600 @@
+/**
+ ******************************************************************************
+ * @file font24.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 18-February-2014
+ * @brief This file provides text font24 for STM32xx-EVAL's LCD driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "fonts.h"
+
+/** @addtogroup Utilities
+ * @{
+ */
+
+/** @addtogroup STM32_EVAL
+ * @{
+ */
+
+/** @addtogroup Common
+ * @{
+ */
+
+/** @addtogroup FONTS
+ * @brief This file provides text font24 for STM32xx-EVAL's LCD driver.
+ * @{
+ */
+
+/** @defgroup FONTS_Private_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Variables
+ * @{
+ */
+const uint8_t Font24_Table [] =
+{
+ // @0 ' ' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @72 '!' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x01, 0x00, 0x00, // #
+ 0x01, 0x00, 0x00, // #
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @144 '"' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x0E, 0x70, 0x00, // ### ###
+ 0x0E, 0x70, 0x00, // ### ###
+ 0x0E, 0x70, 0x00, // ### ###
+ 0x04, 0x20, 0x00, // # #
+ 0x04, 0x20, 0x00, // # #
+ 0x04, 0x20, 0x00, // # #
+ 0x04, 0x20, 0x00, // # #
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @216 '#' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x06, 0x60, 0x00, // ## ##
+ 0x06, 0x60, 0x00, // ## ##
+ 0x06, 0x60, 0x00, // ## ##
+ 0x06, 0x60, 0x00, // ## ##
+ 0x06, 0x60, 0x00, // ## ##
+ 0x3F, 0xF8, 0x00, // ###########
+ 0x3F, 0xF8, 0x00, // ###########
+ 0x06, 0x60, 0x00, // ## ##
+ 0x0C, 0xC0, 0x00, // ## ##
+ 0x3F, 0xF8, 0x00, // ###########
+ 0x3F, 0xF8, 0x00, // ###########
+ 0x0C, 0xC0, 0x00, // ## ##
+ 0x0C, 0xC0, 0x00, // ## ##
+ 0x0C, 0xC0, 0x00, // ## ##
+ 0x0C, 0xC0, 0x00, // ## ##
+ 0x0C, 0xC0, 0x00, // ## ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @288 '$' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x07, 0xB0, 0x00, // #### ##
+ 0x0F, 0xF0, 0x00, // ########
+ 0x18, 0x70, 0x00, // ## ###
+ 0x18, 0x70, 0x00, // ## ###
+ 0x1C, 0x00, 0x00, // ###
+ 0x0F, 0x80, 0x00, // #####
+ 0x07, 0xE0, 0x00, // ######
+ 0x00, 0xF0, 0x00, // ####
+ 0x18, 0x30, 0x00, // ## ##
+ 0x1C, 0x30, 0x00, // ### ##
+ 0x1C, 0x70, 0x00, // ### ###
+ 0x1F, 0xE0, 0x00, // ########
+ 0x1B, 0xC0, 0x00, // ## ####
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @360 '%' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x07, 0x80, 0x00, // ####
+ 0x0F, 0xC0, 0x00, // ######
+ 0x1C, 0xE0, 0x00, // ### ###
+ 0x18, 0x60, 0x00, // ## ##
+ 0x18, 0x60, 0x00, // ## ##
+ 0x1C, 0xE0, 0x00, // ### ###
+ 0x0F, 0xF8, 0x00, // #########
+ 0x07, 0xE0, 0x00, // ######
+ 0x1F, 0xF0, 0x00, // #########
+ 0x07, 0x38, 0x00, // ### ###
+ 0x06, 0x18, 0x00, // ## ##
+ 0x06, 0x18, 0x00, // ## ##
+ 0x07, 0x38, 0x00, // ### ###
+ 0x03, 0xF0, 0x00, // ######
+ 0x01, 0xE0, 0x00, // ####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @432 '&' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0xF0, 0x00, // ######
+ 0x07, 0xF0, 0x00, // #######
+ 0x0C, 0x60, 0x00, // ## ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x06, 0x00, 0x00, // ##
+ 0x07, 0x00, 0x00, // ###
+ 0x0F, 0x9C, 0x00, // ##### ###
+ 0x1D, 0xFC, 0x00, // ### #######
+ 0x18, 0xF0, 0x00, // ## ####
+ 0x18, 0x70, 0x00, // ## ###
+ 0x0F, 0xFC, 0x00, // ##########
+ 0x07, 0xDC, 0x00, // ##### ###
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @504 ''' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x01, 0x00, 0x00, // #
+ 0x01, 0x00, 0x00, // #
+ 0x01, 0x00, 0x00, // #
+ 0x01, 0x00, 0x00, // #
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @576 '(' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x38, 0x00, // ###
+ 0x00, 0x70, 0x00, // ###
+ 0x00, 0xF0, 0x00, // ####
+ 0x00, 0xE0, 0x00, // ###
+ 0x00, 0xE0, 0x00, // ###
+ 0x01, 0xC0, 0x00, // ###
+ 0x01, 0xC0, 0x00, // ###
+ 0x01, 0xC0, 0x00, // ###
+ 0x01, 0xC0, 0x00, // ###
+ 0x01, 0xC0, 0x00, // ###
+ 0x01, 0xC0, 0x00, // ###
+ 0x00, 0xE0, 0x00, // ###
+ 0x00, 0xE0, 0x00, // ###
+ 0x00, 0x70, 0x00, // ###
+ 0x00, 0x70, 0x00, // ###
+ 0x00, 0x38, 0x00, // ###
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @648 ')' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x18, 0x00, 0x00, // ##
+ 0x1C, 0x00, 0x00, // ###
+ 0x0E, 0x00, 0x00, // ###
+ 0x0E, 0x00, 0x00, // ###
+ 0x07, 0x00, 0x00, // ###
+ 0x07, 0x00, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x07, 0x00, 0x00, // ###
+ 0x07, 0x00, 0x00, // ###
+ 0x0F, 0x00, 0x00, // ####
+ 0x0E, 0x00, 0x00, // ###
+ 0x1C, 0x00, 0x00, // ###
+ 0x18, 0x00, 0x00, // ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @720 '*' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x1D, 0xB8, 0x00, // ### ## ###
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x07, 0xE0, 0x00, // ######
+ 0x03, 0xC0, 0x00, // ####
+ 0x03, 0xC0, 0x00, // ####
+ 0x06, 0x60, 0x00, // ## ##
+ 0x06, 0x60, 0x00, // ## ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @792 '+' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x3F, 0xFC, 0x00, // ############
+ 0x3F, 0xFC, 0x00, // ############
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @864 ',' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0xE0, 0x00, // ###
+ 0x00, 0xC0, 0x00, // ##
+ 0x01, 0xC0, 0x00, // ###
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x03, 0x00, 0x00, // ##
+ 0x03, 0x00, 0x00, // ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @936 '-' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @1008 '.' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0xC0, 0x00, // ####
+ 0x03, 0xC0, 0x00, // ####
+ 0x03, 0xC0, 0x00, // ####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @1080 '/' (17 pixels wide)
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x38, 0x00, // ###
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x70, 0x00, // ###
+ 0x00, 0x60, 0x00, // ##
+ 0x00, 0x60, 0x00, // ##
+ 0x00, 0xC0, 0x00, // ##
+ 0x00, 0xC0, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x03, 0x00, 0x00, // ##
+ 0x03, 0x00, 0x00, // ##
+ 0x06, 0x00, 0x00, // ##
+ 0x06, 0x00, 0x00, // ##
+ 0x0E, 0x00, 0x00, // ###
+ 0x0C, 0x00, 0x00, // ##
+ 0x1C, 0x00, 0x00, // ###
+ 0x18, 0x00, 0x00, // ##
+ 0x18, 0x00, 0x00, // ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @1152 '0' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0xC0, 0x00, // ####
+ 0x07, 0xE0, 0x00, // ######
+ 0x0C, 0x30, 0x00, // ## ##
+ 0x0C, 0x30, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x0C, 0x30, 0x00, // ## ##
+ 0x0C, 0x30, 0x00, // ## ##
+ 0x07, 0xE0, 0x00, // ######
+ 0x03, 0xC0, 0x00, // ####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @1224 '1' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x80, 0x00, // #
+ 0x07, 0x80, 0x00, // ####
+ 0x1F, 0x80, 0x00, // ######
+ 0x1D, 0x80, 0x00, // ### ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @1296 '2' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x07, 0xC0, 0x00, // #####
+ 0x1F, 0xF0, 0x00, // #########
+ 0x38, 0x30, 0x00, // ### ##
+ 0x30, 0x18, 0x00, // ## ##
+ 0x30, 0x18, 0x00, // ## ##
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x60, 0x00, // ##
+ 0x01, 0xC0, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x06, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x18, 0x00, 0x00, // ##
+ 0x3F, 0xF8, 0x00, // ###########
+ 0x3F, 0xF8, 0x00, // ###########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @1368 '3' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0xC0, 0x00, // ####
+ 0x0F, 0xE0, 0x00, // #######
+ 0x0C, 0x70, 0x00, // ## ###
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x60, 0x00, // ##
+ 0x03, 0xC0, 0x00, // ####
+ 0x03, 0xE0, 0x00, // #####
+ 0x00, 0x70, 0x00, // ###
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x18, 0x00, // ##
+ 0x18, 0x38, 0x00, // ## ###
+ 0x1F, 0xF0, 0x00, // #########
+ 0x0F, 0xC0, 0x00, // ######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @1440 '4' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0xE0, 0x00, // ###
+ 0x01, 0xE0, 0x00, // ####
+ 0x01, 0xE0, 0x00, // ####
+ 0x03, 0x60, 0x00, // ## ##
+ 0x06, 0x60, 0x00, // ## ##
+ 0x06, 0x60, 0x00, // ## ##
+ 0x0C, 0x60, 0x00, // ## ##
+ 0x0C, 0x60, 0x00, // ## ##
+ 0x18, 0x60, 0x00, // ## ##
+ 0x30, 0x60, 0x00, // ## ##
+ 0x3F, 0xF8, 0x00, // ###########
+ 0x3F, 0xF8, 0x00, // ###########
+ 0x00, 0x60, 0x00, // ##
+ 0x03, 0xF8, 0x00, // #######
+ 0x03, 0xF8, 0x00, // #######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @1512 '5' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x1F, 0xF0, 0x00, // #########
+ 0x1F, 0xF0, 0x00, // #########
+ 0x18, 0x00, 0x00, // ##
+ 0x18, 0x00, 0x00, // ##
+ 0x18, 0x00, 0x00, // ##
+ 0x1B, 0xC0, 0x00, // ## ####
+ 0x1F, 0xF0, 0x00, // #########
+ 0x1C, 0x30, 0x00, // ### ##
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x18, 0x00, // ##
+ 0x30, 0x30, 0x00, // ## ##
+ 0x3F, 0xF0, 0x00, // ##########
+ 0x0F, 0xC0, 0x00, // ######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @1584 '6' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0xF8, 0x00, // #####
+ 0x03, 0xF8, 0x00, // #######
+ 0x07, 0x00, 0x00, // ###
+ 0x0E, 0x00, 0x00, // ###
+ 0x0C, 0x00, 0x00, // ##
+ 0x18, 0x00, 0x00, // ##
+ 0x1B, 0xC0, 0x00, // ## ####
+ 0x1F, 0xF0, 0x00, // #########
+ 0x1C, 0x30, 0x00, // ### ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x0C, 0x38, 0x00, // ## ###
+ 0x0F, 0xF0, 0x00, // ########
+ 0x03, 0xE0, 0x00, // #####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @1656 '7' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x38, 0x00, // ## ###
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x70, 0x00, // ###
+ 0x00, 0x60, 0x00, // ##
+ 0x00, 0x60, 0x00, // ##
+ 0x00, 0xE0, 0x00, // ###
+ 0x00, 0xC0, 0x00, // ##
+ 0x00, 0xC0, 0x00, // ##
+ 0x01, 0xC0, 0x00, // ###
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @1728 '8' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x07, 0xE0, 0x00, // ######
+ 0x0F, 0xF0, 0x00, // ########
+ 0x1C, 0x38, 0x00, // ### ###
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x0C, 0x30, 0x00, // ## ##
+ 0x07, 0xE0, 0x00, // ######
+ 0x07, 0xE0, 0x00, // ######
+ 0x0C, 0x30, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x1C, 0x38, 0x00, // ### ###
+ 0x0F, 0xF0, 0x00, // ########
+ 0x07, 0xE0, 0x00, // ######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @1800 '9' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x07, 0xC0, 0x00, // #####
+ 0x0F, 0xF0, 0x00, // ########
+ 0x1C, 0x30, 0x00, // ### ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x0C, 0x38, 0x00, // ## ###
+ 0x0F, 0xF8, 0x00, // #########
+ 0x03, 0xD8, 0x00, // #### ##
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x70, 0x00, // ###
+ 0x00, 0xE0, 0x00, // ###
+ 0x1F, 0xC0, 0x00, // #######
+ 0x1F, 0x00, 0x00, // #####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @1872 ':' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0xC0, 0x00, // ####
+ 0x03, 0xC0, 0x00, // ####
+ 0x03, 0xC0, 0x00, // ####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0xC0, 0x00, // ####
+ 0x03, 0xC0, 0x00, // ####
+ 0x03, 0xC0, 0x00, // ####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @1944 ';' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0xF0, 0x00, // ####
+ 0x00, 0xF0, 0x00, // ####
+ 0x00, 0xF0, 0x00, // ####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0xE0, 0x00, // ###
+ 0x01, 0xC0, 0x00, // ###
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x03, 0x00, 0x00, // ##
+ 0x02, 0x00, 0x00, // #
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @2016 '<' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x1C, 0x00, // ###
+ 0x00, 0x3C, 0x00, // ####
+ 0x00, 0xF0, 0x00, // ####
+ 0x03, 0xC0, 0x00, // ####
+ 0x0F, 0x00, 0x00, // ####
+ 0x3C, 0x00, 0x00, // ####
+ 0xF0, 0x00, 0x00, // ####
+ 0x3C, 0x00, 0x00, // ####
+ 0x0F, 0x00, 0x00, // ####
+ 0x03, 0xC0, 0x00, // ####
+ 0x00, 0xF0, 0x00, // ####
+ 0x00, 0x3C, 0x00, // ####
+ 0x00, 0x1C, 0x00, // ###
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @2088 '=' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7F, 0xFC, 0x00, // #############
+ 0x7F, 0xFC, 0x00, // #############
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7F, 0xFC, 0x00, // #############
+ 0x7F, 0xFC, 0x00, // #############
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @2160 '>' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x70, 0x00, 0x00, // ###
+ 0x78, 0x00, 0x00, // ####
+ 0x1E, 0x00, 0x00, // ####
+ 0x07, 0x80, 0x00, // ####
+ 0x01, 0xE0, 0x00, // ####
+ 0x00, 0x78, 0x00, // ####
+ 0x00, 0x1E, 0x00, // ####
+ 0x00, 0x78, 0x00, // ####
+ 0x01, 0xE0, 0x00, // ####
+ 0x07, 0x80, 0x00, // ####
+ 0x1E, 0x00, 0x00, // ####
+ 0x78, 0x00, 0x00, // ####
+ 0x70, 0x00, 0x00, // ###
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @2232 '?' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x07, 0xC0, 0x00, // #####
+ 0x0F, 0xE0, 0x00, // #######
+ 0x18, 0x70, 0x00, // ## ###
+ 0x18, 0x30, 0x00, // ## ##
+ 0x18, 0x30, 0x00, // ## ##
+ 0x00, 0x70, 0x00, // ###
+ 0x00, 0xE0, 0x00, // ###
+ 0x03, 0xC0, 0x00, // ####
+ 0x03, 0x80, 0x00, // ###
+ 0x03, 0x00, 0x00, // ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x07, 0x00, 0x00, // ###
+ 0x07, 0x00, 0x00, // ###
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @2304 '@' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0xE0, 0x00, // #####
+ 0x07, 0xF0, 0x00, // #######
+ 0x0E, 0x38, 0x00, // ### ###
+ 0x0C, 0x18, 0x00, // ## ##
+ 0x18, 0x78, 0x00, // ## ####
+ 0x18, 0xF8, 0x00, // ## #####
+ 0x19, 0xD8, 0x00, // ## ### ##
+ 0x19, 0x98, 0x00, // ## ## ##
+ 0x19, 0x98, 0x00, // ## ## ##
+ 0x19, 0x98, 0x00, // ## ## ##
+ 0x18, 0xF8, 0x00, // ## #####
+ 0x18, 0x78, 0x00, // ## ####
+ 0x18, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0E, 0x18, 0x00, // ### ##
+ 0x07, 0xF8, 0x00, // ########
+ 0x03, 0xE0, 0x00, // #####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @2376 'A' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x1F, 0x80, 0x00, // ######
+ 0x1F, 0xC0, 0x00, // #######
+ 0x01, 0xC0, 0x00, // ###
+ 0x03, 0x60, 0x00, // ## ##
+ 0x03, 0x60, 0x00, // ## ##
+ 0x06, 0x30, 0x00, // ## ##
+ 0x06, 0x30, 0x00, // ## ##
+ 0x0C, 0x30, 0x00, // ## ##
+ 0x0F, 0xF8, 0x00, // #########
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x30, 0x0C, 0x00, // ## ##
+ 0xFC, 0x7F, 0x00, // ###### #######
+ 0xFC, 0x7F, 0x00, // ###### #######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @2448 'B' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7F, 0xE0, 0x00, // ##########
+ 0x7F, 0xF0, 0x00, // ###########
+ 0x18, 0x38, 0x00, // ## ###
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x38, 0x00, // ## ###
+ 0x1F, 0xF0, 0x00, // #########
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x18, 0x1C, 0x00, // ## ###
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x7F, 0xF8, 0x00, // ############
+ 0x7F, 0xF0, 0x00, // ###########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @2520 'C' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0xEC, 0x00, // ##### ##
+ 0x0F, 0xFC, 0x00, // ##########
+ 0x1C, 0x1C, 0x00, // ### ###
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x30, 0x00, 0x00, // ##
+ 0x30, 0x00, 0x00, // ##
+ 0x30, 0x00, 0x00, // ##
+ 0x30, 0x00, 0x00, // ##
+ 0x30, 0x00, 0x00, // ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x1C, 0x1C, 0x00, // ### ###
+ 0x0F, 0xF8, 0x00, // #########
+ 0x03, 0xF0, 0x00, // ######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @2592 'D' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7F, 0xC0, 0x00, // #########
+ 0x7F, 0xF0, 0x00, // ###########
+ 0x18, 0x38, 0x00, // ## ###
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x38, 0x00, // ## ###
+ 0x7F, 0xF0, 0x00, // ###########
+ 0x7F, 0xE0, 0x00, // ##########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @2664 'E' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7F, 0xF8, 0x00, // ############
+ 0x7F, 0xF8, 0x00, // ############
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x19, 0x98, 0x00, // ## ## ##
+ 0x19, 0x80, 0x00, // ## ##
+ 0x1F, 0x80, 0x00, // ######
+ 0x1F, 0x80, 0x00, // ######
+ 0x19, 0x80, 0x00, // ## ##
+ 0x19, 0x98, 0x00, // ## ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x7F, 0xF8, 0x00, // ############
+ 0x7F, 0xF8, 0x00, // ############
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @2736 'F' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x3F, 0xFC, 0x00, // ############
+ 0x3F, 0xFC, 0x00, // ############
+ 0x0C, 0x0C, 0x00, // ## ##
+ 0x0C, 0x0C, 0x00, // ## ##
+ 0x0C, 0xCC, 0x00, // ## ## ##
+ 0x0C, 0xC0, 0x00, // ## ##
+ 0x0F, 0xC0, 0x00, // ######
+ 0x0F, 0xC0, 0x00, // ######
+ 0x0C, 0xC0, 0x00, // ## ##
+ 0x0C, 0xC0, 0x00, // ## ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x3F, 0xC0, 0x00, // ########
+ 0x3F, 0xC0, 0x00, // ########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @2808 'G' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0xEC, 0x00, // ##### ##
+ 0x0F, 0xFC, 0x00, // ##########
+ 0x1C, 0x1C, 0x00, // ### ###
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x30, 0x00, 0x00, // ##
+ 0x30, 0x00, 0x00, // ##
+ 0x30, 0xFE, 0x00, // ## #######
+ 0x30, 0xFE, 0x00, // ## #######
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x38, 0x0C, 0x00, // ### ##
+ 0x1C, 0x1C, 0x00, // ### ###
+ 0x0F, 0xFC, 0x00, // ##########
+ 0x03, 0xF0, 0x00, // ######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @2880 'H' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7E, 0x7E, 0x00, // ###### ######
+ 0x7E, 0x7E, 0x00, // ###### ######
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x7E, 0x7E, 0x00, // ###### ######
+ 0x7E, 0x7E, 0x00, // ###### ######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @2952 'I' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @3024 'J' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x07, 0xFE, 0x00, // ##########
+ 0x07, 0xFE, 0x00, // ##########
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x30, 0x30, 0x00, // ## ##
+ 0x30, 0x30, 0x00, // ## ##
+ 0x30, 0x30, 0x00, // ## ##
+ 0x30, 0x30, 0x00, // ## ##
+ 0x30, 0x60, 0x00, // ## ##
+ 0x3F, 0xE0, 0x00, // #########
+ 0x0F, 0x80, 0x00, // #####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @3096 'K' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7F, 0x3E, 0x00, // ####### #####
+ 0x7F, 0x3E, 0x00, // ####### #####
+ 0x18, 0x30, 0x00, // ## ##
+ 0x18, 0x60, 0x00, // ## ##
+ 0x18, 0xC0, 0x00, // ## ##
+ 0x19, 0x80, 0x00, // ## ##
+ 0x1B, 0x80, 0x00, // ## ###
+ 0x1F, 0xC0, 0x00, // #######
+ 0x1C, 0xE0, 0x00, // ### ###
+ 0x18, 0x70, 0x00, // ## ###
+ 0x18, 0x30, 0x00, // ## ##
+ 0x18, 0x38, 0x00, // ## ###
+ 0x7F, 0x1F, 0x00, // ####### #####
+ 0x7F, 0x1F, 0x00, // ####### #####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @3168 'L' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7F, 0x80, 0x00, // ########
+ 0x7F, 0x80, 0x00, // ########
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x0C, 0x00, // ## ##
+ 0x0C, 0x0C, 0x00, // ## ##
+ 0x0C, 0x0C, 0x00, // ## ##
+ 0x0C, 0x0C, 0x00, // ## ##
+ 0x7F, 0xFC, 0x00, // #############
+ 0x7F, 0xFC, 0x00, // #############
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @3240 'M' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0xF0, 0x0F, 0x00, // #### ####
+ 0xF8, 0x1F, 0x00, // ##### #####
+ 0x38, 0x1C, 0x00, // ### ###
+ 0x3C, 0x3C, 0x00, // #### ####
+ 0x3C, 0x3C, 0x00, // #### ####
+ 0x36, 0x6C, 0x00, // ## ## ## ##
+ 0x36, 0x6C, 0x00, // ## ## ## ##
+ 0x33, 0xCC, 0x00, // ## #### ##
+ 0x33, 0xCC, 0x00, // ## #### ##
+ 0x31, 0x8C, 0x00, // ## ## ##
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x30, 0x0C, 0x00, // ## ##
+ 0xFE, 0x7F, 0x00, // ####### #######
+ 0xFE, 0x7F, 0x00, // ####### #######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @3312 'N' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x78, 0xFE, 0x00, // #### #######
+ 0x78, 0xFE, 0x00, // #### #######
+ 0x1C, 0x18, 0x00, // ### ##
+ 0x1E, 0x18, 0x00, // #### ##
+ 0x1F, 0x18, 0x00, // ##### ##
+ 0x1B, 0x18, 0x00, // ## ## ##
+ 0x1B, 0x98, 0x00, // ## ### ##
+ 0x19, 0xD8, 0x00, // ## ### ##
+ 0x18, 0xD8, 0x00, // ## ## ##
+ 0x18, 0xF8, 0x00, // ## #####
+ 0x18, 0x78, 0x00, // ## ####
+ 0x18, 0x38, 0x00, // ## ###
+ 0x7F, 0x18, 0x00, // ####### ##
+ 0x7F, 0x18, 0x00, // ####### ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @3384 'O' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0xC0, 0x00, // ####
+ 0x0F, 0xF0, 0x00, // ########
+ 0x1C, 0x38, 0x00, // ### ###
+ 0x18, 0x18, 0x00, // ## ##
+ 0x38, 0x1C, 0x00, // ### ###
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x38, 0x1C, 0x00, // ### ###
+ 0x18, 0x18, 0x00, // ## ##
+ 0x1C, 0x38, 0x00, // ### ###
+ 0x0F, 0xF0, 0x00, // ########
+ 0x03, 0xC0, 0x00, // ####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @3456 'P' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x3F, 0xF0, 0x00, // ##########
+ 0x3F, 0xF8, 0x00, // ###########
+ 0x0C, 0x1C, 0x00, // ## ###
+ 0x0C, 0x0C, 0x00, // ## ##
+ 0x0C, 0x0C, 0x00, // ## ##
+ 0x0C, 0x0C, 0x00, // ## ##
+ 0x0C, 0x18, 0x00, // ## ##
+ 0x0F, 0xF8, 0x00, // #########
+ 0x0F, 0xE0, 0x00, // #######
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x3F, 0xC0, 0x00, // ########
+ 0x3F, 0xC0, 0x00, // ########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @3528 'Q' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0xC0, 0x00, // ####
+ 0x0F, 0xF0, 0x00, // ########
+ 0x1C, 0x38, 0x00, // ### ###
+ 0x18, 0x18, 0x00, // ## ##
+ 0x38, 0x1C, 0x00, // ### ###
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x38, 0x1C, 0x00, // ### ###
+ 0x18, 0x18, 0x00, // ## ##
+ 0x1C, 0x38, 0x00, // ### ###
+ 0x0F, 0xF0, 0x00, // ########
+ 0x07, 0xC0, 0x00, // #####
+ 0x07, 0xCC, 0x00, // ##### ##
+ 0x0F, 0xFC, 0x00, // ##########
+ 0x0C, 0x38, 0x00, // ## ###
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @3600 'R' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7F, 0xE0, 0x00, // ##########
+ 0x7F, 0xF0, 0x00, // ###########
+ 0x18, 0x38, 0x00, // ## ###
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x38, 0x00, // ## ###
+ 0x1F, 0xF0, 0x00, // #########
+ 0x1F, 0xC0, 0x00, // #######
+ 0x18, 0xE0, 0x00, // ## ###
+ 0x18, 0x70, 0x00, // ## ###
+ 0x18, 0x30, 0x00, // ## ##
+ 0x18, 0x38, 0x00, // ## ###
+ 0x7F, 0x1E, 0x00, // ####### ####
+ 0x7F, 0x0E, 0x00, // ####### ###
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @3672 'S' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x07, 0xD8, 0x00, // ##### ##
+ 0x0F, 0xF8, 0x00, // #########
+ 0x1C, 0x38, 0x00, // ### ###
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x1E, 0x00, 0x00, // ####
+ 0x0F, 0xC0, 0x00, // ######
+ 0x03, 0xF0, 0x00, // ######
+ 0x00, 0x78, 0x00, // ####
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x1C, 0x38, 0x00, // ### ###
+ 0x1F, 0xF0, 0x00, // #########
+ 0x1B, 0xE0, 0x00, // ## #####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @3744 'T' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x3F, 0xFC, 0x00, // ############
+ 0x3F, 0xFC, 0x00, // ############
+ 0x31, 0x8C, 0x00, // ## ## ##
+ 0x31, 0x8C, 0x00, // ## ## ##
+ 0x31, 0x8C, 0x00, // ## ## ##
+ 0x31, 0x8C, 0x00, // ## ## ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x0F, 0xF0, 0x00, // ########
+ 0x0F, 0xF0, 0x00, // ########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @3816 'U' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7E, 0x7E, 0x00, // ###### ######
+ 0x7E, 0x7E, 0x00, // ###### ######
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x0C, 0x30, 0x00, // ## ##
+ 0x0F, 0xF0, 0x00, // ########
+ 0x03, 0xC0, 0x00, // ####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @3888 'V' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7F, 0x7F, 0x00, // ####### #######
+ 0x7F, 0x7F, 0x00, // ####### #######
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x0C, 0x18, 0x00, // ## ##
+ 0x0C, 0x18, 0x00, // ## ##
+ 0x0C, 0x18, 0x00, // ## ##
+ 0x06, 0x30, 0x00, // ## ##
+ 0x06, 0x30, 0x00, // ## ##
+ 0x03, 0x60, 0x00, // ## ##
+ 0x03, 0x60, 0x00, // ## ##
+ 0x03, 0x60, 0x00, // ## ##
+ 0x01, 0xC0, 0x00, // ###
+ 0x01, 0xC0, 0x00, // ###
+ 0x00, 0x80, 0x00, // #
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @3960 'W' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0xFE, 0x3F, 0x80, // ####### #######
+ 0xFE, 0x3F, 0x80, // ####### #######
+ 0x30, 0x06, 0x00, // ## ##
+ 0x30, 0x06, 0x00, // ## ##
+ 0x30, 0x86, 0x00, // ## # ##
+ 0x19, 0xCC, 0x00, // ## ### ##
+ 0x19, 0xCC, 0x00, // ## ### ##
+ 0x1B, 0x6C, 0x00, // ## ## ## ##
+ 0x1B, 0x6C, 0x00, // ## ## ## ##
+ 0x1E, 0x7C, 0x00, // #### #####
+ 0x0E, 0x38, 0x00, // ### ###
+ 0x0E, 0x38, 0x00, // ### ###
+ 0x0C, 0x18, 0x00, // ## ##
+ 0x0C, 0x18, 0x00, // ## ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @4032 'X' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7E, 0x7E, 0x00, // ###### ######
+ 0x7E, 0x7E, 0x00, // ###### ######
+ 0x18, 0x18, 0x00, // ## ##
+ 0x0C, 0x30, 0x00, // ## ##
+ 0x06, 0x60, 0x00, // ## ##
+ 0x03, 0xC0, 0x00, // ####
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x03, 0xC0, 0x00, // ####
+ 0x06, 0x60, 0x00, // ## ##
+ 0x0C, 0x30, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x7E, 0x7E, 0x00, // ###### ######
+ 0x7E, 0x7E, 0x00, // ###### ######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @4104 'Y' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7C, 0x7E, 0x00, // ##### ######
+ 0x7C, 0x7E, 0x00, // ##### ######
+ 0x18, 0x18, 0x00, // ## ##
+ 0x0C, 0x30, 0x00, // ## ##
+ 0x06, 0x60, 0x00, // ## ##
+ 0x06, 0x60, 0x00, // ## ##
+ 0x03, 0xC0, 0x00, // ####
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x0F, 0xF0, 0x00, // ########
+ 0x0F, 0xF0, 0x00, // ########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @4176 'Z' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x30, 0x00, // ## ##
+ 0x18, 0x60, 0x00, // ## ##
+ 0x18, 0xC0, 0x00, // ## ##
+ 0x01, 0x80, 0x00, // ##
+ 0x03, 0x00, 0x00, // ##
+ 0x06, 0x18, 0x00, // ## ##
+ 0x0C, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x30, 0x18, 0x00, // ## ##
+ 0x3F, 0xF8, 0x00, // ###########
+ 0x3F, 0xF8, 0x00, // ###########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @4248 '[' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x01, 0xF0, 0x00, // #####
+ 0x01, 0xF0, 0x00, // #####
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0xF0, 0x00, // #####
+ 0x01, 0xF0, 0x00, // #####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @4320 '\' (17 pixels wide)
+ 0x18, 0x00, 0x00, // ##
+ 0x18, 0x00, 0x00, // ##
+ 0x1C, 0x00, 0x00, // ###
+ 0x0C, 0x00, 0x00, // ##
+ 0x0E, 0x00, 0x00, // ###
+ 0x06, 0x00, 0x00, // ##
+ 0x06, 0x00, 0x00, // ##
+ 0x03, 0x00, 0x00, // ##
+ 0x03, 0x00, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x00, 0xC0, 0x00, // ##
+ 0x00, 0xC0, 0x00, // ##
+ 0x00, 0x60, 0x00, // ##
+ 0x00, 0x60, 0x00, // ##
+ 0x00, 0x70, 0x00, // ###
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x38, 0x00, // ###
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @4392 ']' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x0F, 0x80, 0x00, // #####
+ 0x0F, 0x80, 0x00, // #####
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x0F, 0x80, 0x00, // #####
+ 0x0F, 0x80, 0x00, // #####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @4464 '^' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x80, 0x00, // #
+ 0x01, 0xC0, 0x00, // ###
+ 0x03, 0xE0, 0x00, // #####
+ 0x07, 0x70, 0x00, // ### ###
+ 0x06, 0x30, 0x00, // ## ##
+ 0x0C, 0x18, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x10, 0x04, 0x00, // # #
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @4536 '_' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0xFF, 0xFF, 0x00, // ################
+ 0xFF, 0xFF, 0x00, // ################
+
+ // @4608 '`' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x03, 0x00, 0x00, // ##
+ 0x03, 0x80, 0x00, // ###
+ 0x00, 0xE0, 0x00, // ###
+ 0x00, 0x60, 0x00, // ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @4680 'a' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x0F, 0xC0, 0x00, // ######
+ 0x1F, 0xE0, 0x00, // ########
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x07, 0xF0, 0x00, // #######
+ 0x1F, 0xF0, 0x00, // #########
+ 0x38, 0x30, 0x00, // ### ##
+ 0x30, 0x30, 0x00, // ## ##
+ 0x30, 0x70, 0x00, // ## ###
+ 0x1F, 0xFC, 0x00, // ###########
+ 0x0F, 0xBC, 0x00, // ##### ####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @4752 'b' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x78, 0x00, 0x00, // ####
+ 0x78, 0x00, 0x00, // ####
+ 0x18, 0x00, 0x00, // ##
+ 0x18, 0x00, 0x00, // ##
+ 0x1B, 0xE0, 0x00, // ## #####
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x1C, 0x18, 0x00, // ### ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x1C, 0x18, 0x00, // ### ##
+ 0x7F, 0xF8, 0x00, // ############
+ 0x7B, 0xE0, 0x00, // #### #####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @4824 'c' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0xEC, 0x00, // ##### ##
+ 0x0F, 0xFC, 0x00, // ##########
+ 0x1C, 0x1C, 0x00, // ### ###
+ 0x38, 0x0C, 0x00, // ### ##
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x30, 0x00, 0x00, // ##
+ 0x30, 0x00, 0x00, // ##
+ 0x38, 0x0C, 0x00, // ### ##
+ 0x1C, 0x1C, 0x00, // ### ###
+ 0x0F, 0xF8, 0x00, // #########
+ 0x03, 0xF0, 0x00, // ######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @4896 'd' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x78, 0x00, // ####
+ 0x00, 0x78, 0x00, // ####
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x18, 0x00, // ##
+ 0x07, 0xD8, 0x00, // ##### ##
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x18, 0x38, 0x00, // ## ###
+ 0x30, 0x18, 0x00, // ## ##
+ 0x30, 0x18, 0x00, // ## ##
+ 0x30, 0x18, 0x00, // ## ##
+ 0x30, 0x18, 0x00, // ## ##
+ 0x30, 0x18, 0x00, // ## ##
+ 0x18, 0x38, 0x00, // ## ###
+ 0x1F, 0xFE, 0x00, // ############
+ 0x07, 0xDE, 0x00, // ##### ####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @4968 'e' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x07, 0xE0, 0x00, // ######
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x18, 0x18, 0x00, // ## ##
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x3F, 0xFC, 0x00, // ############
+ 0x3F, 0xFC, 0x00, // ############
+ 0x30, 0x00, 0x00, // ##
+ 0x30, 0x00, 0x00, // ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x1F, 0xFC, 0x00, // ###########
+ 0x07, 0xF0, 0x00, // #######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @5040 'f' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x01, 0xFC, 0x00, // #######
+ 0x03, 0xFC, 0x00, // ########
+ 0x06, 0x00, 0x00, // ##
+ 0x06, 0x00, 0x00, // ##
+ 0x3F, 0xF8, 0x00, // ###########
+ 0x3F, 0xF8, 0x00, // ###########
+ 0x06, 0x00, 0x00, // ##
+ 0x06, 0x00, 0x00, // ##
+ 0x06, 0x00, 0x00, // ##
+ 0x06, 0x00, 0x00, // ##
+ 0x06, 0x00, 0x00, // ##
+ 0x06, 0x00, 0x00, // ##
+ 0x06, 0x00, 0x00, // ##
+ 0x3F, 0xF0, 0x00, // ##########
+ 0x3F, 0xF0, 0x00, // ##########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @5112 'g' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x07, 0xDE, 0x00, // ##### ####
+ 0x1F, 0xFE, 0x00, // ############
+ 0x18, 0x38, 0x00, // ## ###
+ 0x30, 0x18, 0x00, // ## ##
+ 0x30, 0x18, 0x00, // ## ##
+ 0x30, 0x18, 0x00, // ## ##
+ 0x30, 0x18, 0x00, // ## ##
+ 0x30, 0x18, 0x00, // ## ##
+ 0x18, 0x38, 0x00, // ## ###
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x07, 0xD8, 0x00, // ##### ##
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x38, 0x00, // ###
+ 0x0F, 0xF0, 0x00, // ########
+ 0x0F, 0xC0, 0x00, // ######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @5184 'h' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x78, 0x00, 0x00, // ####
+ 0x78, 0x00, 0x00, // ####
+ 0x18, 0x00, 0x00, // ##
+ 0x18, 0x00, 0x00, // ##
+ 0x1B, 0xE0, 0x00, // ## #####
+ 0x1F, 0xF0, 0x00, // #########
+ 0x1C, 0x38, 0x00, // ### ###
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x7E, 0x7E, 0x00, // ###### ######
+ 0x7E, 0x7E, 0x00, // ###### ######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @5256 'i' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x1F, 0x80, 0x00, // ######
+ 0x1F, 0x80, 0x00, // ######
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x3F, 0xFC, 0x00, // ############
+ 0x3F, 0xFC, 0x00, // ############
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @5328 'j' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0xC0, 0x00, // ##
+ 0x00, 0xC0, 0x00, // ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x1F, 0xF0, 0x00, // #########
+ 0x1F, 0xF0, 0x00, // #########
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x30, 0x00, // ##
+ 0x00, 0x70, 0x00, // ###
+ 0x1F, 0xE0, 0x00, // ########
+ 0x1F, 0x80, 0x00, // ######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @5400 'k' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x3C, 0x00, 0x00, // ####
+ 0x3C, 0x00, 0x00, // ####
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0xF8, 0x00, // ## #####
+ 0x0C, 0xF8, 0x00, // ## #####
+ 0x0C, 0xC0, 0x00, // ## ##
+ 0x0D, 0x80, 0x00, // ## ##
+ 0x0F, 0x80, 0x00, // #####
+ 0x0F, 0x00, 0x00, // ####
+ 0x0F, 0x80, 0x00, // #####
+ 0x0D, 0xC0, 0x00, // ## ###
+ 0x0C, 0xE0, 0x00, // ## ###
+ 0x3C, 0x7C, 0x00, // #### #####
+ 0x3C, 0x7C, 0x00, // #### #####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @5472 'l' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x1F, 0x80, 0x00, // ######
+ 0x1F, 0x80, 0x00, // ######
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x3F, 0xFC, 0x00, // ############
+ 0x3F, 0xFC, 0x00, // ############
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @5544 'm' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0xF7, 0x78, 0x00, // #### ### ####
+ 0xFF, 0xFC, 0x00, // ##############
+ 0x39, 0xCC, 0x00, // ### ### ##
+ 0x31, 0x8C, 0x00, // ## ## ##
+ 0x31, 0x8C, 0x00, // ## ## ##
+ 0x31, 0x8C, 0x00, // ## ## ##
+ 0x31, 0x8C, 0x00, // ## ## ##
+ 0x31, 0x8C, 0x00, // ## ## ##
+ 0x31, 0x8C, 0x00, // ## ## ##
+ 0xFD, 0xEF, 0x00, // ###### #### ####
+ 0xFD, 0xEF, 0x00, // ###### #### ####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @5616 'n' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7B, 0xE0, 0x00, // #### #####
+ 0x7F, 0xF0, 0x00, // ###########
+ 0x1C, 0x38, 0x00, // ### ###
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x7E, 0x7E, 0x00, // ###### ######
+ 0x7E, 0x7E, 0x00, // ###### ######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @5688 'o' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x03, 0xC0, 0x00, // ####
+ 0x0F, 0xF0, 0x00, // ########
+ 0x1C, 0x38, 0x00, // ### ###
+ 0x38, 0x1C, 0x00, // ### ###
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x30, 0x0C, 0x00, // ## ##
+ 0x38, 0x1C, 0x00, // ### ###
+ 0x1C, 0x38, 0x00, // ### ###
+ 0x0F, 0xF0, 0x00, // ########
+ 0x03, 0xC0, 0x00, // ####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @5760 'p' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7B, 0xE0, 0x00, // #### #####
+ 0x7F, 0xF8, 0x00, // ############
+ 0x1C, 0x18, 0x00, // ### ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x1C, 0x18, 0x00, // ### ##
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x1B, 0xE0, 0x00, // ## #####
+ 0x18, 0x00, 0x00, // ##
+ 0x18, 0x00, 0x00, // ##
+ 0x18, 0x00, 0x00, // ##
+ 0x7F, 0x00, 0x00, // #######
+ 0x7F, 0x00, 0x00, // #######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @5832 'q' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x07, 0xDE, 0x00, // ##### ####
+ 0x1F, 0xFE, 0x00, // ############
+ 0x18, 0x38, 0x00, // ## ###
+ 0x30, 0x18, 0x00, // ## ##
+ 0x30, 0x18, 0x00, // ## ##
+ 0x30, 0x18, 0x00, // ## ##
+ 0x30, 0x18, 0x00, // ## ##
+ 0x30, 0x18, 0x00, // ## ##
+ 0x18, 0x38, 0x00, // ## ###
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x07, 0xD8, 0x00, // ##### ##
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0x18, 0x00, // ##
+ 0x00, 0xFE, 0x00, // #######
+ 0x00, 0xFE, 0x00, // #######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @5904 'r' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x3E, 0x78, 0x00, // ##### ####
+ 0x3E, 0xFC, 0x00, // ##### ######
+ 0x07, 0xCC, 0x00, // ##### ##
+ 0x07, 0x00, 0x00, // ###
+ 0x06, 0x00, 0x00, // ##
+ 0x06, 0x00, 0x00, // ##
+ 0x06, 0x00, 0x00, // ##
+ 0x06, 0x00, 0x00, // ##
+ 0x06, 0x00, 0x00, // ##
+ 0x3F, 0xF0, 0x00, // ##########
+ 0x3F, 0xF0, 0x00, // ##########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @5976 's' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x07, 0xF8, 0x00, // ########
+ 0x0F, 0xF8, 0x00, // #########
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x1F, 0x80, 0x00, // ######
+ 0x0F, 0xF0, 0x00, // ########
+ 0x00, 0xF8, 0x00, // #####
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x38, 0x00, // ## ###
+ 0x1F, 0xF0, 0x00, // #########
+ 0x1F, 0xE0, 0x00, // ########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @6048 't' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x3F, 0xF0, 0x00, // ##########
+ 0x3F, 0xF0, 0x00, // ##########
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x00, 0x00, // ##
+ 0x0C, 0x1C, 0x00, // ## ###
+ 0x07, 0xFC, 0x00, // #########
+ 0x03, 0xF0, 0x00, // ######
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @6120 'u' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x78, 0x78, 0x00, // #### ####
+ 0x78, 0x78, 0x00, // #### ####
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x38, 0x00, // ## ###
+ 0x0F, 0xFE, 0x00, // ###########
+ 0x07, 0xDE, 0x00, // ##### ####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @6192 'v' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7C, 0x3E, 0x00, // ##### #####
+ 0x7C, 0x3E, 0x00, // ##### #####
+ 0x18, 0x18, 0x00, // ## ##
+ 0x18, 0x18, 0x00, // ## ##
+ 0x0C, 0x30, 0x00, // ## ##
+ 0x0C, 0x30, 0x00, // ## ##
+ 0x06, 0x60, 0x00, // ## ##
+ 0x06, 0x60, 0x00, // ## ##
+ 0x07, 0xE0, 0x00, // ######
+ 0x03, 0xC0, 0x00, // ####
+ 0x03, 0xC0, 0x00, // ####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @6264 'w' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x78, 0x3C, 0x00, // #### ####
+ 0x78, 0x3C, 0x00, // #### ####
+ 0x31, 0x18, 0x00, // ## # ##
+ 0x33, 0x98, 0x00, // ## ### ##
+ 0x33, 0x98, 0x00, // ## ### ##
+ 0x1A, 0xB0, 0x00, // ## # # ##
+ 0x1E, 0xF0, 0x00, // #### ####
+ 0x1E, 0xF0, 0x00, // #### ####
+ 0x1C, 0x60, 0x00, // ### ##
+ 0x0C, 0x60, 0x00, // ## ##
+ 0x0C, 0x60, 0x00, // ## ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @6336 'x' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x3E, 0x7C, 0x00, // ##### #####
+ 0x3E, 0x7C, 0x00, // ##### #####
+ 0x0C, 0x30, 0x00, // ## ##
+ 0x06, 0x60, 0x00, // ## ##
+ 0x03, 0xC0, 0x00, // ####
+ 0x01, 0x80, 0x00, // ##
+ 0x03, 0xC0, 0x00, // ####
+ 0x06, 0x60, 0x00, // ## ##
+ 0x0C, 0x30, 0x00, // ## ##
+ 0x3E, 0x7C, 0x00, // ##### #####
+ 0x3E, 0x7C, 0x00, // ##### #####
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @6408 'y' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x7E, 0x1F, 0x00, // ###### #####
+ 0x7E, 0x1F, 0x00, // ###### #####
+ 0x18, 0x0C, 0x00, // ## ##
+ 0x0C, 0x18, 0x00, // ## ##
+ 0x0C, 0x18, 0x00, // ## ##
+ 0x06, 0x30, 0x00, // ## ##
+ 0x06, 0x30, 0x00, // ## ##
+ 0x03, 0x60, 0x00, // ## ##
+ 0x03, 0xE0, 0x00, // #####
+ 0x01, 0xC0, 0x00, // ###
+ 0x00, 0xC0, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x03, 0x00, 0x00, // ##
+ 0x3F, 0xC0, 0x00, // ########
+ 0x3F, 0xC0, 0x00, // ########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @6480 'z' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x18, 0x30, 0x00, // ## ##
+ 0x18, 0x60, 0x00, // ## ##
+ 0x00, 0xC0, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x03, 0x00, 0x00, // ##
+ 0x06, 0x18, 0x00, // ## ##
+ 0x0C, 0x18, 0x00, // ## ##
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x1F, 0xF8, 0x00, // ##########
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @6552 '{' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0xE0, 0x00, // ###
+ 0x01, 0xE0, 0x00, // ####
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x03, 0x80, 0x00, // ###
+ 0x07, 0x00, 0x00, // ###
+ 0x03, 0x80, 0x00, // ###
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0xE0, 0x00, // ####
+ 0x00, 0xE0, 0x00, // ###
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @6624 '|' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @6696 '}' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x07, 0x00, 0x00, // ###
+ 0x07, 0x80, 0x00, // ####
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0xC0, 0x00, // ###
+ 0x00, 0xE0, 0x00, // ###
+ 0x01, 0xC0, 0x00, // ###
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x01, 0x80, 0x00, // ##
+ 0x07, 0x80, 0x00, // ####
+ 0x07, 0x00, 0x00, // ###
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+
+ // @6768 '~' (17 pixels wide)
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x0E, 0x00, 0x00, // ###
+ 0x1F, 0x18, 0x00, // ##### ##
+ 0x3B, 0xB8, 0x00, // ### ### ###
+ 0x31, 0xF0, 0x00, // ## #####
+ 0x00, 0xE0, 0x00, // ###
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, //
+};
+
+sFONT Font24 = {
+ Font24_Table,
+ 17, /* Width */
+ 24, /* Height */
+};
+
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Function_Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Utilities/Fonts/font8.c Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,1084 @@
+/**
+ ******************************************************************************
+ * @file Font8.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 18-February-2014
+ * @brief This file provides text Font8 for STM32xx-EVAL's LCD driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "fonts.h"
+
+/** @addtogroup Utilities
+ * @{
+ */
+
+/** @addtogroup STM32_EVAL
+ * @{
+ */
+
+/** @addtogroup Common
+ * @{
+ */
+
+/** @addtogroup FONTS
+ * @brief This file provides text Font8 for STM32xx-EVAL's LCD driver.
+ * @{
+ */
+
+/** @defgroup FONTS_Private_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Variables
+ * @{
+ */
+//
+// Font data for Courier New 12pt
+//
+
+const uint8_t Font8_Table[] =
+{
+ // @0 ' ' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @8 '!' (5 pixels wide)
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x00, //
+ 0x20, // #
+ 0x00, //
+ 0x00, //
+
+ // @16 '"' (5 pixels wide)
+ 0x50, // # #
+ 0x50, // # #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @24 '#' (5 pixels wide)
+ 0x28, // # #
+ 0x50, // # #
+ 0xF8, // #####
+ 0x50, // # #
+ 0xF8, // #####
+ 0x50, // # #
+ 0xA0, // # #
+ 0x00, //
+
+ // @32 '$' (5 pixels wide)
+ 0x20, // #
+ 0x30, // ##
+ 0x60, // ##
+ 0x30, // ##
+ 0x10, // #
+ 0x60, // ##
+ 0x20, // #
+ 0x00, //
+
+ // @40 '%' (5 pixels wide)
+ 0x20, // #
+ 0x20, // #
+ 0x18, // ##
+ 0x60, // ##
+ 0x10, // #
+ 0x10, // #
+ 0x00, //
+ 0x00, //
+
+ // @48 '&' (5 pixels wide)
+ 0x00, //
+ 0x38, // ###
+ 0x20, // #
+ 0x60, // ##
+ 0x50, // # #
+ 0x78, // ####
+ 0x00, //
+ 0x00, //
+
+ // @56 ''' (5 pixels wide)
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @64 '(' (5 pixels wide)
+ 0x10, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x10, // #
+ 0x00, //
+
+ // @72 ')' (5 pixels wide)
+ 0x40, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x40, // #
+ 0x00, //
+
+ // @80 '*' (5 pixels wide)
+ 0x20, // #
+ 0x70, // ###
+ 0x20, // #
+ 0x50, // # #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @88 '+' (5 pixels wide)
+ 0x00, //
+ 0x20, // #
+ 0x20, // #
+ 0xF8, // #####
+ 0x20, // #
+ 0x20, // #
+ 0x00, //
+ 0x00, //
+
+ // @96 ',' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x10, // #
+ 0x20, // #
+ 0x20, // #
+ 0x00, //
+
+ // @104 '-' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x70, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @112 '.' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x20, // #
+ 0x00, //
+ 0x00, //
+
+ // @120 '/' (5 pixels wide)
+ 0x10, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x40, // #
+ 0x40, // #
+ 0x80, // #
+ 0x00, //
+
+ // @128 '0' (5 pixels wide)
+ 0x20, // #
+ 0x50, // # #
+ 0x50, // # #
+ 0x50, // # #
+ 0x50, // # #
+ 0x20, // #
+ 0x00, //
+ 0x00, //
+
+ // @136 '1' (5 pixels wide)
+ 0x60, // ##
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0xF8, // #####
+ 0x00, //
+ 0x00, //
+
+ // @144 '2' (5 pixels wide)
+ 0x20, // #
+ 0x50, // # #
+ 0x20, // #
+ 0x20, // #
+ 0x40, // #
+ 0x70, // ###
+ 0x00, //
+ 0x00, //
+
+ // @152 '3' (5 pixels wide)
+ 0x20, // #
+ 0x50, // # #
+ 0x10, // #
+ 0x20, // #
+ 0x10, // #
+ 0x60, // ##
+ 0x00, //
+ 0x00, //
+
+ // @160 '4' (5 pixels wide)
+ 0x10, // #
+ 0x30, // ##
+ 0x50, // # #
+ 0x78, // ####
+ 0x10, // #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+
+ // @168 '5' (5 pixels wide)
+ 0x70, // ###
+ 0x40, // #
+ 0x60, // ##
+ 0x10, // #
+ 0x50, // # #
+ 0x20, // #
+ 0x00, //
+ 0x00, //
+
+ // @176 '6' (5 pixels wide)
+ 0x30, // ##
+ 0x40, // #
+ 0x60, // ##
+ 0x50, // # #
+ 0x50, // # #
+ 0x60, // ##
+ 0x00, //
+ 0x00, //
+
+ // @184 '7' (5 pixels wide)
+ 0x70, // ###
+ 0x50, // # #
+ 0x10, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x00, //
+ 0x00, //
+
+ // @192 '8' (5 pixels wide)
+ 0x20, // #
+ 0x50, // # #
+ 0x20, // #
+ 0x50, // # #
+ 0x50, // # #
+ 0x20, // #
+ 0x00, //
+ 0x00, //
+
+ // @200 '9' (5 pixels wide)
+ 0x30, // ##
+ 0x50, // # #
+ 0x50, // # #
+ 0x30, // ##
+ 0x10, // #
+ 0x60, // ##
+ 0x00, //
+ 0x00, //
+
+ // @208 ':' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x20, // #
+ 0x00, //
+ 0x00, //
+ 0x20, // #
+ 0x00, //
+ 0x00, //
+
+ // @216 ';' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x10, // #
+ 0x00, //
+ 0x10, // #
+ 0x20, // #
+ 0x00, //
+ 0x00, //
+
+ // @224 '<' (5 pixels wide)
+ 0x00, //
+ 0x10, // #
+ 0x20, // #
+ 0xC0, // ##
+ 0x20, // #
+ 0x10, // #
+ 0x00, //
+ 0x00, //
+
+ // @232 '=' (5 pixels wide)
+ 0x00, //
+ 0x70, // ###
+ 0x00, //
+ 0x70, // ###
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @240 '>' (5 pixels wide)
+ 0x00, //
+ 0x40, // #
+ 0x20, // #
+ 0x18, // ##
+ 0x20, // #
+ 0x40, // #
+ 0x00, //
+ 0x00, //
+
+ // @248 '?' (5 pixels wide)
+ 0x20, // #
+ 0x50, // # #
+ 0x10, // #
+ 0x20, // #
+ 0x00, //
+ 0x20, // #
+ 0x00, //
+ 0x00, //
+
+ // @256 '@' (5 pixels wide)
+ 0x30, // ##
+ 0x48, // # #
+ 0x48, // # #
+ 0x58, // # ##
+ 0x48, // # #
+ 0x40, // #
+ 0x38, // ###
+ 0x00, //
+
+ // @264 'A' (5 pixels wide)
+ 0x60, // ##
+ 0x20, // #
+ 0x50, // # #
+ 0x70, // ###
+ 0x88, // # #
+ 0xD8, // ## ##
+ 0x00, //
+ 0x00, //
+
+ // @272 'B' (5 pixels wide)
+ 0xF0, // ####
+ 0x48, // # #
+ 0x70, // ###
+ 0x48, // # #
+ 0x48, // # #
+ 0xF0, // ####
+ 0x00, //
+ 0x00, //
+
+ // @280 'C' (5 pixels wide)
+ 0x70, // ###
+ 0x50, // # #
+ 0x40, // #
+ 0x40, // #
+ 0x40, // #
+ 0x30, // ##
+ 0x00, //
+ 0x00, //
+
+ // @288 'D' (5 pixels wide)
+ 0xF0, // ####
+ 0x48, // # #
+ 0x48, // # #
+ 0x48, // # #
+ 0x48, // # #
+ 0xF0, // ####
+ 0x00, //
+ 0x00, //
+
+ // @296 'E' (5 pixels wide)
+ 0xF8, // #####
+ 0x48, // # #
+ 0x60, // ##
+ 0x40, // #
+ 0x48, // # #
+ 0xF8, // #####
+ 0x00, //
+ 0x00, //
+
+ // @304 'F' (5 pixels wide)
+ 0xF8, // #####
+ 0x48, // # #
+ 0x60, // ##
+ 0x40, // #
+ 0x40, // #
+ 0xE0, // ###
+ 0x00, //
+ 0x00, //
+
+ // @312 'G' (5 pixels wide)
+ 0x70, // ###
+ 0x40, // #
+ 0x40, // #
+ 0x58, // # ##
+ 0x50, // # #
+ 0x30, // ##
+ 0x00, //
+ 0x00, //
+
+ // @320 'H' (5 pixels wide)
+ 0xE8, // ### #
+ 0x48, // # #
+ 0x78, // ####
+ 0x48, // # #
+ 0x48, // # #
+ 0xE8, // ### #
+ 0x00, //
+ 0x00, //
+
+ // @328 'I' (5 pixels wide)
+ 0x70, // ###
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x70, // ###
+ 0x00, //
+ 0x00, //
+
+ // @336 'J' (5 pixels wide)
+ 0x38, // ###
+ 0x10, // #
+ 0x10, // #
+ 0x50, // # #
+ 0x50, // # #
+ 0x20, // #
+ 0x00, //
+ 0x00, //
+
+ // @344 'K' (5 pixels wide)
+ 0xD8, // ## ##
+ 0x50, // # #
+ 0x60, // ##
+ 0x70, // ###
+ 0x50, // # #
+ 0xD8, // ## ##
+ 0x00, //
+ 0x00, //
+
+ // @352 'L' (5 pixels wide)
+ 0xE0, // ###
+ 0x40, // #
+ 0x40, // #
+ 0x40, // #
+ 0x48, // # #
+ 0xF8, // #####
+ 0x00, //
+ 0x00, //
+
+ // @360 'M' (5 pixels wide)
+ 0xD8, // ## ##
+ 0xD8, // ## ##
+ 0xD8, // ## ##
+ 0xA8, // # # #
+ 0x88, // # #
+ 0xD8, // ## ##
+ 0x00, //
+ 0x00, //
+
+ // @368 'N' (5 pixels wide)
+ 0xD8, // ## ##
+ 0x68, // ## #
+ 0x68, // ## #
+ 0x58, // # ##
+ 0x58, // # ##
+ 0xE8, // ### #
+ 0x00, //
+ 0x00, //
+
+ // @376 'O' (5 pixels wide)
+ 0x30, // ##
+ 0x48, // # #
+ 0x48, // # #
+ 0x48, // # #
+ 0x48, // # #
+ 0x30, // ##
+ 0x00, //
+ 0x00, //
+
+ // @384 'P' (5 pixels wide)
+ 0xF0, // ####
+ 0x48, // # #
+ 0x48, // # #
+ 0x70, // ###
+ 0x40, // #
+ 0xE0, // ###
+ 0x00, //
+ 0x00, //
+
+ // @392 'Q' (5 pixels wide)
+ 0x30, // ##
+ 0x48, // # #
+ 0x48, // # #
+ 0x48, // # #
+ 0x48, // # #
+ 0x30, // ##
+ 0x18, // ##
+ 0x00, //
+
+ // @400 'R' (5 pixels wide)
+ 0xF0, // ####
+ 0x48, // # #
+ 0x48, // # #
+ 0x70, // ###
+ 0x48, // # #
+ 0xE8, // ### #
+ 0x00, //
+ 0x00, //
+
+ // @408 'S' (5 pixels wide)
+ 0x70, // ###
+ 0x50, // # #
+ 0x20, // #
+ 0x10, // #
+ 0x50, // # #
+ 0x70, // ###
+ 0x00, //
+ 0x00, //
+
+ // @416 'T' (5 pixels wide)
+ 0xF8, // #####
+ 0xA8, // # # #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x70, // ###
+ 0x00, //
+ 0x00, //
+
+ // @424 'U' (5 pixels wide)
+ 0xD8, // ## ##
+ 0x48, // # #
+ 0x48, // # #
+ 0x48, // # #
+ 0x48, // # #
+ 0x30, // ##
+ 0x00, //
+ 0x00, //
+
+ // @432 'V' (5 pixels wide)
+ 0xD8, // ## ##
+ 0x88, // # #
+ 0x48, // # #
+ 0x50, // # #
+ 0x50, // # #
+ 0x30, // ##
+ 0x00, //
+ 0x00, //
+
+ // @440 'W' (5 pixels wide)
+ 0xD8, // ## ##
+ 0x88, // # #
+ 0xA8, // # # #
+ 0xA8, // # # #
+ 0xA8, // # # #
+ 0x50, // # #
+ 0x00, //
+ 0x00, //
+
+ // @448 'X' (5 pixels wide)
+ 0xD8, // ## ##
+ 0x50, // # #
+ 0x20, // #
+ 0x20, // #
+ 0x50, // # #
+ 0xD8, // ## ##
+ 0x00, //
+ 0x00, //
+
+ // @456 'Y' (5 pixels wide)
+ 0xD8, // ## ##
+ 0x88, // # #
+ 0x50, // # #
+ 0x20, // #
+ 0x20, // #
+ 0x70, // ###
+ 0x00, //
+ 0x00, //
+
+ // @464 'Z' (5 pixels wide)
+ 0x78, // ####
+ 0x48, // # #
+ 0x10, // #
+ 0x20, // #
+ 0x48, // # #
+ 0x78, // ####
+ 0x00, //
+ 0x00, //
+
+ // @472 '[' (5 pixels wide)
+ 0x30, // ##
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x30, // ##
+ 0x00, //
+
+ // @480 '\' (5 pixels wide)
+ 0x80, // #
+ 0x40, // #
+ 0x40, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x10, // #
+ 0x00, //
+
+ // @488 ']' (5 pixels wide)
+ 0x60, // ##
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x60, // ##
+ 0x00, //
+
+ // @496 '^' (5 pixels wide)
+ 0x20, // #
+ 0x20, // #
+ 0x50, // # #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @504 '_' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0xF8, // #####
+
+ // @512 '`' (5 pixels wide)
+ 0x20, // #
+ 0x10, // #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+
+ // @520 'a' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x30, // ##
+ 0x10, // #
+ 0x70, // ###
+ 0x78, // ####
+ 0x00, //
+ 0x00, //
+
+ // @528 'b' (5 pixels wide)
+ 0xC0, // ##
+ 0x40, // #
+ 0x70, // ###
+ 0x48, // # #
+ 0x48, // # #
+ 0xF0, // ####
+ 0x00, //
+ 0x00, //
+
+ // @536 'c' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x70, // ###
+ 0x40, // #
+ 0x40, // #
+ 0x70, // ###
+ 0x00, //
+ 0x00, //
+
+ // @544 'd' (5 pixels wide)
+ 0x18, // ##
+ 0x08, // #
+ 0x38, // ###
+ 0x48, // # #
+ 0x48, // # #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+
+ // @552 'e' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x70, // ###
+ 0x70, // ###
+ 0x40, // #
+ 0x30, // ##
+ 0x00, //
+ 0x00, //
+
+ // @560 'f' (5 pixels wide)
+ 0x10, // #
+ 0x20, // #
+ 0x70, // ###
+ 0x20, // #
+ 0x20, // #
+ 0x70, // ###
+ 0x00, //
+ 0x00, //
+
+ // @568 'g' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x38, // ###
+ 0x48, // # #
+ 0x48, // # #
+ 0x38, // ###
+ 0x08, // #
+ 0x30, // ##
+
+ // @576 'h' (5 pixels wide)
+ 0xC0, // ##
+ 0x40, // #
+ 0x70, // ###
+ 0x48, // # #
+ 0x48, // # #
+ 0xE8, // ### #
+ 0x00, //
+ 0x00, //
+
+ // @584 'i' (5 pixels wide)
+ 0x20, // #
+ 0x00, //
+ 0x60, // ##
+ 0x20, // #
+ 0x20, // #
+ 0x70, // ###
+ 0x00, //
+ 0x00, //
+
+ // @592 'j' (5 pixels wide)
+ 0x20, // #
+ 0x00, //
+ 0x70, // ###
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x10, // #
+ 0x70, // ###
+
+ // @600 'k' (5 pixels wide)
+ 0xC0, // ##
+ 0x40, // #
+ 0x58, // # ##
+ 0x70, // ###
+ 0x50, // # #
+ 0xD8, // ## ##
+ 0x00, //
+ 0x00, //
+
+ // @608 'l' (5 pixels wide)
+ 0x60, // ##
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x70, // ###
+ 0x00, //
+ 0x00, //
+
+ // @616 'm' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0xD0, // ## #
+ 0xA8, // # # #
+ 0xA8, // # # #
+ 0xA8, // # # #
+ 0x00, //
+ 0x00, //
+
+ // @624 'n' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0xF0, // ####
+ 0x48, // # #
+ 0x48, // # #
+ 0xC8, // ## #
+ 0x00, //
+ 0x00, //
+
+ // @632 'o' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x30, // ##
+ 0x48, // # #
+ 0x48, // # #
+ 0x30, // ##
+ 0x00, //
+ 0x00, //
+
+ // @640 'p' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0xF0, // ####
+ 0x48, // # #
+ 0x48, // # #
+ 0x70, // ###
+ 0x40, // #
+ 0xE0, // ###
+
+ // @648 'q' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x38, // ###
+ 0x48, // # #
+ 0x48, // # #
+ 0x38, // ###
+ 0x08, // #
+ 0x18, // ##
+
+ // @656 'r' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x78, // ####
+ 0x20, // #
+ 0x20, // #
+ 0x70, // ###
+ 0x00, //
+ 0x00, //
+
+ // @664 's' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x30, // ##
+ 0x20, // #
+ 0x10, // #
+ 0x60, // ##
+ 0x00, //
+ 0x00, //
+
+ // @672 't' (5 pixels wide)
+ 0x00, //
+ 0x40, // #
+ 0xF0, // ####
+ 0x40, // #
+ 0x48, // # #
+ 0x30, // ##
+ 0x00, //
+ 0x00, //
+
+ // @680 'u' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0xD8, // ## ##
+ 0x48, // # #
+ 0x48, // # #
+ 0x38, // ###
+ 0x00, //
+ 0x00, //
+
+ // @688 'v' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0xC8, // ## #
+ 0x48, // # #
+ 0x30, // ##
+ 0x30, // ##
+ 0x00, //
+ 0x00, //
+
+ // @696 'w' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0xD8, // ## ##
+ 0xA8, // # # #
+ 0xA8, // # # #
+ 0x50, // # #
+ 0x00, //
+ 0x00, //
+
+ // @704 'x' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x48, // # #
+ 0x30, // ##
+ 0x30, // ##
+ 0x48, // # #
+ 0x00, //
+ 0x00, //
+
+ // @712 'y' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0xD8, // ## ##
+ 0x50, // # #
+ 0x50, // # #
+ 0x20, // #
+ 0x20, // #
+ 0x60, // ##
+
+ // @720 'z' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x78, // ####
+ 0x50, // # #
+ 0x28, // # #
+ 0x78, // ####
+ 0x00, //
+ 0x00, //
+
+ // @728 '{' (5 pixels wide)
+ 0x10, // #
+ 0x20, // #
+ 0x20, // #
+ 0x60, // ##
+ 0x20, // #
+ 0x20, // #
+ 0x10, // #
+ 0x00, //
+
+ // @736 '|' (5 pixels wide)
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x20, // #
+ 0x00, //
+
+ // @744 '}' (5 pixels wide)
+ 0x40, // #
+ 0x20, // #
+ 0x20, // #
+ 0x30, // ##
+ 0x20, // #
+ 0x20, // #
+ 0x40, // #
+ 0x00, //
+
+ // @752 '~' (5 pixels wide)
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x28, // # #
+ 0x50, // # #
+ 0x00, //
+ 0x00, //
+ 0x00, //
+};
+
+sFONT Font8 = {
+ Font8_Table,
+ 5, /* Width */
+ 8, /* Height */
+};
+
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Function_Prototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup FONTS_Private_Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Utilities/Fonts/fonts.h Wed Sep 25 13:37:39 2019 +0200
@@ -0,0 +1,134 @@
+/**
+ ******************************************************************************
+ * @file fonts.h
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 18-February-2014
+ * @brief Header for fonts.c file
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __FONTS_H
+#define __FONTS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup Utilities
+ * @{
+ */
+
+/** @addtogroup STM32_EVAL
+ * @{
+ */
+
+/** @addtogroup Common
+ * @{
+ */
+
+/** @addtogroup FONTS
+ * @{
+ */
+
+/** @defgroup FONTS_Exported_Types
+ * @{
+ */
+typedef struct _tFont
+{
+ const uint8_t *table;
+ uint16_t Width;
+ uint16_t Height;
+
+} sFONT;
+
+extern sFONT Font24;
+extern sFONT Font20;
+extern sFONT Font16;
+extern sFONT Font12;
+extern sFONT Font8;
+/**
+ * @}
+ */
+
+/** @defgroup FONTS_Exported_Constants
+ * @{
+ */
+#define LINE(x) ((x) * (((sFONT *)BSP_LCD_GetFont())->Height))
+
+/**
+ * @}
+ */
+
+/** @defgroup FONTS_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup FONTS_Exported_Functions
+ * @{
+ */
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __FONTS_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/