summaryrefslogtreecommitdiff
path: root/bsp
diff options
context:
space:
mode:
authorthread-liu <[email protected]>2020-12-03 09:02:36 +0800
committerthread-liu <[email protected]>2020-12-04 17:48:42 +0800
commit10da8d4e447364da4398ced479623a19b31bd058 (patch)
tree66f531ab974b8367436d7956b1213504cb4e4793 /bsp
parentc5612fd2e1196ccae30fe5062667f0f19d1e28ad (diff)
[add] dcmi and ov5640 driver.
Diffstat (limited to 'bsp')
-rw-r--r--bsp/stm32/libraries/STM32MPxx_HAL/SConscript4
-rw-r--r--bsp/stm32/libraries/STM32MPxx_HAL/STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sd.c4
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h2
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c123
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/Kconfig12
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/SConscript8
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/board.h7
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.c203
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.h22
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.c297
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.h45
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.c666
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.h653
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pmic.c62
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.c1602
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.h853
16 files changed, 4522 insertions, 41 deletions
diff --git a/bsp/stm32/libraries/STM32MPxx_HAL/SConscript b/bsp/stm32/libraries/STM32MPxx_HAL/SConscript
index 298fb80409..a55b27925d 100644
--- a/bsp/stm32/libraries/STM32MPxx_HAL/SConscript
+++ b/bsp/stm32/libraries/STM32MPxx_HAL/SConscript
@@ -69,7 +69,9 @@ if GetDepend(['RT_USING_SDIO']):
if GetDepend(['RT_USING_AUDIO']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sai.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sai_ex.c']
-
+if GetDepend(['BSP_USING_DCMI']):
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_dcmi.c']
+
if GetDepend(['BSP_USING_FMC']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_ll_fmc.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_ll_fsmc.c']
diff --git a/bsp/stm32/libraries/STM32MPxx_HAL/STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sd.c b/bsp/stm32/libraries/STM32MPxx_HAL/STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sd.c
index 59044a2669..a7a01539d8 100644
--- a/bsp/stm32/libraries/STM32MPxx_HAL/STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sd.c
+++ b/bsp/stm32/libraries/STM32MPxx_HAL/STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sd.c
@@ -3236,7 +3236,7 @@ uint32_t SD_HighSpeed(SD_HandleTypeDef *hsd)
{
SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance);
}
- loop += 8U;
+ loop ++;
}
if((HAL_GetTick()-Timeout) >= SDMMC_DATATIMEOUT)
@@ -3351,7 +3351,7 @@ uint32_t SD_UltraHighSpeed(SD_HandleTypeDef *hsd)
{
SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance);
}
- loop += 8U;
+ loop ++;
}
if((HAL_GetTick()-Timeout) >= SDMMC_DATATIMEOUT)
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h b/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h
index 572739c375..3b5a7e76df 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h
@@ -37,7 +37,7 @@
/*#define HAL_CRC_MODULE_ENABLED */
/*#define HAL_CRYP_MODULE_ENABLED */
#define HAL_DAC_MODULE_ENABLED
-/*#define HAL_DCMI_MODULE_ENABLED */
+#define HAL_DCMI_MODULE_ENABLED
/*#define HAL_DSI_MODULE_ENABLED */
/*#define HAL_DFSDM_MODULE_ENABLED */
/*#define HAL_DTS_MODULE_ENABLED */
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c b/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
index 5bf014d8b9..1a712c3f8d 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
@@ -1398,6 +1398,129 @@ void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)
}
/**
+* @brief DCMI MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hdcmi: DCMI handle pointer
+* @retval None
+*/
+void HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(hdcmi->Instance==DCMI)
+ {
+ /* USER CODE BEGIN DCMI_MspInit 0 */
+
+ /* USER CODE END DCMI_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_DCMI_CLK_ENABLE();
+
+ __HAL_RCC_GPIOH_CLK_ENABLE();
+ __HAL_RCC_GPIOE_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOI_CLK_ENABLE();
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+
+ /**DCMI GPIO Configuration
+ PH9 ------> DCMI_D0
+ PH10 ------> DCMI_D1
+ PH11 ------> DCMI_D2
+ PH12 ------> DCMI_D3
+ PH14 ------> DCMI_D4
+ PI4 ------> DCMI_D5
+ PB8 ------> DCMI_D6
+ PE6 ------> DCMI_D7
+ PH8 ------> DCMI_HSYNC
+ PB7 ------> DCMI_VSYNC
+ PA6 ------> DCMI_PIXCLK
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_14|GPIO_PIN_8
+ |GPIO_PIN_9|GPIO_PIN_12;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_6;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_4;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_6;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ HAL_NVIC_SetPriority(DCMI_IRQn, 0x03, 0x00);
+ HAL_NVIC_EnableIRQ(DCMI_IRQn);
+
+ /* USER CODE BEGIN DCMI_MspInit 1 */
+ /* USER CODE END DCMI_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief DCMI MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hdcmi: DCMI handle pointer
+* @retval None
+*/
+void HAL_DCMI_MspDeInit(DCMI_HandleTypeDef* hdcmi)
+{
+ if(hdcmi->Instance==DCMI)
+ {
+ /* USER CODE BEGIN DCMI_MspDeInit 0 */
+
+ /* USER CODE END DCMI_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_DCMI_CLK_DISABLE();
+
+ /**DCMI GPIO Configuration
+ PH10 ------> DCMI_D1
+ PH11 ------> DCMI_D2
+ PH14 ------> DCMI_D4
+ PH8 ------> DCMI_HSYNC
+ PH9 ------> DCMI_D0
+ PE6 ------> DCMI_D7
+ PH12 ------> DCMI_D3
+ PB7 ------> DCMI_VSYNC
+ PI4 ------> DCMI_D5
+ PA6 ------> DCMI_PIXCLK
+ PB8 ------> DCMI_D6
+ */
+ HAL_GPIO_DeInit(GPIOH, GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_14|GPIO_PIN_8
+ |GPIO_PIN_9|GPIO_PIN_12);
+
+ HAL_GPIO_DeInit(GPIOE, GPIO_PIN_6);
+
+ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7|GPIO_PIN_8);
+
+ HAL_GPIO_DeInit(GPIOI, GPIO_PIN_4);
+
+ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_6);
+
+ /* USER CODE BEGIN DCMI_MspDeInit 1 */
+ HAL_DMA_DeInit(hdcmi->DMA_Handle);
+ /* USER CODE END DCMI_MspDeInit 1 */
+ }
+
+}
+
+/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/Kconfig b/bsp/stm32/stm32mp157a-st-ev1/board/Kconfig
index 1e601d8377..13d562ea95 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/Kconfig
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/Kconfig
@@ -72,6 +72,18 @@ menu "Onboard Peripheral Drivers"
select BSP_USING_I2C2
default n
+ config BSP_USING_DCMI
+ bool "Enable CAMERA (ov5640)"
+ select BSP_USING_MFX
+ select BSP_USING_PMIC
+ select BSP_USING_I2C
+ select BSP_USING_I2C2
+ default n
+
+ config BSP_USING_MFX
+ bool "Enable Multi Function eXpander"
+ default n
+
endmenu
menu "On-chip Peripheral Drivers"
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/SConscript b/bsp/stm32/stm32mp157a-st-ev1/board/SConscript
index 26ec814da7..2d43e1cf64 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/SConscript
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/SConscript
@@ -32,6 +32,14 @@ if GetDepend(['BSP_USING_AUDIO']):
src += Glob('ports/drv_wm8994.c')
src += Glob('ports/drv_sound.c')
+if GetDepend(['BSP_USING_DCMI']):
+ src += Glob('ports/drv_dcmi.c')
+ src += Glob('ports/drv_ov5640.c')
+
+if GetDepend(['BSP_USING_MFX']):
+ src += Glob('ports/drv_mfx.c')
+ src += Glob('ports/mfxstm32l152.c')
+
if GetDepend(['BSP_USING_OPENAMP']):
src += Glob('CubeMX_Config/CM4/Src/ipcc.c')
src += Glob('CubeMX_Config/CM4/Src/openamp.c')
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/board.h b/bsp/stm32/stm32mp157a-st-ev1/board/board.h
index 18cab2141c..81cdaa92fb 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/board.h
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/board.h
@@ -23,14 +23,9 @@ extern "C" {
#endif
#define STM32_FLASH_START_ADRESS ((uint32_t)0x10000000)
-#if defined(BSP_USING_OPENAMP)
-#define STM32_FLASH_SIZE (64 * 1024)
-#else
-#define STM32_FLASH_SIZE (256 * 1024)
-#endif
+#define STM32_FLASH_SIZE (191 * 1024)
#define STM32_FLASH_END_ADDRESS ((uint32_t)(STM32_FLASH_START_ADRESS + STM32_FLASH_SIZE))
-
#if defined(BSP_USING_OPENAMP)
#define STM32_SRAM_BEGIN (uint32_t)0x10030000
#else
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.c
new file mode 100644
index 0000000000..def5dfd461
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-27 thread-liu the first version
+ */
+
+#include "board.h"
+
+#if defined(BSP_USING_DCMI)
+#include "drv_dcmi.h"
+
+#define DRV_DEBUG
+#define LOG_TAG "drv.dcmi"
+#include <drv_log.h>
+
+struct stm32_dcmi
+{
+ struct rt_device dev;
+};
+static struct stm32_dcmi rt_dcmi = {0};
+DCMI_HandleTypeDef dcmi = {0};
+DMA_HandleTypeDef hdma_dcmi = {0};
+
+extern void jpeg_data_process(void);
+
+static void rt_hw_dmci_dma_init(void)
+{
+ __HAL_RCC_DMAMUX_CLK_ENABLE();
+ __HAL_RCC_DMA1_CLK_ENABLE();
+
+ hdma_dcmi.Instance = DMA1_Stream3;
+ hdma_dcmi.Init.Request = DMA_REQUEST_DCMI;
+ hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ hdma_dcmi.Init.Mode = DMA_CIRCULAR;
+ hdma_dcmi.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
+ hdma_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_dcmi.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+ HAL_DMA_Init(&hdma_dcmi);
+
+ __HAL_LINKDMA(&dcmi, DMA_Handle, hdma_dcmi);
+
+ HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 0x02, 0);
+ HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);
+}
+
+void rt_hw_dcmi_dma_config(rt_uint32_t dst_addr1, rt_uint32_t dst_addr2, rt_uint16_t len)
+{
+ HAL_DMAEx_MultiBufferStart(&hdma_dcmi, (rt_uint32_t)&DCMI->DR, dst_addr1, dst_addr2, len);
+ __HAL_DMA_ENABLE_IT(&hdma_dcmi, DMA_IT_TC);
+}
+
+static rt_err_t rt_hw_dcmi_init(DCMI_HandleTypeDef *device)
+{
+ RT_ASSERT(device != RT_NULL);
+
+ device->Instance = DCMI;
+ device->Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
+ device->Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;
+ device->Init.VSPolarity = DCMI_VSPOLARITY_LOW;
+ device->Init.HSPolarity = DCMI_HSPOLARITY_LOW;
+ device->Init.CaptureRate = DCMI_CR_ALL_FRAME;
+ device->Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
+ device->Init.JPEGMode = DCMI_JPEG_DISABLE;
+ device->Init.ByteSelectMode = DCMI_BSM_ALL;
+ device->Init.ByteSelectStart = DCMI_OEBS_ODD;
+ device->Init.LineSelectMode = DCMI_LSM_ALL;
+ device->Init.LineSelectStart = DCMI_OELS_ODD;
+
+ if (HAL_DCMI_Init(device) != HAL_OK)
+ {
+ LOG_E("dcmi init error!");
+ return RT_ERROR;
+ }
+
+ DCMI->IER = 0x0;
+
+ __HAL_DCMI_ENABLE_IT(device, DCMI_IT_FRAME);
+ __HAL_DCMI_ENABLE(device);
+
+ rt_hw_dmci_dma_init();
+
+ return RT_EOK;
+}
+
+void DCMI_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_DCMI_IRQHandler(&dcmi);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+/* Capture a frame of the image */
+void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ jpeg_data_process();
+ __HAL_DCMI_ENABLE_IT(&dcmi,DCMI_IT_FRAME);
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void DMA1_Stream3_IRQHandler(void)
+{
+ extern void rt_hw_camera_rx_callback(void);
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ if(__HAL_DMA_GET_FLAG(&hdma_dcmi, DMA_FLAG_TCIF3_7)!=RESET)
+ {
+ __HAL_DMA_CLEAR_FLAG(&hdma_dcmi, DMA_FLAG_TCIF3_7);
+ rt_hw_camera_rx_callback();
+ }
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+static rt_err_t rt_dcmi_init(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+ rt_err_t result = RT_EOK;
+
+ result = rt_hw_dcmi_init(&dcmi);
+ if (result != RT_EOK)
+ {
+ return result;
+ }
+
+ return result;
+}
+
+static rt_err_t rt_dcmi_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_dcmi_close(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_dcmi_control(rt_device_t dev, int cmd, void *args)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_size_t rt_dcmi_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_size_t rt_dcmi_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+int dcmi_init(void)
+{
+ rt_dcmi.dev.type = RT_Device_Class_Miscellaneous;
+ rt_dcmi.dev.init = rt_dcmi_init;
+ rt_dcmi.dev.open = rt_dcmi_open;
+ rt_dcmi.dev.close = rt_dcmi_close;
+ rt_dcmi.dev.read = rt_dcmi_read;
+ rt_dcmi.dev.write = rt_dcmi_write;
+ rt_dcmi.dev.control = rt_dcmi_control;
+ rt_dcmi.dev.user_data = RT_NULL;
+
+ rt_device_register(&rt_dcmi.dev, "dcmi", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
+
+ LOG_I("dcmi init success!");
+
+ return RT_EOK;
+}
+INIT_BOARD_EXPORT(dcmi_init);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.h
new file mode 100644
index 0000000000..39fe3bdd26
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-27 thread-liu first version
+ */
+
+#ifndef __DRV_DCMI_H__
+#define __DRV_DCMI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.c
new file mode 100644
index 0000000000..071f833a10
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-08-08 thread-liu first version
+ */
+
+#include "board.h"
+
+#include "mfxstm32l152.h"
+#define DRV_DEBUG
+#define LOG_TAG "drv.mfx"
+#include <drv_log.h>
+
+#define CHIP_ADDRESS 0x42 /* mfx address */
+#define I2C_NAME "i2c2"
+
+struct st_mfx
+{
+ struct rt_device dev;
+ struct rt_i2c_bus_device *i2c_bus;
+ rt_uint8_t id;
+ rt_uint16_t type;
+};
+static struct st_mfx rt_mfx = {0};
+static IO_DrvTypeDef *IoDrv = NULL;
+
+static rt_err_t read_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint16_t len, rt_uint8_t *buf)
+{
+ struct rt_i2c_msg msg[2] = {0, 0};
+
+ RT_ASSERT(bus != RT_NULL);
+
+ msg[0].addr = CHIP_ADDRESS;
+ msg[0].flags = RT_I2C_WR;
+ msg[0].buf = &reg;
+ msg[0].len = 1;
+
+ msg[1].addr = CHIP_ADDRESS;
+ msg[1].flags = RT_I2C_RD;
+ msg[1].len = len;
+ msg[1].buf = buf;
+
+ if (rt_i2c_transfer(bus, msg, 2) == 2)
+ {
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+/* i2c write reg */
+static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t data)
+{
+ rt_uint8_t buf[2];
+ struct rt_i2c_msg msgs;
+
+ RT_ASSERT(bus != RT_NULL);
+ buf[0] = reg;
+ buf[1] = data;
+
+ msgs.addr = CHIP_ADDRESS;
+ msgs.flags = RT_I2C_WR;
+ msgs.buf = buf;
+ msgs.len = sizeof(buf);
+
+ if (rt_i2c_transfer(bus, &msgs, 1) == 1)
+ {
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+void MFX_IO_Init(void)
+{
+ rt_mfx.i2c_bus = rt_i2c_bus_device_find(I2C_NAME);
+ if (rt_mfx.i2c_bus == RT_NULL)
+ {
+ LOG_E("can't find %c deivce", I2C_NAME);
+ }
+}
+
+void MFX_IO_DeInit(void)
+{
+}
+
+void MFX_IO_ITConfig(void)
+{
+ static rt_uint8_t mfx_io_it_enabled = 0;
+ GPIO_InitTypeDef gpio_init_structure;
+
+ if(mfx_io_it_enabled == 0)
+ {
+ mfx_io_it_enabled = 1;
+ /* Enable the GPIO EXTI clock */
+ __HAL_RCC_GPIOI_CLK_ENABLE();
+
+ gpio_init_structure.Pin = GPIO_PIN_8;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_LOW;
+ gpio_init_structure.Mode = GPIO_MODE_IT_RISING;
+ HAL_GPIO_Init(GPIOI, &gpio_init_structure);
+
+ /* Enable and set GPIO EXTI Interrupt to the lowest priority */
+ HAL_NVIC_SetPriority((IRQn_Type)(EXTI8_IRQn), 0x04, 0x00);
+ HAL_NVIC_EnableIRQ((IRQn_Type)(EXTI8_IRQn));
+ }
+}
+
+void MFX_IO_Write(rt_uint16_t Addr, rt_uint8_t Reg, rt_uint8_t Value)
+{
+ write_reg(rt_mfx.i2c_bus, Reg, Value);
+}
+
+rt_uint8_t MFX_IO_Read(rt_uint16_t Addr, rt_uint8_t Reg)
+{
+ rt_uint8_t value = 0;
+ read_reg(rt_mfx.i2c_bus, Reg, 1, &value);
+
+ return value;
+}
+
+rt_uint16_t MFX_IO_ReadMultiple(rt_uint16_t Addr, rt_uint8_t Reg, rt_uint8_t *Buffer, rt_uint16_t Length)
+{
+ return read_reg(rt_mfx.i2c_bus, Reg, Length, Buffer);
+}
+
+RT_WEAK void MFX_IO_Delay(rt_uint32_t Delay)
+{
+ rt_thread_delay(Delay);
+}
+
+RT_WEAK void MFX_IO_Wakeup(void)
+{
+}
+
+RT_WEAK void MFX_IO_EnableWakeupPin(void)
+{
+}
+
+rt_uint8_t BSP_IO_DeInit(void)
+{
+ IoDrv = NULL;
+ return RT_EOK;
+}
+
+rt_uint32_t BSP_IO_ITGetStatus(rt_uint32_t IoPin)
+{
+ /* Return the IO Pin IT status */
+ return (IoDrv->ITStatus(0, IoPin));
+}
+
+/**
+ * @brief Clears all the IO IT pending bits.
+ * @retval None
+ */
+void BSP_IO_ITClear(void)
+{
+ /* Clear all IO IT pending bits */
+ IoDrv->ClearIT(0, MFXSTM32L152_GPIO_PINS_ALL);
+}
+
+void BSP_IO_ITClearPin(rt_uint32_t IO_Pins_To_Clear)
+{
+ /* Clear only the selected list of IO IT pending bits */
+ IoDrv->ClearIT(0, IO_Pins_To_Clear);
+}
+
+/**
+ * @brief Configures the IO pin(s) according to IO mode structure value.
+ * @param IoPin: IO pin(s) to be configured.
+ * This parameter can be one of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+ * @param IoMode: IO pin mode to configure
+ * This parameter can be one of the following values:
+ * @arg IO_MODE_INPUT
+ * @arg IO_MODE_OUTPUT
+ * @arg IO_MODE_IT_RISING_EDGE
+ * @arg IO_MODE_IT_FALLING_EDGE
+ * @arg IO_MODE_IT_LOW_LEVEL
+ * @arg IO_MODE_IT_HIGH_LEVEL
+ * @arg IO_MODE_ANALOG
+ * @arg IO_MODE_OFF
+ * @arg IO_MODE_INPUT_PU,
+ * @arg IO_MODE_INPUT_PD,
+ * @arg IO_MODE_OUTPUT_OD,
+ * @arg IO_MODE_OUTPUT_OD_PU,
+ * @arg IO_MODE_OUTPUT_OD_PD,
+ * @arg IO_MODE_OUTPUT_PP,
+ * @arg IO_MODE_OUTPUT_PP_PU,
+ * @arg IO_MODE_OUTPUT_PP_PD,
+ * @arg IO_MODE_IT_RISING_EDGE_PU
+ * @arg IO_MODE_IT_FALLING_EDGE_PU
+ * @arg IO_MODE_IT_LOW_LEVEL_PU
+ * @arg IO_MODE_IT_HIGH_LEVEL_PU
+ * @arg IO_MODE_IT_RISING_EDGE_PD
+ * @arg IO_MODE_IT_FALLING_EDGE_PD
+ * @arg IO_MODE_IT_LOW_LEVEL_PD
+ * @arg IO_MODE_IT_HIGH_LEVEL_PD
+ * @retval RT_EOK if all initializations are OK. Other value if error.
+ */
+rt_uint8_t rt_mfx_pin_mode(rt_uint32_t IoPin, IO_ModeTypedef IoMode)
+{
+ /* Configure the selected IO pin(s) mode */
+ IoDrv->Config(0, IoPin, IoMode);
+
+ return RT_EOK;
+}
+
+/**
+ * @brief Sets the IRQ_OUT pin polarity and type
+ * @param IoIrqOutPinPolarity: High/Low
+ * @param IoIrqOutPinType: OpenDrain/PushPull
+ * @retval OK
+ */
+rt_uint8_t rt_mfx_config_irq(rt_uint8_t IoIrqOutPinPolarity, rt_uint8_t IoIrqOutPinType)
+{
+ if((rt_mfx.id == MFXSTM32L152_ID_1) || (rt_mfx.id == MFXSTM32L152_ID_2))
+ {
+ /* Initialize the IO driver structure */
+ mfxstm32l152_SetIrqOutPinPolarity(0, IoIrqOutPinPolarity);
+ mfxstm32l152_SetIrqOutPinType(0, IoIrqOutPinType);
+ }
+
+ return RT_EOK;
+}
+
+/**
+ * @brief Sets the selected pins state.
+ * @param IoPin: Selected pins to write.
+ * This parameter can be any combination of the IO pins.
+ * @param PinState: New pins state to write
+ * @retval None
+ */
+void rt_mfx_pin_write(rt_uint32_t IoPin, rt_base_t PinState)
+{
+ /* Set the Pin state */
+ IoDrv->WritePin(0, IoPin, PinState);
+}
+
+/**
+ * @brief Gets the selected pins current state.
+ * @param IoPin: Selected pins to read.
+ * This parameter can be any combination of the IO pins.
+ * @retval The current pins state
+ */
+rt_uint32_t rt_mfx_pin_read(rt_uint32_t IoPin)
+{
+ return(IoDrv->ReadPin(0, IoPin));
+}
+
+/**
+ * @brief Toggles the selected pins state.
+ * @param IoPin: Selected pins to toggle.
+ * This parameter can be any combination of the IO pins.
+ * @note This function is only used to toggle one pin in the same time
+ * @retval None
+ */
+void rt_mfx_pin_toggle(rt_uint32_t IoPin)
+{
+ /* Toggle the current pin state */
+ if(IoDrv->ReadPin(0, IoPin) != 0)
+ {
+ IoDrv->WritePin(0, IoPin, 0); /* Reset */
+ }
+ else
+ {
+ IoDrv->WritePin(0, IoPin, 1); /* Set */
+ }
+}
+
+int rt_mfx_init(void)
+{
+ /* Read ID and verify the MFX is ready */
+ rt_mfx.id = mfxstm32l152_io_drv.ReadID(0);
+ if((rt_mfx.id == MFXSTM32L152_ID_1) || (rt_mfx.id == MFXSTM32L152_ID_2))
+ {
+ /* Initialize the IO driver structure */
+ IoDrv = &mfxstm32l152_io_drv;
+
+ /* Initialize MFX */
+ IoDrv->Init(0);
+ IoDrv->Start(0, IO_PIN_ALL);
+
+ LOG_I("mfx init success, id: 0x%x", rt_mfx.id);
+
+ return RT_EOK;
+ }
+ LOG_I("mfx init error, id: 0x%x", rt_mfx.id);
+
+ return RT_ERROR;
+}
+INIT_DEVICE_EXPORT(rt_mfx_init);
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.h
new file mode 100644
index 0000000000..a0cf46777c
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-08-08 thread-liu first version
+ */
+
+#ifndef __DRV_MFX_H__
+#define __DRV_MFX_H__
+
+#include "board.h"
+#include "mfxstm32l152.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ BSP_IO_PIN_RESET = 0,
+ BSP_IO_PIN_SET = 1
+}BSP_IO_PinStateTypeDef;
+
+#define CAMERA_RST1 MFXSTM32L152_AGPIO_PIN_3
+#define CAMERA_XSDN MFXSTM32L152_AGPIO_PIN_2
+#define CARMERA_PLUG MFXSTM32L152_GPIO_PIN_12
+
+void rt_mfx_init(void);
+rt_uint32_t BSP_IO_ITGetStatus(rt_uint32_t IoPin);
+void BSP_IO_ITClear(void);
+void BSP_IO_ITClearPin(rt_uint32_t IO_Pins_To_Clear);
+rt_uint8_t rt_mfx_pin_mode(rt_uint32_t IoPin, IO_ModeTypedef IoMode);
+rt_uint8_t rt_mfx_config_irq(rt_uint8_t IoIrqOutPinPolarity, rt_uint8_t IoIrqOutPinType);
+void rt_mfx_pin_write(rt_uint32_t IoPin, rt_base_t PinState);
+rt_uint32_t rt_mfx_pin_read(rt_uint32_t IoPin);
+void rt_mfx_pin_toggle(rt_uint32_t IoPin);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.c
new file mode 100644
index 0000000000..b8dada9d5a
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.c
@@ -0,0 +1,666 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-08-03 thread-liu the first version
+ */
+
+#include "board.h"
+
+#if defined(BSP_USING_DCMI)
+
+#include "drv_mfx.h"
+#include <dfs_posix.h>
+#include "drv_ov5640.h"
+
+//#define DRV_DEBUG
+//#define CAMERA_DUMP
+#define LOG_TAG "drv.ov5640"
+#include <drv_log.h>
+
+#define CHIP_ADDRESS 0x3C /* OV5640 address */
+#define I2C_NAME "i2c2"
+
+#define JPEG_BUF_SIZE 8 * 1024
+#define JPEG_LINE_SIZE 1 * 1024
+
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+__attribute__((at(0x2FFCC000)))
+#elif defined(__GNUC__)
+__attribute__((at(0x2FFCC000)))
+#elif defined(__ICCARM__)
+#pragma location = 0x2FFCC000
+#endif
+static rt_int32_t JPEG_DATA_BUF[JPEG_BUF_SIZE];
+
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+__attribute__((at(0x2FFDC000)))
+#elif defined(__GNUC__)
+__attribute__((at(0x2FFDC000)))
+#elif defined(__ICCARM__)
+#pragma location = 0x2FFDC000
+#endif
+static rt_int32_t JPEG_LINE_BUF[2][JPEG_LINE_SIZE];
+
+
+volatile rt_uint32_t jpeg_data_len = 0;
+volatile rt_uint8_t jpeg_data_ok = 0;
+struct rt_i2c_bus_device *i2c_bus = RT_NULL;
+extern DCMI_HandleTypeDef dcmi;
+extern DMA_HandleTypeDef hdma_dcmi;
+
+#if defined(CAMERA_DUMP)
+#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
+static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
+{
+ unsigned char *buf = (unsigned char *)ptr;
+ int i, j;
+
+ for (i = 0; i < buflen; i += 16)
+ {
+ rt_kprintf("%08x:", i);
+
+ for (j = 0; j < 16; j++)
+ {
+ if (i + j < buflen)
+ {
+ rt_kprintf("%02x", buf[i + j]);
+ }
+ else
+ {
+ rt_kprintf(" ");
+ }
+ }
+ rt_kprintf(" ");
+
+ for (j = 0; j < 16; j++)
+ {
+ if (i + j < buflen)
+ {
+ rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
+ }
+ }
+ rt_kprintf("\n");
+ }
+}
+#endif
+
+static rt_err_t read_reg(struct rt_i2c_bus_device *bus, rt_uint16_t reg, rt_uint8_t len, rt_uint8_t *buf)
+{
+ struct rt_i2c_msg msg[2] = {0, 0};
+ static rt_uint8_t i2c_reg[2] = {0, 0};
+
+ RT_ASSERT(bus != RT_NULL);
+
+ i2c_reg[0] = ((uint16_t)(reg >> 8) & 0xFF);
+ i2c_reg[1] = ((uint16_t)(reg & 0xFF));
+
+ msg[0].addr = CHIP_ADDRESS;
+ msg[0].flags = RT_I2C_WR;
+ msg[0].buf = i2c_reg;
+ msg[0].len = 2;
+
+ msg[1].addr = CHIP_ADDRESS;
+ msg[1].flags = RT_I2C_RD;
+ msg[1].len = len;
+ msg[1].buf = buf;
+
+ if (rt_i2c_transfer(bus, msg, 2) == 2)
+ {
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+/* i2c write reg */
+static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint16_t reg, rt_uint8_t data)
+{
+ rt_uint8_t buf[3];
+ struct rt_i2c_msg msgs;
+
+ RT_ASSERT(bus != RT_NULL);
+
+ buf[0] = ((uint16_t)(reg >> 8) & 0xFF);
+ buf[1] = ((uint16_t)(reg)&0xFF);
+
+ buf[2] = data;
+
+ msgs.addr = CHIP_ADDRESS;
+ msgs.flags = RT_I2C_WR;
+ msgs.buf = buf;
+ msgs.len = 3;
+
+ if (rt_i2c_transfer(bus, &msgs, 1) == 1)
+ {
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+static rt_err_t ov5640_read_id(struct rt_i2c_bus_device *bus, rt_uint16_t *id)
+{
+ rt_uint8_t read_value[2];
+
+ read_reg(bus, 0x300A, 1, &read_value[0]);
+ read_reg(bus, 0x300B, 1, &read_value[1]);
+ *id = ((uint16_t)(read_value[0] << 8) & 0xFF00);
+ *id |= ((uint16_t)(read_value[1]) & 0x00FF);
+
+ if (*id != OV5640_ID)
+ {
+ LOG_E("ov5640 init error, id: 0x%04x", *id);
+ return RT_ERROR;
+ }
+
+ LOG_I("ov5640 init success, id: 0x%04x", *id);
+
+ return RT_EOK;
+}
+
+static rt_err_t ov5640_hard_reset(struct rt_i2c_bus_device *bus)
+{
+ /* Camera sensor RESET sequence */
+ rt_mfx_pin_mode(CAMERA_RST1, IO_MODE_OUTPUT);
+ rt_mfx_pin_mode(CAMERA_XSDN, IO_MODE_OUTPUT);
+
+ /* Assert the camera STANDBY pin (active high) */
+ rt_mfx_pin_write(CAMERA_XSDN, BSP_IO_PIN_SET);
+
+ /* Assert the camera RSTI pin (active low) */
+ rt_mfx_pin_write(CAMERA_RST1, BSP_IO_PIN_RESET);
+
+ rt_thread_delay(100); /* RST and XSDN signals asserted during 100ms */
+
+ /* De-assert the camera STANDBY pin (active high) */
+ rt_mfx_pin_write(CAMERA_XSDN, BSP_IO_PIN_RESET);
+
+ rt_thread_delay(3); /* RST de-asserted and XSDN asserted during 3ms */
+
+ /* De-assert the camera RSTI pin (active low) */
+ rt_mfx_pin_write(CAMERA_RST1, BSP_IO_PIN_SET);
+
+ rt_thread_delay(6); /* RST de-asserted during 3ms */
+
+ return RT_EOK;
+}
+
+void OV5640_Flash_Ctrl(struct rt_i2c_bus_device *bus, rt_uint8_t sw)
+{
+ write_reg(bus, 0x3016, 0X02);
+ write_reg(bus, 0x301C, 0X02);
+ if (sw)
+ {
+ write_reg(bus, 0X3019, 0X02);
+ }
+ else
+ {
+ write_reg(bus, 0X3019, 0X00);
+ }
+}
+
+static rt_err_t ov5640_config(struct rt_i2c_bus_device *bus)
+{
+ rt_uint32_t i = 0;
+ rt_uint8_t value = 0;
+
+ write_reg(bus, 0x3103, 0X11); /* system clock from pad, bit[1] */
+ write_reg(bus, 0X3008, 0X82); /* soft reset */
+
+ rt_thread_delay(10);
+
+ for (i = 0; i < (sizeof(RGB565_Init) / 4); i++)
+ {
+ write_reg(bus, RGB565_Init[i][0], RGB565_Init[i][1]);
+ rt_thread_delay(10);
+ read_reg(bus, RGB565_Init[i][0], 1, &value);
+
+ if (RGB565_Init[i][1] != value)
+ {
+ LOG_D("error reg value[0x%x]:0x%02x - 0x%02x", RGB565_Init[i][0], RGB565_Init[i][1], value);
+ }
+ }
+
+ OV5640_Flash_Ctrl(bus, 1); /* open camera flash*/
+ rt_thread_delay(3);
+ OV5640_Flash_Ctrl(bus, 0); /* close camera flash*/
+
+ return RT_EOK;
+}
+
+/* JPEG */
+void ov5640_jpeg_mode(struct rt_i2c_bus_device *bus)
+{
+ rt_uint16_t i = 0;
+ for (i = 0; i < (sizeof(OV5640_jpeg_reg_tbl) / 4); i++)
+ {
+ write_reg(bus, OV5640_jpeg_reg_tbl[i][0], OV5640_jpeg_reg_tbl[i][1]);
+ }
+}
+
+/* RGB565 */
+void ov5640_rgb565_mode(struct rt_i2c_bus_device *bus)
+{
+ rt_uint16_t i = 0;
+ for (i = 0; i < (sizeof(ov5640_rgb565_reg_tbl) / 4); i++)
+ {
+ write_reg(bus, ov5640_rgb565_reg_tbl[i][0], ov5640_rgb565_reg_tbl[i][1]);
+ }
+
+ write_reg(bus, 0x3821, 0x06);
+}
+
+rt_uint8_t ov5640_focus_init(struct rt_i2c_bus_device *bus)
+{
+ rt_uint16_t tickstart = 0 ,i = 0;
+ rt_uint16_t addr = 0x8000;
+ rt_uint8_t state = 0x8F;
+
+ write_reg(bus, 0x3000, 0x20); //reset MCU
+ for (i = 0; i < sizeof(OV5640_AF_Config); i++)
+ {
+ write_reg(bus, addr, OV5640_AF_Config[i]);
+ addr++;
+ }
+ write_reg(bus, 0x3022, 0x00);
+ write_reg(bus, 0x3023, 0x00);
+ write_reg(bus, 0x3024, 0x00);
+ write_reg(bus, 0x3025, 0x00);
+ write_reg(bus, 0x3026, 0x00);
+ write_reg(bus, 0x3027, 0x00);
+ write_reg(bus, 0x3028, 0x00);
+ write_reg(bus, 0x3029, 0x7f);
+ write_reg(bus, 0x3000, 0x00);
+ i = 0;
+
+ tickstart = rt_tick_get();
+ do
+ {
+ read_reg(bus, 0x3029, 1, &state);
+ if (rt_tick_get() - tickstart > 1000)
+ {
+ return RT_ERROR;
+ }
+ } while (state != 0x70);
+
+ return RT_EOK;
+}
+
+void ov5640_set_light(struct rt_i2c_bus_device *bus, rt_uint8_t mode)
+{
+ rt_uint8_t i = 0;
+ write_reg(bus, 0x3212, 0x03); //start group 3
+
+ for (i = 0; i < 7; i++)
+ {
+ write_reg(bus, 0x3400 + i, OV5640_LIGHTMODE_TBL[mode][i]);
+ }
+
+ write_reg(bus, 0x3212, 0x13); //end group 3
+ write_reg(bus, 0x3212, 0xa3); //launch group 3
+}
+
+/* sat:0~6 */
+void ov5640_color_saturation(struct rt_i2c_bus_device *bus, rt_uint8_t sat)
+{
+ rt_uint8_t i = 0;
+ write_reg(bus, 0x3212, 0x03); //start group 3
+ write_reg(bus, 0x5381, 0x1c);
+ write_reg(bus, 0x5382, 0x5a);
+ write_reg(bus, 0x5383, 0x06);
+ for (i = 0; i < 6; i++)
+ {
+ write_reg(bus, 0x5384 + i, OV5640_SATURATION_TBL[sat][i]);
+ }
+ write_reg(bus, 0x538b, 0x98);
+ write_reg(bus, 0x538a, 0x01);
+ write_reg(bus, 0x3212, 0x13); //end group 3
+ write_reg(bus, 0x3212, 0xa3); //launch group 3
+}
+
+/* bright:0~8 */
+void ov5640_set_brightness(struct rt_i2c_bus_device *bus, rt_uint8_t bright)
+{
+ rt_uint8_t brtval;
+ if (bright < 4)
+ {
+ brtval = 4 - bright;
+ }
+ else
+ {
+ brtval = bright - 4;
+ }
+ write_reg(bus, 0x3212, 0x03); //start group 3
+ write_reg(bus, 0x5587, brtval << 4);
+ if (bright < 4)
+ {
+ write_reg(bus, 0x5588, 0x09);
+ }
+ else
+ {
+ write_reg(bus, 0x5588, 0x01);
+ }
+ write_reg(bus, 0x3212, 0x13); //end group 3
+ write_reg(bus, 0x3212, 0xa3); //launch group 3
+}
+
+/* contrast:0~6 */
+void ov5640_contrast(struct rt_i2c_bus_device *bus, rt_uint8_t contrast)
+{
+ rt_uint8_t reg0val = 0x00;
+ rt_uint8_t reg1val = 0x20;
+ switch (contrast)
+ {
+ case 0:
+ reg1val = reg0val = 0X14;
+ break;
+
+ case 1:
+ reg1val = reg0val = 0X18;
+ break;
+
+ case 2:
+ reg1val = reg0val = 0X1C;
+ break;
+
+ case 4:
+ reg0val = 0X10;
+ reg1val = 0X24;
+ break;
+
+ case 5:
+ reg0val = 0X18;
+ reg1val = 0X28;
+ break;
+
+ case 6:
+ reg0val = 0X1C;
+ reg1val = 0X2C;
+
+ break;
+ }
+ write_reg(bus, 0x3212, 0x03); //start group 3
+ write_reg(bus, 0x5585, reg0val);
+ write_reg(bus, 0x5586, reg1val);
+ write_reg(bus, 0x3212, 0x13); //end group 3
+ write_reg(bus, 0x3212, 0xa3); //launch group 3
+}
+/* sharp:0~33 */
+void ov5640_set_sharpness(struct rt_i2c_bus_device *bus, rt_uint8_t sharp)
+{
+ if (sharp < 33)
+ {
+ write_reg(bus, 0x5308, 0x65);
+ write_reg(bus, 0x5302, sharp);
+ }
+ else
+ {
+ write_reg(bus, 0x5308, 0x25);
+ write_reg(bus, 0x5300, 0x08);
+ write_reg(bus, 0x5301, 0x30);
+ write_reg(bus, 0x5302, 0x10);
+ write_reg(bus, 0x5303, 0x00);
+ write_reg(bus, 0x5309, 0x08);
+ write_reg(bus, 0x530a, 0x30);
+ write_reg(bus, 0x530b, 0x04);
+ write_reg(bus, 0x530c, 0x06);
+ }
+}
+
+rt_uint8_t ov5640_focus_constant(struct rt_i2c_bus_device *bus)
+{
+ rt_uint8_t temp = 0;
+ rt_uint16_t tickstrat = 0;
+
+ write_reg(bus, 0x3023, 0x01);
+ write_reg(bus, 0x3022, 0x08);
+ do
+ {
+ tickstrat = rt_tick_get();
+ read_reg(bus, 0x3023, 1, &temp);
+ if (rt_tick_get() - tickstrat > 1000)
+ {
+ return RT_ERROR;
+ }
+ } while (temp != 0x00);
+
+ write_reg(bus, 0x3023, 0x01);
+ write_reg(bus, 0x3022, 0x04);
+
+ do
+ {
+ tickstrat = rt_tick_get();
+ read_reg(bus, 0x3023, 1, &temp);
+ if (rt_tick_get() - tickstrat > 1000)
+ {
+ return RT_ERROR;
+ }
+ } while (temp != 0x00);
+
+ return 0;
+}
+
+rt_uint8_t ov5640_set_outsize(struct rt_i2c_bus_device *bus, rt_uint16_t offx, rt_uint16_t offy, rt_uint16_t width, rt_uint16_t height)
+{
+ write_reg(bus, 0X3212, 0X03);
+
+ write_reg(bus, 0x3808, width >> 8);
+ write_reg(bus, 0x3809, width & 0xff);
+ write_reg(bus, 0x380a, height >> 8);
+ write_reg(bus, 0x380b, height & 0xff);
+
+ write_reg(bus, 0x3810, offx >> 8);
+ write_reg(bus, 0x3811, offx & 0xff);
+
+ write_reg(bus, 0x3812, offy >> 8);
+ write_reg(bus, 0x3813, offy & 0xff);
+
+ write_reg(bus, 0X3212, 0X13);
+ write_reg(bus, 0X3212, 0Xa3);
+
+ return RT_EOK;
+}
+
+void rt_hw_camera_rx_callback(void)
+{
+ rt_uint16_t i;
+ rt_int32_t *pbuf = RT_NULL;
+ pbuf = JPEG_DATA_BUF + jpeg_data_len;
+
+ if (hdma_dcmi.Instance->CR & (1 << 19))
+ {
+ for (i = 0; i < JPEG_LINE_SIZE; i++)
+ {
+ pbuf[i] = JPEG_LINE_BUF[0][i];
+ }
+ jpeg_data_len += JPEG_LINE_SIZE;
+
+ }
+ else
+ {
+ for (i = 0; i < JPEG_LINE_SIZE; i++)
+ {
+ pbuf[i] = JPEG_LINE_BUF[1][i];
+ }
+ jpeg_data_len += JPEG_LINE_SIZE;
+ }
+}
+
+/* After a frame of JPEG data has been collected. */
+void jpeg_data_process(void)
+{
+ rt_uint16_t i, rlen;
+ int *pbuf = RT_NULL;
+
+ if (!jpeg_data_ok)
+ {
+ __HAL_DMA_DISABLE(&hdma_dcmi);
+ rlen = JPEG_LINE_SIZE - __HAL_DMA_GET_COUNTER(&hdma_dcmi);
+ pbuf = JPEG_DATA_BUF + jpeg_data_len;
+ if (hdma_dcmi.Instance->CR & (1 << 19))
+ {
+ for (i = 0; i < rlen; i++)
+ {
+ pbuf[i] = JPEG_LINE_BUF[1][i];
+ }
+ }
+ else
+ {
+ for (i = 0; i < rlen; i++)
+ {
+ pbuf[i] = JPEG_LINE_BUF[0][i];
+ }
+ }
+ jpeg_data_len += rlen;
+ jpeg_data_ok = 1;
+ }
+
+ if (jpeg_data_ok == 2)
+ {
+ __HAL_DMA_SET_COUNTER(&hdma_dcmi, JPEG_LINE_SIZE);
+ __HAL_DMA_ENABLE(&hdma_dcmi);
+
+ jpeg_data_ok = 0;
+ jpeg_data_len = 0;
+ }
+}
+
+int rt_hw_ov5640_init(void)
+{
+ extern void rt_hw_dcmi_dma_config(rt_uint32_t dst_addr1, rt_uint32_t dst_addr2, rt_uint16_t len);
+
+ static rt_uint16_t id = 0;
+ rt_device_t dcmi_dev = RT_NULL;
+
+ i2c_bus = rt_i2c_bus_device_find(I2C_NAME);
+ if (i2c_bus == RT_NULL)
+ {
+ LOG_E("can't find %c deivce", I2C_NAME);
+ return RT_ERROR;
+ }
+
+ ov5640_hard_reset(i2c_bus);
+ ov5640_read_id(i2c_bus, &id);
+ ov5640_config(i2c_bus);
+ ov5640_rgb565_mode(i2c_bus); /* rgb565 mode */
+ ov5640_focus_init(i2c_bus);
+ ov5640_jpeg_mode(i2c_bus); /* jpeg mode */
+ ov5640_set_light(i2c_bus, 0); /* auto mode */
+ ov5640_color_saturation(i2c_bus, 3);
+ ov5640_set_brightness(i2c_bus, 4); /* brigetness 0 */
+ ov5640_contrast(i2c_bus, 3);
+ ov5640_set_sharpness(i2c_bus, 33);
+ ov5640_focus_constant(i2c_bus);
+
+ /* dcmi init */
+ dcmi_dev = rt_device_find("dcmi");
+ if (dcmi_dev == RT_NULL)
+ {
+ LOG_E("can't find dcmi device!");
+ return RT_ERROR;
+ }
+ rt_device_open(dcmi_dev, RT_DEVICE_FLAG_RDWR);
+
+ rt_hw_dcmi_dma_config((rt_uint32_t)&JPEG_LINE_BUF[0], (rt_uint32_t)&JPEG_LINE_BUF[1], JPEG_LINE_SIZE);
+ ov5640_set_outsize(i2c_bus, 4, 0, jpeg_picture_size[1][0], jpeg_picture_size[1][1]);
+
+ return RT_EOK;
+}
+INIT_APP_EXPORT(rt_hw_ov5640_init);
+
+int camera_sample(int argc, char **argv)
+{
+
+ int fd = -1;
+ rt_uint32_t i, jpg_start, jpg_len;
+ rt_uint16_t tickstart = 0;
+ rt_uint8_t jpg_head = 0;
+ rt_uint8_t *p = RT_NULL;
+
+ if (argc != 2)
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("camera_sample file.jpg\n");
+ return -1;
+ }
+
+ /* start dcmi capture */
+ __HAL_DMA_ENABLE(&hdma_dcmi);
+ dcmi.Instance->CR |= DCMI_CR_CAPTURE;
+
+ tickstart = rt_tick_get();
+ while (1)
+ {
+ if (rt_tick_get() - tickstart > 1000)
+ {
+ LOG_E("picture capture overtime!");
+ break;
+ }
+
+ if (jpeg_data_ok == 1)
+ {
+ dcmi.Instance->CR &= ~(DCMI_CR_CAPTURE);
+ tickstart = rt_tick_get();
+ while(dcmi.Instance->CR & 0x01)
+ {
+ if (rt_tick_get() - tickstart > 0x1000)
+ {
+ rt_kprintf("dcmi close failed!\n");
+ jpeg_data_ok = 2;
+ break;
+ }
+ }
+ __HAL_DMA_DISABLE(&hdma_dcmi);
+
+ p = (rt_uint8_t *)JPEG_DATA_BUF;
+ jpg_len = 0;
+ jpg_head = 0;
+ for (i = 0; i < jpeg_data_len * 4; i++)
+ {
+ /* jpg head */
+ if ((p[i] == 0xFF) && (p[i + 1] == 0xD8))
+ {
+ jpg_start = i;
+ jpg_head = 1;
+ }
+ /* jpg end */
+ if ((p[i] == 0xFF) && (p[i + 1] == 0xD9) && jpg_head)
+ {
+ jpg_len = i - jpg_start + 2; /* a picture len */
+ break;
+ }
+ }
+
+ if (jpg_len)
+ {
+ p += jpg_start;
+
+ fd = open(argv[1], O_WRONLY | O_CREAT);
+ if (fd < 0)
+ {
+ rt_kprintf("open file for recording failed!\n");
+ return -RT_ERROR;
+ }
+ else
+ {
+ write(fd, p, jpg_len);
+ close(fd);
+ rt_kprintf("picture capture complate!\n");
+
+ break;
+ }
+ }
+
+ jpeg_data_ok = 2;
+ }
+ }
+
+ return RT_EOK;
+}
+MSH_CMD_EXPORT(camera_sample, record picture to a jpg file);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.h
new file mode 100644
index 0000000000..d005150482
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.h
@@ -0,0 +1,653 @@
+
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-27 thread-liu first version
+ */
+
+#ifndef __DRV_OV5640_H__
+#define __DRV_OV5640_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief OV5640 ID
+ */
+#define OV5640_ID 0x5640U
+
+/* JPEG picture size table */
+static const unsigned short jpeg_picture_size[][2] =
+{
+ 160, 120, /* QQVGA */
+ 320, 240, /* QVGA */
+ 640, 480, /* VGA */
+ 800, 600, /* SVGA */
+ 1024, 768, /* XGA */
+ 1280, 800, /* WXGA */
+ 1440, 900, /* WXGA+ */
+ 1280, 1024, /* SXGA */
+ 1600, 1200, /* UXGA */
+ 1920, 1080, /* 1080P */
+ 2048, 1536, /* QXGA */
+ 2592, 1944, /* 500W */
+};
+
+/* camera light mode */
+static const unsigned char OV5640_LIGHTMODE_TBL[5][7]=
+{
+ 0x04,0X00,0X04,0X00,0X04,0X00,0X00, /* Auto */
+ 0x06,0X1C,0X04,0X00,0X04,0XF3,0X01, /* Sunny */
+ 0x05,0X48,0X04,0X00,0X07,0XCF,0X01, /* Office */
+ 0x06,0X48,0X04,0X00,0X04,0XD3,0X01, /* Cloudy */
+ 0x04,0X10,0X04,0X00,0X08,0X40,0X01, /* Home */
+};
+
+/* Table of color saturation setting parameters */
+static const unsigned char OV5640_SATURATION_TBL[7][6]=
+{
+ 0X0C,0x30,0X3D,0X3E,0X3D,0X01, /* -3 */
+ 0X10,0x3D,0X4D,0X4E,0X4D,0X01, /* -2 */
+ 0X15,0x52,0X66,0X68,0X66,0X02, /* -1 */
+ 0X1A,0x66,0X80,0X82,0X80,0X02, /* 0 */
+ 0X1F,0x7A,0X9A,0X9C,0X9A,0X02, /* 1 */
+ 0X24,0x8F,0XB3,0XB6,0XB3,0X03, /* 2 */
+ 0X2B,0xAB,0XD6,0XDA,0XD6,0X04, /* 3 */
+};
+
+static const unsigned short OV5640_jpeg_reg_tbl[][2]=
+{
+ 0x4300, 0x30, // YUV 422, YUYV
+ 0x501f, 0x00, // YUV 422
+ // Input clock = 24Mhz
+ 0x3035, 0x21, // PLL
+ 0x3036, 0x69, // PLL
+ 0x3c07, 0x07, // lightmeter 1 threshold[7:0]
+ 0x3820, 0x46, // flip
+ 0x3821, 0x20, // mirror
+ 0x3814, 0x11, // timing X inc
+ 0x3815, 0x11, // timing Y inc
+ 0x3800, 0x00, // HS
+ 0x3801, 0x00, // HS
+ 0x3802, 0x00, // VS
+ 0x3803, 0x00, // VS
+ 0x3804, 0x0a, // HW (HE)
+ 0x3805, 0x3f, // HW (HE)
+ 0x3806, 0x07, // VH (VE)
+ 0x3807, 0x9f, // VH (VE)
+
+ 0x3808, 0x02, // DVPHO
+ 0x3809, 0x80, // DVPHO
+ 0x380a, 0x01, // DVPVO
+ 0x380b, 0xe0, // DVPVO
+
+ 0x380c, 0x0b, // HTS //
+ 0x380d, 0x1c, // HTS
+ 0x380e, 0x07, // VTS //
+ 0x380f, 0xb0, // VTS
+ 0x3813, 0x04, // timing V offset 04
+ 0x3618, 0x04,
+ 0x3612, 0x2b,
+ 0x3709, 0x12,
+ 0x370c, 0x00,
+
+ 0x4004, 0x06, // BLC line number
+ 0x3002, 0x00, // enable JFIFO, SFIFO, JPG
+ 0x3006, 0xff, // enable clock of JPEG2x, JPEG
+ 0x4713, 0x03, // JPEG mode 3
+ 0x4407, 0x01, // Quantization sacle
+ 0x460b, 0x35,
+ 0x460c, 0x22,
+ 0x4837, 0x16, // MIPI global timing
+ 0x3824, 0x02, // PCLK manual divider
+ 0x5001, 0xA3, // SDE on, Scaling on, CMX on, AWB on
+ 0x3503, 0x00, // AEC/AGC on
+};
+
+/* RGB565 configuration, 15 frames */
+static const unsigned short ov5640_rgb565_reg_tbl[][2]=
+{
+ 0x4300, 0X6F,
+ 0X501F, 0x01,
+ // 1280x800, 15fps
+ // input clock 24Mhz, PCLK 42Mhz
+ 0x3035, 0x41, // PLL
+ 0x3036, 0x69, // PLL
+ 0x3c07, 0x07, // lightmeter 1 threshold[7:0]
+ 0x3820, 0x46, // flip
+ 0x3821, 0x00, // mirror
+ 0x3814, 0x31, // timing X inc
+ 0x3815, 0x31, // timing Y inc
+ 0x3800, 0x00, // HS
+ 0x3801, 0x00, // HS
+ 0x3802, 0x00, // VS
+ 0x3803, 0x00, // VS
+ 0x3804, 0x0a, // HW (HE)
+ 0x3805, 0x3f, // HW (HE)
+ 0x3806, 0x06, // VH (VE)
+ 0x3807, 0xa9, // VH (VE)
+ 0x3808, 0x05, // DVPHO
+ 0x3809, 0x00, // DVPHO
+ 0x380a, 0x02, // DVPVO
+ 0x380b, 0xd0, // DVPVO
+ 0x380c, 0x05, // HTS
+ 0x380d, 0xF8, // HTS
+ 0x380e, 0x03, // VTS
+ 0x380f, 0x84, // VTS
+ 0x3813, 0x04, // timing V offset
+ 0x3618, 0x00,
+ 0x3612, 0x29,
+ 0x3709, 0x52,
+ 0x370c, 0x03,
+ 0x3a02, 0x02, // 60Hz max exposure
+ 0x3a03, 0xe0, // 60Hz max exposure
+
+ 0x3a14, 0x02, // 50Hz max exposure
+ 0x3a15, 0xe0, // 50Hz max exposure
+ 0x4004, 0x02, // BLC line number
+ 0x3002, 0x1c, // reset JFIFO, SFIFO, JPG
+ 0x3006, 0xc3, // disable clock of JPEG2x, JPEG
+ 0x4713, 0x03, // JPEG mode 3
+ 0x4407, 0x04, // Quantization scale
+ 0x460b, 0x37,
+ 0x460c, 0x20,
+ 0x4837, 0x16, // MIPI global timing
+ 0x3824, 0x04, // PCLK manual divider
+ 0x5001, 0xA3, // SDE on, scale on, UV average off, color matrix on, AWB on
+ 0x3503, 0x00, // AEC/AGC on
+};
+
+static const unsigned short RGB565_Init[][2]=
+{
+ /* 24MHz input clock, 24MHz PCLK */
+ 0x3008, 0x42, // software power down, bit[6]
+ 0x3103, 0x03, // system clock from PLL, bit[1]
+ 0x3017, 0xff, // FREX, Vsync, HREF, PCLK, D[9:6] output enable
+ 0x3018, 0xff, // D[5:0], GPIO[1:0] output enable
+ 0x3034, 0x1a, // MIPI 10-bit
+ 0x3037, 0x13, // PLL root divider, bit[4], PLL pre-divider, bit[3:0]
+ 0x3108, 0x01, // PCLK root divider, bit[5:4], SCLK2x root divider, bit[3:2]
+
+ // SCLK root divider, bit[1:0]
+ 0x3630, 0x36,
+ 0x3631, 0x0e,
+ 0x3632, 0xe2,
+ 0x3633, 0x12,
+ 0x3621, 0xe0,
+ 0x3704, 0xa0,
+ 0x3703, 0x5a,
+ 0x3715, 0x78,
+ 0x3717, 0x01,
+ 0x370b, 0x60,
+ 0x3705, 0x1a,
+ 0x3905, 0x02,
+ 0x3906, 0x10,
+ 0x3901, 0x0a,
+ 0x3731, 0x12,
+ 0x3600, 0x08, // VCM control
+ 0x3601, 0x33, // VCM control
+ 0x302d, 0x60, // system control
+ 0x3620, 0x52,
+ 0x371b, 0x20,
+ 0x471c, 0x50,
+ 0x3a13, 0x43, // pre-gain = 1.047x
+ 0x3a18, 0x00, // gain ceiling
+ 0x3a19, 0xf8, // gain ceiling = 15.5x
+ 0x3635, 0x13,
+ 0x3636, 0x03,
+ 0x3634, 0x40,
+ 0x3622, 0x01,
+ // 50/60Hz detection 50/60Hz
+ 0x3c01, 0x34, // Band auto, bit[7]
+ 0x3c04, 0x28, // threshold low sum
+ 0x3c05, 0x98, // threshold high sum
+ 0x3c06, 0x00, // light meter 1 threshold[15:8]
+ 0x3c07, 0x08, // light meter 1 threshold[7:0]
+ 0x3c08, 0x00, // light meter 2 threshold[15:8]
+ 0x3c09, 0x1c, // light meter 2 threshold[7:0]
+ 0x3c0a, 0x9c, // sample number[15:8]
+ 0x3c0b, 0x40, // sample number[7:0]
+ 0x3810, 0x00, // Timing Hoffset[11:8]
+ 0x3811, 0x10, // Timing Hoffset[7:0]
+ 0x3812, 0x00, // Timing Voffset[10:8]
+ 0x3708, 0x64,
+ 0x4001, 0x02, // BLC start from line 2
+ 0x4005, 0x1a, // BLC always update
+ 0x3000, 0x00, // enable blocks
+ 0x3004, 0xff, // enable clocks
+ 0x300e, 0x58, // MIPI power down, DVP enable
+ 0x302e, 0x00,
+ 0x4300, 0x30, // YUV 422, YUYV
+ 0x501f, 0x00, // YUV 422
+ 0x440e, 0x00,
+ 0x5000, 0xa7, // Lenc on, raw gamma on, BPC on, WPC on, CIP on
+ // AEC target
+ 0x3a0f, 0x30, // stable range in high
+ 0x3a10, 0x28, // stable range in low
+ 0x3a1b, 0x30, // stable range out high
+ 0x3a1e, 0x26, // stable range out low
+ 0x3a11, 0x60, // fast zone high
+ 0x3a1f, 0x14, // fast zone low
+ // Lens correction
+ 0x5800, 0x23,
+ 0x5801, 0x14,
+ 0x5802, 0x0f,
+ 0x5803, 0x0f,
+ 0x5804, 0x12,
+ 0x5805, 0x26,
+ 0x5806, 0x0c,
+ 0x5807, 0x08,
+ 0x5808, 0x05,
+ 0x5809, 0x05,
+ 0x580a, 0x08,
+
+ 0x580b, 0x0d,
+ 0x580c, 0x08,
+ 0x580d, 0x03,
+ 0x580e, 0x00,
+ 0x580f, 0x00,
+ 0x5810, 0x03,
+ 0x5811, 0x09,
+ 0x5812, 0x07,
+ 0x5813, 0x03,
+ 0x5814, 0x00,
+ 0x5815, 0x01,
+ 0x5816, 0x03,
+ 0x5817, 0x08,
+ 0x5818, 0x0d,
+ 0x5819, 0x08,
+ 0x581a, 0x05,
+ 0x581b, 0x06,
+ 0x581c, 0x08,
+ 0x581d, 0x0e,
+ 0x581e, 0x29,
+ 0x581f, 0x17,
+ 0x5820, 0x11,
+ 0x5821, 0x11,
+ 0x5822, 0x15,
+ 0x5823, 0x28,
+ 0x5824, 0x46,
+ 0x5825, 0x26,
+ 0x5826, 0x08,
+ 0x5827, 0x26,
+ 0x5828, 0x64,
+ 0x5829, 0x26,
+ 0x582a, 0x24,
+ 0x582b, 0x22,
+ 0x582c, 0x24,
+ 0x582d, 0x24,
+ 0x582e, 0x06,
+ 0x582f, 0x22,
+ 0x5830, 0x40,
+ 0x5831, 0x42,
+ 0x5832, 0x24,
+ 0x5833, 0x26,
+ 0x5834, 0x24,
+ 0x5835, 0x22,
+ 0x5836, 0x22,
+ 0x5837, 0x26,
+ 0x5838, 0x44,
+ 0x5839, 0x24,
+ 0x583a, 0x26,
+ 0x583b, 0x28,
+ 0x583c, 0x42,
+ 0x583d, 0xce, // lenc BR offset
+ // AWB
+ 0x5180, 0xff, // AWB B block
+ 0x5181, 0xf2, // AWB control
+ 0x5182, 0x00, // [7:4] max local counter, [3:0] max fast counter
+ 0x5183, 0x14, // AWB advanced
+ 0x5184, 0x25,
+ 0x5185, 0x24,
+ 0x5186, 0x09,
+ 0x5187, 0x09,
+ 0x5188, 0x09,
+ 0x5189, 0x75,
+ 0x518a, 0x54,
+ 0x518b, 0xe0,
+ 0x518c, 0xb2,
+ 0x518d, 0x42,
+ 0x518e, 0x3d,
+ 0x518f, 0x56,
+ 0x5190, 0x46,
+ 0x5191, 0xf8, // AWB top limit
+ 0x5192, 0x04, // AWB bottom limit
+ 0x5193, 0x70, // red limit
+ 0x5194, 0xf0, // green limit
+ 0x5195, 0xf0, // blue limit
+ 0x5196, 0x03, // AWB control
+ 0x5197, 0x01, // local limit
+ 0x5198, 0x04,
+ 0x5199, 0x12,
+ 0x519a, 0x04,
+ 0x519b, 0x00,
+ 0x519c, 0x06,
+ 0x519d, 0x82,
+ 0x519e, 0x38, // AWB control
+ // Gamma
+ 0x5480, 0x01, // Gamma bias plus on, bit[0]
+ 0x5481, 0x08,
+ 0x5482, 0x14,
+ 0x5483, 0x28,
+ 0x5484, 0x51,
+ 0x5485, 0x65,
+ 0x5486, 0x71,
+ 0x5487, 0x7d,
+ 0x5488, 0x87,
+ 0x5489, 0x91,
+ 0x548a, 0x9a,
+ 0x548b, 0xaa,
+ 0x548c, 0xb8,
+ 0x548d, 0xcd,
+ 0x548e, 0xdd,
+ 0x548f, 0xea,
+ 0x5490, 0x1d,
+ // color matrix
+ 0x5381, 0x1e, // CMX1 for Y
+ 0x5382, 0x5b, // CMX2 for Y
+ 0x5383, 0x08, // CMX3 for Y
+ 0x5384, 0x0a, // CMX4 for U
+ 0x5385, 0x7e, // CMX5 for U
+ 0x5386, 0x88, // CMX6 for U
+ 0x5387, 0x7c, // CMX7 for V
+ 0x5388, 0x6c, // CMX8 for V
+ 0x5389, 0x10, // CMX9 for V
+ 0x538a, 0x01, // sign[9]
+ 0x538b, 0x98, // sign[8:1]
+ // UV adjust UV
+ 0x5580, 0x06, // saturation on, bit[1]
+ 0x5583, 0x40,
+ 0x5584, 0x10,
+ 0x5589, 0x10,
+ 0x558a, 0x00,
+ 0x558b, 0xf8,
+ 0x501d, 0x40, // enable manual offset of contrast
+ // CIP
+ 0x5300, 0x08, // CIP sharpen MT threshold 1
+ 0x5301, 0x30, // CIP sharpen MT threshold 2
+ 0x5302, 0x10, // CIP sharpen MT offset 1
+ 0x5303, 0x00, // CIP sharpen MT offset 2
+ 0x5304, 0x08, // CIP DNS threshold 1
+ 0x5305, 0x30, // CIP DNS threshold 2
+ 0x5306, 0x08, // CIP DNS offset 1
+ 0x5307, 0x16, // CIP DNS offset 2
+ 0x5309, 0x08, // CIP sharpen TH threshold 1
+ 0x530a, 0x30, // CIP sharpen TH threshold 2
+ 0x530b, 0x04, // CIP sharpen TH offset 1
+ 0x530c, 0x06, // CIP sharpen TH offset 2
+ 0x5025, 0x00,
+ 0x3008, 0x02, // wake up from standby, bit[6]
+
+ 0x4740, 0X21, //VSYNC
+};
+
+/* Autofocus initialization configuration */
+const unsigned char OV5640_AF_Config[] =
+{
+ 0x02, 0x0f, 0xd6, 0x02, 0x0a, 0x39, 0xc2, 0x01, 0x22, 0x22, 0x00, 0x02, 0x0f, 0xb2, 0xe5, 0x1f, //0x8000,
+ 0x70, 0x72, 0xf5, 0x1e, 0xd2, 0x35, 0xff, 0xef, 0x25, 0xe0, 0x24, 0x4e, 0xf8, 0xe4, 0xf6, 0x08, //0x8010,
+ 0xf6, 0x0f, 0xbf, 0x34, 0xf2, 0x90, 0x0e, 0x93, 0xe4, 0x93, 0xff, 0xe5, 0x4b, 0xc3, 0x9f, 0x50, //0x8020,
+ 0x04, 0x7f, 0x05, 0x80, 0x02, 0x7f, 0xfb, 0x78, 0xbd, 0xa6, 0x07, 0x12, 0x0f, 0x04, 0x40, 0x04, //0x8030,
+ 0x7f, 0x03, 0x80, 0x02, 0x7f, 0x30, 0x78, 0xbc, 0xa6, 0x07, 0xe6, 0x18, 0xf6, 0x08, 0xe6, 0x78, //0x8040,
+ 0xb9, 0xf6, 0x78, 0xbc, 0xe6, 0x78, 0xba, 0xf6, 0x78, 0xbf, 0x76, 0x33, 0xe4, 0x08, 0xf6, 0x78, //0x8050,
+ 0xb8, 0x76, 0x01, 0x75, 0x4a, 0x02, 0x78, 0xb6, 0xf6, 0x08, 0xf6, 0x74, 0xff, 0x78, 0xc1, 0xf6, //0x8060,
+ 0x08, 0xf6, 0x75, 0x1f, 0x01, 0x78, 0xbc, 0xe6, 0x75, 0xf0, 0x05, 0xa4, 0xf5, 0x4b, 0x12, 0x0a, //0x8070,
+ 0xff, 0xc2, 0x37, 0x22, 0x78, 0xb8, 0xe6, 0xd3, 0x94, 0x00, 0x40, 0x02, 0x16, 0x22, 0xe5, 0x1f, //0x8080,
+ 0xb4, 0x05, 0x23, 0xe4, 0xf5, 0x1f, 0xc2, 0x01, 0x78, 0xb6, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x78, //0x8090,
+ 0x4e, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0xa2, 0x37, 0xe4, 0x33, 0xf5, 0x3c, 0x90, 0x30, 0x28, 0xf0, //0x80a0,
+ 0x75, 0x1e, 0x10, 0xd2, 0x35, 0x22, 0xe5, 0x4b, 0x75, 0xf0, 0x05, 0x84, 0x78, 0xbc, 0xf6, 0x90, //0x80b0,
+ 0x0e, 0x8c, 0xe4, 0x93, 0xff, 0x25, 0xe0, 0x24, 0x0a, 0xf8, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x78, //0x80c0,
+ 0xbc, 0xe6, 0x25, 0xe0, 0x24, 0x4e, 0xf8, 0xa6, 0x04, 0x08, 0xa6, 0x05, 0xef, 0x12, 0x0f, 0x0b, //0x80d0,
+ 0xd3, 0x78, 0xb7, 0x96, 0xee, 0x18, 0x96, 0x40, 0x0d, 0x78, 0xbc, 0xe6, 0x78, 0xb9, 0xf6, 0x78, //0x80e0,
+ 0xb6, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0x90, 0x0e, 0x8c, 0xe4, 0x93, 0x12, 0x0f, 0x0b, 0xc3, 0x78, //0x80f0,
+ 0xc2, 0x96, 0xee, 0x18, 0x96, 0x50, 0x0d, 0x78, 0xbc, 0xe6, 0x78, 0xba, 0xf6, 0x78, 0xc1, 0xa6, //0x8100,
+ 0x06, 0x08, 0xa6, 0x07, 0x78, 0xb6, 0xe6, 0xfe, 0x08, 0xe6, 0xc3, 0x78, 0xc2, 0x96, 0xff, 0xee, //0x8110,
+ 0x18, 0x96, 0x78, 0xc3, 0xf6, 0x08, 0xa6, 0x07, 0x90, 0x0e, 0x95, 0xe4, 0x18, 0x12, 0x0e, 0xe9, //0x8120,
+ 0x40, 0x02, 0xd2, 0x37, 0x78, 0xbc, 0xe6, 0x08, 0x26, 0x08, 0xf6, 0xe5, 0x1f, 0x64, 0x01, 0x70, //0x8130,
+ 0x4a, 0xe6, 0xc3, 0x78, 0xc0, 0x12, 0x0e, 0xdf, 0x40, 0x05, 0x12, 0x0e, 0xda, 0x40, 0x39, 0x12, //0x8140,
+ 0x0f, 0x02, 0x40, 0x04, 0x7f, 0xfe, 0x80, 0x02, 0x7f, 0x02, 0x78, 0xbd, 0xa6, 0x07, 0x78, 0xb9, //0x8150,
+ 0xe6, 0x24, 0x03, 0x78, 0xbf, 0xf6, 0x78, 0xb9, 0xe6, 0x24, 0xfd, 0x78, 0xc0, 0xf6, 0x12, 0x0f, //0x8160,
+ 0x02, 0x40, 0x06, 0x78, 0xc0, 0xe6, 0xff, 0x80, 0x04, 0x78, 0xbf, 0xe6, 0xff, 0x78, 0xbe, 0xa6, //0x8170,
+ 0x07, 0x75, 0x1f, 0x02, 0x78, 0xb8, 0x76, 0x01, 0x02, 0x02, 0x4a, 0xe5, 0x1f, 0x64, 0x02, 0x60, //0x8180,
+ 0x03, 0x02, 0x02, 0x2a, 0x78, 0xbe, 0xe6, 0xff, 0xc3, 0x78, 0xc0, 0x12, 0x0e, 0xe0, 0x40, 0x08, //0x8190,
+ 0x12, 0x0e, 0xda, 0x50, 0x03, 0x02, 0x02, 0x28, 0x12, 0x0f, 0x02, 0x40, 0x04, 0x7f, 0xff, 0x80, //0x81a0,
+ 0x02, 0x7f, 0x01, 0x78, 0xbd, 0xa6, 0x07, 0x78, 0xb9, 0xe6, 0x04, 0x78, 0xbf, 0xf6, 0x78, 0xb9, //0x81b0,
+ 0xe6, 0x14, 0x78, 0xc0, 0xf6, 0x18, 0x12, 0x0f, 0x04, 0x40, 0x04, 0xe6, 0xff, 0x80, 0x02, 0x7f, //0x81c0,
+ 0x00, 0x78, 0xbf, 0xa6, 0x07, 0xd3, 0x08, 0xe6, 0x64, 0x80, 0x94, 0x80, 0x40, 0x04, 0xe6, 0xff, //0x81d0,
+ 0x80, 0x02, 0x7f, 0x00, 0x78, 0xc0, 0xa6, 0x07, 0xc3, 0x18, 0xe6, 0x64, 0x80, 0x94, 0xb3, 0x50, //0x81e0,
+ 0x04, 0xe6, 0xff, 0x80, 0x02, 0x7f, 0x33, 0x78, 0xbf, 0xa6, 0x07, 0xc3, 0x08, 0xe6, 0x64, 0x80, //0x81f0,
+ 0x94, 0xb3, 0x50, 0x04, 0xe6, 0xff, 0x80, 0x02, 0x7f, 0x33, 0x78, 0xc0, 0xa6, 0x07, 0x12, 0x0f, //0x8200,
+ 0x02, 0x40, 0x06, 0x78, 0xc0, 0xe6, 0xff, 0x80, 0x04, 0x78, 0xbf, 0xe6, 0xff, 0x78, 0xbe, 0xa6, //0x8210,
+ 0x07, 0x75, 0x1f, 0x03, 0x78, 0xb8, 0x76, 0x01, 0x80, 0x20, 0xe5, 0x1f, 0x64, 0x03, 0x70, 0x26, //0x8220,
+ 0x78, 0xbe, 0xe6, 0xff, 0xc3, 0x78, 0xc0, 0x12, 0x0e, 0xe0, 0x40, 0x05, 0x12, 0x0e, 0xda, 0x40, //0x8230,
+ 0x09, 0x78, 0xb9, 0xe6, 0x78, 0xbe, 0xf6, 0x75, 0x1f, 0x04, 0x78, 0xbe, 0xe6, 0x75, 0xf0, 0x05, //0x8240,
+ 0xa4, 0xf5, 0x4b, 0x02, 0x0a, 0xff, 0xe5, 0x1f, 0xb4, 0x04, 0x10, 0x90, 0x0e, 0x94, 0xe4, 0x78, //0x8250,
+ 0xc3, 0x12, 0x0e, 0xe9, 0x40, 0x02, 0xd2, 0x37, 0x75, 0x1f, 0x05, 0x22, 0x30, 0x01, 0x03, 0x02, //0x8260,
+ 0x04, 0xc0, 0x30, 0x02, 0x03, 0x02, 0x04, 0xc0, 0x90, 0x51, 0xa5, 0xe0, 0x78, 0x93, 0xf6, 0xa3, //0x8270,
+ 0xe0, 0x08, 0xf6, 0xa3, 0xe0, 0x08, 0xf6, 0xe5, 0x1f, 0x70, 0x3c, 0x75, 0x1e, 0x20, 0xd2, 0x35, //0x8280,
+ 0x12, 0x0c, 0x7a, 0x78, 0x7e, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0x78, 0x8b, 0xa6, 0x09, 0x18, 0x76, //0x8290,
+ 0x01, 0x12, 0x0c, 0x5b, 0x78, 0x4e, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0x78, 0x8b, 0xe6, 0x78, 0x6e, //0x82a0,
+ 0xf6, 0x75, 0x1f, 0x01, 0x78, 0x93, 0xe6, 0x78, 0x90, 0xf6, 0x78, 0x94, 0xe6, 0x78, 0x91, 0xf6, //0x82b0,
+ 0x78, 0x95, 0xe6, 0x78, 0x92, 0xf6, 0x22, 0x79, 0x90, 0xe7, 0xd3, 0x78, 0x93, 0x96, 0x40, 0x05, //0x82c0,
+ 0xe7, 0x96, 0xff, 0x80, 0x08, 0xc3, 0x79, 0x93, 0xe7, 0x78, 0x90, 0x96, 0xff, 0x78, 0x88, 0x76, //0x82d0,
+ 0x00, 0x08, 0xa6, 0x07, 0x79, 0x91, 0xe7, 0xd3, 0x78, 0x94, 0x96, 0x40, 0x05, 0xe7, 0x96, 0xff, //0x82e0,
+ 0x80, 0x08, 0xc3, 0x79, 0x94, 0xe7, 0x78, 0x91, 0x96, 0xff, 0x12, 0x0c, 0x8e, 0x79, 0x92, 0xe7, //0x82f0,
+ 0xd3, 0x78, 0x95, 0x96, 0x40, 0x05, 0xe7, 0x96, 0xff, 0x80, 0x08, 0xc3, 0x79, 0x95, 0xe7, 0x78, //0x8300,
+ 0x92, 0x96, 0xff, 0x12, 0x0c, 0x8e, 0x12, 0x0c, 0x5b, 0x78, 0x8a, 0xe6, 0x25, 0xe0, 0x24, 0x4e, //0x8310,
+ 0xf8, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0x78, 0x8a, 0xe6, 0x24, 0x6e, 0xf8, 0xa6, 0x09, 0x78, 0x8a, //0x8320,
+ 0xe6, 0x24, 0x01, 0xff, 0xe4, 0x33, 0xfe, 0xd3, 0xef, 0x94, 0x0f, 0xee, 0x64, 0x80, 0x94, 0x80, //0x8330,
+ 0x40, 0x04, 0x7f, 0x00, 0x80, 0x05, 0x78, 0x8a, 0xe6, 0x04, 0xff, 0x78, 0x8a, 0xa6, 0x07, 0xe5, //0x8340,
+ 0x1f, 0xb4, 0x01, 0x0a, 0xe6, 0x60, 0x03, 0x02, 0x04, 0xc0, 0x75, 0x1f, 0x02, 0x22, 0x12, 0x0c, //0x8350,
+ 0x7a, 0x78, 0x80, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0x12, 0x0c, 0x7a, 0x78, 0x82, 0xa6, 0x06, 0x08, //0x8360,
+ 0xa6, 0x07, 0x78, 0x6e, 0xe6, 0x78, 0x8c, 0xf6, 0x78, 0x6e, 0xe6, 0x78, 0x8d, 0xf6, 0x7f, 0x01, //0x8370,
+ 0xef, 0x25, 0xe0, 0x24, 0x4f, 0xf9, 0xc3, 0x78, 0x81, 0xe6, 0x97, 0x18, 0xe6, 0x19, 0x97, 0x50, //0x8380,
+ 0x0a, 0x12, 0x0c, 0x82, 0x78, 0x80, 0xa6, 0x04, 0x08, 0xa6, 0x05, 0x74, 0x6e, 0x2f, 0xf9, 0x78, //0x8390,
+ 0x8c, 0xe6, 0xc3, 0x97, 0x50, 0x08, 0x74, 0x6e, 0x2f, 0xf8, 0xe6, 0x78, 0x8c, 0xf6, 0xef, 0x25, //0x83a0,
+ 0xe0, 0x24, 0x4f, 0xf9, 0xd3, 0x78, 0x83, 0xe6, 0x97, 0x18, 0xe6, 0x19, 0x97, 0x40, 0x0a, 0x12, //0x83b0,
+ 0x0c, 0x82, 0x78, 0x82, 0xa6, 0x04, 0x08, 0xa6, 0x05, 0x74, 0x6e, 0x2f, 0xf9, 0x78, 0x8d, 0xe6, //0x83c0,
+ 0xd3, 0x97, 0x40, 0x08, 0x74, 0x6e, 0x2f, 0xf8, 0xe6, 0x78, 0x8d, 0xf6, 0x0f, 0xef, 0x64, 0x10, //0x83d0,
+ 0x70, 0x9e, 0xc3, 0x79, 0x81, 0xe7, 0x78, 0x83, 0x96, 0xff, 0x19, 0xe7, 0x18, 0x96, 0x78, 0x84, //0x83e0,
+ 0xf6, 0x08, 0xa6, 0x07, 0xc3, 0x79, 0x8c, 0xe7, 0x78, 0x8d, 0x96, 0x08, 0xf6, 0xd3, 0x79, 0x81, //0x83f0,
+ 0xe7, 0x78, 0x7f, 0x96, 0x19, 0xe7, 0x18, 0x96, 0x40, 0x05, 0x09, 0xe7, 0x08, 0x80, 0x06, 0xc3, //0x8400,
+ 0x79, 0x7f, 0xe7, 0x78, 0x81, 0x96, 0xff, 0x19, 0xe7, 0x18, 0x96, 0xfe, 0x78, 0x86, 0xa6, 0x06, //0x8410,
+ 0x08, 0xa6, 0x07, 0x79, 0x8c, 0xe7, 0xd3, 0x78, 0x8b, 0x96, 0x40, 0x05, 0xe7, 0x96, 0xff, 0x80, //0x8420,
+ 0x08, 0xc3, 0x79, 0x8b, 0xe7, 0x78, 0x8c, 0x96, 0xff, 0x78, 0x8f, 0xa6, 0x07, 0xe5, 0x1f, 0x64, //0x8430,
+ 0x02, 0x70, 0x69, 0x90, 0x0e, 0x91, 0x93, 0xff, 0x18, 0xe6, 0xc3, 0x9f, 0x50, 0x72, 0x12, 0x0c, //0x8440,
+ 0x4a, 0x12, 0x0c, 0x2f, 0x90, 0x0e, 0x8e, 0x12, 0x0c, 0x38, 0x78, 0x80, 0x12, 0x0c, 0x6b, 0x7b, //0x8450,
+ 0x04, 0x12, 0x0c, 0x1d, 0xc3, 0x12, 0x06, 0x45, 0x50, 0x56, 0x90, 0x0e, 0x92, 0xe4, 0x93, 0xff, //0x8460,
+ 0x78, 0x8f, 0xe6, 0x9f, 0x40, 0x02, 0x80, 0x11, 0x90, 0x0e, 0x90, 0xe4, 0x93, 0xff, 0xd3, 0x78, //0x8470,
+ 0x89, 0xe6, 0x9f, 0x18, 0xe6, 0x94, 0x00, 0x40, 0x03, 0x75, 0x1f, 0x05, 0x12, 0x0c, 0x4a, 0x12, //0x8480,
+ 0x0c, 0x2f, 0x90, 0x0e, 0x8f, 0x12, 0x0c, 0x38, 0x78, 0x7e, 0x12, 0x0c, 0x6b, 0x7b, 0x40, 0x12, //0x8490,
+ 0x0c, 0x1d, 0xd3, 0x12, 0x06, 0x45, 0x40, 0x18, 0x75, 0x1f, 0x05, 0x22, 0xe5, 0x1f, 0xb4, 0x05, //0x84a0,
+ 0x0f, 0xd2, 0x01, 0xc2, 0x02, 0xe4, 0xf5, 0x1f, 0xf5, 0x1e, 0xd2, 0x35, 0xd2, 0x33, 0xd2, 0x36, //0x84b0,
+ 0x22, 0xef, 0x8d, 0xf0, 0xa4, 0xa8, 0xf0, 0xcf, 0x8c, 0xf0, 0xa4, 0x28, 0xce, 0x8d, 0xf0, 0xa4, //0x84c0,
+ 0x2e, 0xfe, 0x22, 0xbc, 0x00, 0x0b, 0xbe, 0x00, 0x29, 0xef, 0x8d, 0xf0, 0x84, 0xff, 0xad, 0xf0, //0x84d0,
+ 0x22, 0xe4, 0xcc, 0xf8, 0x75, 0xf0, 0x08, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xec, 0x33, 0xfc, //0x84e0,
+ 0xee, 0x9d, 0xec, 0x98, 0x40, 0x05, 0xfc, 0xee, 0x9d, 0xfe, 0x0f, 0xd5, 0xf0, 0xe9, 0xe4, 0xce, //0x84f0,
+ 0xfd, 0x22, 0xed, 0xf8, 0xf5, 0xf0, 0xee, 0x84, 0x20, 0xd2, 0x1c, 0xfe, 0xad, 0xf0, 0x75, 0xf0, //0x8500,
+ 0x08, 0xef, 0x2f, 0xff, 0xed, 0x33, 0xfd, 0x40, 0x07, 0x98, 0x50, 0x06, 0xd5, 0xf0, 0xf2, 0x22, //0x8510,
+ 0xc3, 0x98, 0xfd, 0x0f, 0xd5, 0xf0, 0xea, 0x22, 0xe8, 0x8f, 0xf0, 0xa4, 0xcc, 0x8b, 0xf0, 0xa4, //0x8520,
+ 0x2c, 0xfc, 0xe9, 0x8e, 0xf0, 0xa4, 0x2c, 0xfc, 0x8a, 0xf0, 0xed, 0xa4, 0x2c, 0xfc, 0xea, 0x8e, //0x8530,
+ 0xf0, 0xa4, 0xcd, 0xa8, 0xf0, 0x8b, 0xf0, 0xa4, 0x2d, 0xcc, 0x38, 0x25, 0xf0, 0xfd, 0xe9, 0x8f, //0x8540,
+ 0xf0, 0xa4, 0x2c, 0xcd, 0x35, 0xf0, 0xfc, 0xeb, 0x8e, 0xf0, 0xa4, 0xfe, 0xa9, 0xf0, 0xeb, 0x8f, //0x8550,
+ 0xf0, 0xa4, 0xcf, 0xc5, 0xf0, 0x2e, 0xcd, 0x39, 0xfe, 0xe4, 0x3c, 0xfc, 0xea, 0xa4, 0x2d, 0xce, //0x8560,
+ 0x35, 0xf0, 0xfd, 0xe4, 0x3c, 0xfc, 0x22, 0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, //0x8570,
+ 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc, 0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, //0x8580,
+ 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40, 0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, //0x8590,
+ 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6, 0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, //0x85a0,
+ 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9, 0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, //0x85b0,
+ 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb, 0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, //0x85c0,
+ 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb, 0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, //0x85d0,
+ 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9, 0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, //0x85e0,
+ 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, //0x85f0,
+ 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a, 0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, //0x8600,
+ 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, //0x8610,
+ 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07, 0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, //0x8620,
+ 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8, 0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, //0x8630,
+ 0xfa, 0xe4, 0xc8, 0xf9, 0x22, 0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, //0x8640,
+ 0xf0, 0xe8, 0x9c, 0x45, 0xf0, 0x22, 0xe8, 0x60, 0x0f, 0xec, 0xc3, 0x13, 0xfc, 0xed, 0x13, 0xfd, //0x8650,
+ 0xee, 0x13, 0xfe, 0xef, 0x13, 0xff, 0xd8, 0xf1, 0x22, 0xe8, 0x60, 0x0f, 0xef, 0xc3, 0x33, 0xff, //0x8660,
+ 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xd8, 0xf1, 0x22, 0xe4, 0x93, 0xfc, 0x74, //0x8670,
+ 0x01, 0x93, 0xfd, 0x74, 0x02, 0x93, 0xfe, 0x74, 0x03, 0x93, 0xff, 0x22, 0xe6, 0xfb, 0x08, 0xe6, //0x8680,
+ 0xf9, 0x08, 0xe6, 0xfa, 0x08, 0xe6, 0xcb, 0xf8, 0x22, 0xec, 0xf6, 0x08, 0xed, 0xf6, 0x08, 0xee, //0x8690,
+ 0xf6, 0x08, 0xef, 0xf6, 0x22, 0xa4, 0x25, 0x82, 0xf5, 0x82, 0xe5, 0xf0, 0x35, 0x83, 0xf5, 0x83, //0x86a0,
+ 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, //0x86b0,
+ 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, //0x86c0,
+ 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0x90, 0x38, 0x04, 0x78, 0x52, 0x12, 0x0b, 0xfd, 0x90, //0x86d0,
+ 0x38, 0x00, 0xe0, 0xfe, 0xa3, 0xe0, 0xfd, 0xed, 0xff, 0xc3, 0x12, 0x0b, 0x9e, 0x90, 0x38, 0x10, //0x86e0,
+ 0x12, 0x0b, 0x92, 0x90, 0x38, 0x06, 0x78, 0x54, 0x12, 0x0b, 0xfd, 0x90, 0x38, 0x02, 0xe0, 0xfe, //0x86f0,
+ 0xa3, 0xe0, 0xfd, 0xed, 0xff, 0xc3, 0x12, 0x0b, 0x9e, 0x90, 0x38, 0x12, 0x12, 0x0b, 0x92, 0xa3, //0x8700,
+ 0xe0, 0xb4, 0x31, 0x07, 0x78, 0x52, 0x79, 0x52, 0x12, 0x0c, 0x13, 0x90, 0x38, 0x14, 0xe0, 0xb4, //0x8710,
+ 0x71, 0x15, 0x78, 0x52, 0xe6, 0xfe, 0x08, 0xe6, 0x78, 0x02, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, //0x8720,
+ 0xf9, 0x79, 0x53, 0xf7, 0xee, 0x19, 0xf7, 0x90, 0x38, 0x15, 0xe0, 0xb4, 0x31, 0x07, 0x78, 0x54, //0x8730,
+ 0x79, 0x54, 0x12, 0x0c, 0x13, 0x90, 0x38, 0x15, 0xe0, 0xb4, 0x71, 0x15, 0x78, 0x54, 0xe6, 0xfe, //0x8740,
+ 0x08, 0xe6, 0x78, 0x02, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0x79, 0x55, 0xf7, 0xee, 0x19, //0x8750,
+ 0xf7, 0x79, 0x52, 0x12, 0x0b, 0xd9, 0x09, 0x12, 0x0b, 0xd9, 0xaf, 0x47, 0x12, 0x0b, 0xb2, 0xe5, //0x8760,
+ 0x44, 0xfb, 0x7a, 0x00, 0xfd, 0x7c, 0x00, 0x12, 0x04, 0xd3, 0x78, 0x5a, 0xa6, 0x06, 0x08, 0xa6, //0x8770,
+ 0x07, 0xaf, 0x45, 0x12, 0x0b, 0xb2, 0xad, 0x03, 0x7c, 0x00, 0x12, 0x04, 0xd3, 0x78, 0x56, 0xa6, //0x8780,
+ 0x06, 0x08, 0xa6, 0x07, 0xaf, 0x48, 0x78, 0x54, 0x12, 0x0b, 0xb4, 0xe5, 0x43, 0xfb, 0xfd, 0x7c, //0x8790,
+ 0x00, 0x12, 0x04, 0xd3, 0x78, 0x5c, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0xaf, 0x46, 0x7e, 0x00, 0x78, //0x87a0,
+ 0x54, 0x12, 0x0b, 0xb6, 0xad, 0x03, 0x7c, 0x00, 0x12, 0x04, 0xd3, 0x78, 0x58, 0xa6, 0x06, 0x08, //0x87b0,
+ 0xa6, 0x07, 0xc3, 0x78, 0x5b, 0xe6, 0x94, 0x08, 0x18, 0xe6, 0x94, 0x00, 0x50, 0x05, 0x76, 0x00, //0x87c0,
+ 0x08, 0x76, 0x08, 0xc3, 0x78, 0x5d, 0xe6, 0x94, 0x08, 0x18, 0xe6, 0x94, 0x00, 0x50, 0x05, 0x76, //0x87d0,
+ 0x00, 0x08, 0x76, 0x08, 0x78, 0x5a, 0x12, 0x0b, 0xc6, 0xff, 0xd3, 0x78, 0x57, 0xe6, 0x9f, 0x18, //0x87e0,
+ 0xe6, 0x9e, 0x40, 0x0e, 0x78, 0x5a, 0xe6, 0x13, 0xfe, 0x08, 0xe6, 0x78, 0x57, 0x12, 0x0c, 0x08, //0x87f0,
+ 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x78, 0x5e, 0x12, 0x0b, 0xbe, 0xff, 0xd3, 0x78, 0x59, 0xe6, //0x8800,
+ 0x9f, 0x18, 0xe6, 0x9e, 0x40, 0x0e, 0x78, 0x5c, 0xe6, 0x13, 0xfe, 0x08, 0xe6, 0x78, 0x59, 0x12, //0x8810,
+ 0x0c, 0x08, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xe4, 0xfc, 0xfd, 0x78, 0x62, 0x12, 0x06, 0x99, //0x8820,
+ 0x78, 0x5a, 0x12, 0x0b, 0xc6, 0x78, 0x57, 0x26, 0xff, 0xee, 0x18, 0x36, 0xfe, 0x78, 0x66, 0x12, //0x8830,
+ 0x0b, 0xbe, 0x78, 0x59, 0x26, 0xff, 0xee, 0x18, 0x36, 0xfe, 0xe4, 0xfc, 0xfd, 0x78, 0x6a, 0x12, //0x8840,
+ 0x06, 0x99, 0x12, 0x0b, 0xce, 0x78, 0x66, 0x12, 0x06, 0x8c, 0xd3, 0x12, 0x06, 0x45, 0x40, 0x08, //0x8850,
+ 0x12, 0x0b, 0xce, 0x78, 0x66, 0x12, 0x06, 0x99, 0x78, 0x54, 0x12, 0x0b, 0xd0, 0x78, 0x6a, 0x12, //0x8860,
+ 0x06, 0x8c, 0xd3, 0x12, 0x06, 0x45, 0x40, 0x0a, 0x78, 0x54, 0x12, 0x0b, 0xd0, 0x78, 0x6a, 0x12, //0x8870,
+ 0x06, 0x99, 0x78, 0x61, 0xe6, 0x90, 0x60, 0x01, 0xf0, 0x78, 0x65, 0xe6, 0xa3, 0xf0, 0x78, 0x69, //0x8880,
+ 0xe6, 0xa3, 0xf0, 0x78, 0x55, 0xe6, 0xa3, 0xf0, 0x7d, 0x01, 0x78, 0x61, 0x12, 0x0b, 0xe9, 0x24, //0x8890,
+ 0x01, 0x12, 0x0b, 0xa6, 0x78, 0x65, 0x12, 0x0b, 0xe9, 0x24, 0x02, 0x12, 0x0b, 0xa6, 0x78, 0x69, //0x88a0,
+ 0x12, 0x0b, 0xe9, 0x24, 0x03, 0x12, 0x0b, 0xa6, 0x78, 0x6d, 0x12, 0x0b, 0xe9, 0x24, 0x04, 0x12, //0x88b0,
+ 0x0b, 0xa6, 0x0d, 0xbd, 0x05, 0xd4, 0xc2, 0x0e, 0xc2, 0x06, 0x22, 0x85, 0x08, 0x41, 0x90, 0x30, //0x88c0,
+ 0x24, 0xe0, 0xf5, 0x3d, 0xa3, 0xe0, 0xf5, 0x3e, 0xa3, 0xe0, 0xf5, 0x3f, 0xa3, 0xe0, 0xf5, 0x40, //0x88d0,
+ 0xa3, 0xe0, 0xf5, 0x3c, 0xd2, 0x34, 0xe5, 0x41, 0x12, 0x06, 0xb1, 0x09, 0x31, 0x03, 0x09, 0x35, //0x88e0,
+ 0x04, 0x09, 0x3b, 0x05, 0x09, 0x3e, 0x06, 0x09, 0x41, 0x07, 0x09, 0x4a, 0x08, 0x09, 0x5b, 0x12, //0x88f0,
+ 0x09, 0x73, 0x18, 0x09, 0x89, 0x19, 0x09, 0x5e, 0x1a, 0x09, 0x6a, 0x1b, 0x09, 0xad, 0x80, 0x09, //0x8900,
+ 0xb2, 0x81, 0x0a, 0x1d, 0x8f, 0x0a, 0x09, 0x90, 0x0a, 0x1d, 0x91, 0x0a, 0x1d, 0x92, 0x0a, 0x1d, //0x8910,
+ 0x93, 0x0a, 0x1d, 0x94, 0x0a, 0x1d, 0x98, 0x0a, 0x17, 0x9f, 0x0a, 0x1a, 0xec, 0x00, 0x00, 0x0a, //0x8920,
+ 0x38, 0x12, 0x0f, 0x74, 0x22, 0x12, 0x0f, 0x74, 0xd2, 0x03, 0x22, 0xd2, 0x03, 0x22, 0xc2, 0x03, //0x8930,
+ 0x22, 0xa2, 0x37, 0xe4, 0x33, 0xf5, 0x3c, 0x02, 0x0a, 0x1d, 0xc2, 0x01, 0xc2, 0x02, 0xc2, 0x03, //0x8940,
+ 0x12, 0x0d, 0x0d, 0x75, 0x1e, 0x70, 0xd2, 0x35, 0x02, 0x0a, 0x1d, 0x02, 0x0a, 0x04, 0x85, 0x40, //0x8950,
+ 0x4a, 0x85, 0x3c, 0x4b, 0x12, 0x0a, 0xff, 0x02, 0x0a, 0x1d, 0x85, 0x4a, 0x40, 0x85, 0x4b, 0x3c, //0x8960,
+ 0x02, 0x0a, 0x1d, 0xe4, 0xf5, 0x22, 0xf5, 0x23, 0x85, 0x40, 0x31, 0x85, 0x3f, 0x30, 0x85, 0x3e, //0x8970,
+ 0x2f, 0x85, 0x3d, 0x2e, 0x12, 0x0f, 0x46, 0x80, 0x1f, 0x75, 0x22, 0x00, 0x75, 0x23, 0x01, 0x74, //0x8980,
+ 0xff, 0xf5, 0x2d, 0xf5, 0x2c, 0xf5, 0x2b, 0xf5, 0x2a, 0x12, 0x0f, 0x46, 0x85, 0x2d, 0x40, 0x85, //0x8990,
+ 0x2c, 0x3f, 0x85, 0x2b, 0x3e, 0x85, 0x2a, 0x3d, 0xe4, 0xf5, 0x3c, 0x80, 0x70, 0x12, 0x0f, 0x16, //0x89a0,
+ 0x80, 0x6b, 0x85, 0x3d, 0x45, 0x85, 0x3e, 0x46, 0xe5, 0x47, 0xc3, 0x13, 0xff, 0xe5, 0x45, 0xc3, //0x89b0,
+ 0x9f, 0x50, 0x02, 0x8f, 0x45, 0xe5, 0x48, 0xc3, 0x13, 0xff, 0xe5, 0x46, 0xc3, 0x9f, 0x50, 0x02, //0x89c0,
+ 0x8f, 0x46, 0xe5, 0x47, 0xc3, 0x13, 0xff, 0xfd, 0xe5, 0x45, 0x2d, 0xfd, 0xe4, 0x33, 0xfc, 0xe5, //0x89d0,
+ 0x44, 0x12, 0x0f, 0x90, 0x40, 0x05, 0xe5, 0x44, 0x9f, 0xf5, 0x45, 0xe5, 0x48, 0xc3, 0x13, 0xff, //0x89e0,
+ 0xfd, 0xe5, 0x46, 0x2d, 0xfd, 0xe4, 0x33, 0xfc, 0xe5, 0x43, 0x12, 0x0f, 0x90, 0x40, 0x05, 0xe5, //0x89f0,
+ 0x43, 0x9f, 0xf5, 0x46, 0x12, 0x06, 0xd7, 0x80, 0x14, 0x85, 0x40, 0x48, 0x85, 0x3f, 0x47, 0x85, //0x8a00,
+ 0x3e, 0x46, 0x85, 0x3d, 0x45, 0x80, 0x06, 0x02, 0x06, 0xd7, 0x12, 0x0d, 0x7e, 0x90, 0x30, 0x24, //0x8a10,
+ 0xe5, 0x3d, 0xf0, 0xa3, 0xe5, 0x3e, 0xf0, 0xa3, 0xe5, 0x3f, 0xf0, 0xa3, 0xe5, 0x40, 0xf0, 0xa3, //0x8a20,
+ 0xe5, 0x3c, 0xf0, 0x90, 0x30, 0x23, 0xe4, 0xf0, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, //0x8a30,
+ 0xd0, 0x90, 0x3f, 0x0c, 0xe0, 0xf5, 0x32, 0xe5, 0x32, 0x30, 0xe3, 0x74, 0x30, 0x36, 0x66, 0x90, //0x8a40,
+ 0x60, 0x19, 0xe0, 0xf5, 0x0a, 0xa3, 0xe0, 0xf5, 0x0b, 0x90, 0x60, 0x1d, 0xe0, 0xf5, 0x14, 0xa3, //0x8a50,
+ 0xe0, 0xf5, 0x15, 0x90, 0x60, 0x21, 0xe0, 0xf5, 0x0c, 0xa3, 0xe0, 0xf5, 0x0d, 0x90, 0x60, 0x29, //0x8a60,
+ 0xe0, 0xf5, 0x0e, 0xa3, 0xe0, 0xf5, 0x0f, 0x90, 0x60, 0x31, 0xe0, 0xf5, 0x10, 0xa3, 0xe0, 0xf5, //0x8a70,
+ 0x11, 0x90, 0x60, 0x39, 0xe0, 0xf5, 0x12, 0xa3, 0xe0, 0xf5, 0x13, 0x30, 0x01, 0x06, 0x30, 0x33, //0x8a80,
+ 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x09, 0x30, 0x02, 0x06, 0x30, 0x33, 0x03, 0xd3, 0x80, 0x01, //0x8a90,
+ 0xc3, 0x92, 0x0a, 0x30, 0x33, 0x0c, 0x30, 0x03, 0x09, 0x20, 0x02, 0x06, 0x20, 0x01, 0x03, 0xd3, //0x8aa0,
+ 0x80, 0x01, 0xc3, 0x92, 0x0b, 0x90, 0x30, 0x01, 0xe0, 0x44, 0x40, 0xf0, 0xe0, 0x54, 0xbf, 0xf0, //0x8ab0,
+ 0xe5, 0x32, 0x30, 0xe1, 0x14, 0x30, 0x34, 0x11, 0x90, 0x30, 0x22, 0xe0, 0xf5, 0x08, 0xe4, 0xf0, //0x8ac0,
+ 0x30, 0x00, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x08, 0xe5, 0x32, 0x30, 0xe5, 0x12, 0x90, 0x56, //0x8ad0,
+ 0xa1, 0xe0, 0xf5, 0x09, 0x30, 0x31, 0x09, 0x30, 0x05, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x0d, //0x8ae0,
+ 0x90, 0x3f, 0x0c, 0xe5, 0x32, 0xf0, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, //0x8af0,
+ 0x0e, 0x7e, 0xe4, 0x93, 0xfe, 0x74, 0x01, 0x93, 0xff, 0xc3, 0x90, 0x0e, 0x7c, 0x74, 0x01, 0x93, //0x8b00,
+ 0x9f, 0xff, 0xe4, 0x93, 0x9e, 0xfe, 0xe4, 0x8f, 0x3b, 0x8e, 0x3a, 0xf5, 0x39, 0xf5, 0x38, 0xab, //0x8b10,
+ 0x3b, 0xaa, 0x3a, 0xa9, 0x39, 0xa8, 0x38, 0xaf, 0x4b, 0xfc, 0xfd, 0xfe, 0x12, 0x05, 0x28, 0x12, //0x8b20,
+ 0x0d, 0xe1, 0xe4, 0x7b, 0xff, 0xfa, 0xf9, 0xf8, 0x12, 0x05, 0xb3, 0x12, 0x0d, 0xe1, 0x90, 0x0e, //0x8b30,
+ 0x69, 0xe4, 0x12, 0x0d, 0xf6, 0x12, 0x0d, 0xe1, 0xe4, 0x85, 0x4a, 0x37, 0xf5, 0x36, 0xf5, 0x35, //0x8b40,
+ 0xf5, 0x34, 0xaf, 0x37, 0xae, 0x36, 0xad, 0x35, 0xac, 0x34, 0xa3, 0x12, 0x0d, 0xf6, 0x8f, 0x37, //0x8b50,
+ 0x8e, 0x36, 0x8d, 0x35, 0x8c, 0x34, 0xe5, 0x3b, 0x45, 0x37, 0xf5, 0x3b, 0xe5, 0x3a, 0x45, 0x36, //0x8b60,
+ 0xf5, 0x3a, 0xe5, 0x39, 0x45, 0x35, 0xf5, 0x39, 0xe5, 0x38, 0x45, 0x34, 0xf5, 0x38, 0xe4, 0xf5, //0x8b70,
+ 0x22, 0xf5, 0x23, 0x85, 0x3b, 0x31, 0x85, 0x3a, 0x30, 0x85, 0x39, 0x2f, 0x85, 0x38, 0x2e, 0x02, //0x8b80,
+ 0x0f, 0x46, 0xe0, 0xa3, 0xe0, 0x75, 0xf0, 0x02, 0xa4, 0xff, 0xae, 0xf0, 0xc3, 0x08, 0xe6, 0x9f, //0x8b90,
+ 0xf6, 0x18, 0xe6, 0x9e, 0xf6, 0x22, 0xff, 0xe5, 0xf0, 0x34, 0x60, 0x8f, 0x82, 0xf5, 0x83, 0xec, //0x8ba0,
+ 0xf0, 0x22, 0x78, 0x52, 0x7e, 0x00, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x02, 0x04, 0xc1, 0xe4, 0xfc, //0x8bb0,
+ 0xfd, 0x12, 0x06, 0x99, 0x78, 0x5c, 0xe6, 0xc3, 0x13, 0xfe, 0x08, 0xe6, 0x13, 0x22, 0x78, 0x52, //0x8bc0,
+ 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0xe4, 0xfc, 0xfd, 0x22, 0xe7, 0xc4, 0xf8, 0x54, 0xf0, 0xc8, 0x68, //0x8bd0,
+ 0xf7, 0x09, 0xe7, 0xc4, 0x54, 0x0f, 0x48, 0xf7, 0x22, 0xe6, 0xfc, 0xed, 0x75, 0xf0, 0x04, 0xa4, //0x8be0,
+ 0x22, 0x12, 0x06, 0x7c, 0x8f, 0x48, 0x8e, 0x47, 0x8d, 0x46, 0x8c, 0x45, 0x22, 0xe0, 0xfe, 0xa3, //0x8bf0,
+ 0xe0, 0xfd, 0xee, 0xf6, 0xed, 0x08, 0xf6, 0x22, 0x13, 0xff, 0xc3, 0xe6, 0x9f, 0xff, 0x18, 0xe6, //0x8c00,
+ 0x9e, 0xfe, 0x22, 0xe6, 0xc3, 0x13, 0xf7, 0x08, 0xe6, 0x13, 0x09, 0xf7, 0x22, 0xad, 0x39, 0xac, //0x8c10,
+ 0x38, 0xfa, 0xf9, 0xf8, 0x12, 0x05, 0x28, 0x8f, 0x3b, 0x8e, 0x3a, 0x8d, 0x39, 0x8c, 0x38, 0xab, //0x8c20,
+ 0x37, 0xaa, 0x36, 0xa9, 0x35, 0xa8, 0x34, 0x22, 0x93, 0xff, 0xe4, 0xfc, 0xfd, 0xfe, 0x12, 0x05, //0x8c30,
+ 0x28, 0x8f, 0x37, 0x8e, 0x36, 0x8d, 0x35, 0x8c, 0x34, 0x22, 0x78, 0x84, 0xe6, 0xfe, 0x08, 0xe6, //0x8c40,
+ 0xff, 0xe4, 0x8f, 0x37, 0x8e, 0x36, 0xf5, 0x35, 0xf5, 0x34, 0x22, 0x90, 0x0e, 0x8c, 0xe4, 0x93, //0x8c50,
+ 0x25, 0xe0, 0x24, 0x0a, 0xf8, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x22, 0xe6, 0xfe, 0x08, 0xe6, 0xff, //0x8c60,
+ 0xe4, 0x8f, 0x3b, 0x8e, 0x3a, 0xf5, 0x39, 0xf5, 0x38, 0x22, 0x78, 0x4e, 0xe6, 0xfe, 0x08, 0xe6, //0x8c70,
+ 0xff, 0x22, 0xef, 0x25, 0xe0, 0x24, 0x4e, 0xf8, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x22, 0x78, 0x89, //0x8c80,
+ 0xef, 0x26, 0xf6, 0x18, 0xe4, 0x36, 0xf6, 0x22, 0x75, 0x89, 0x03, 0x75, 0xa8, 0x01, 0x75, 0xb8, //0x8c90,
+ 0x04, 0x75, 0x34, 0xff, 0x75, 0x35, 0x0e, 0x75, 0x36, 0x15, 0x75, 0x37, 0x0d, 0x12, 0x0e, 0x9a, //0x8ca0,
+ 0x12, 0x00, 0x09, 0x12, 0x0f, 0x16, 0x12, 0x00, 0x06, 0xd2, 0x00, 0xd2, 0x34, 0xd2, 0xaf, 0x75, //0x8cb0,
+ 0x34, 0xff, 0x75, 0x35, 0x0e, 0x75, 0x36, 0x49, 0x75, 0x37, 0x03, 0x12, 0x0e, 0x9a, 0x30, 0x08, //0x8cc0,
+ 0x09, 0xc2, 0x34, 0x12, 0x08, 0xcb, 0xc2, 0x08, 0xd2, 0x34, 0x30, 0x0b, 0x09, 0xc2, 0x36, 0x12, //0x8cd0,
+ 0x02, 0x6c, 0xc2, 0x0b, 0xd2, 0x36, 0x30, 0x09, 0x09, 0xc2, 0x36, 0x12, 0x00, 0x0e, 0xc2, 0x09, //0x8ce0,
+ 0xd2, 0x36, 0x30, 0x0e, 0x03, 0x12, 0x06, 0xd7, 0x30, 0x35, 0xd3, 0x90, 0x30, 0x29, 0xe5, 0x1e, //0x8cf0,
+ 0xf0, 0xb4, 0x10, 0x05, 0x90, 0x30, 0x23, 0xe4, 0xf0, 0xc2, 0x35, 0x80, 0xc1, 0xe4, 0xf5, 0x4b, //0x8d00,
+ 0x90, 0x0e, 0x7a, 0x93, 0xff, 0xe4, 0x8f, 0x37, 0xf5, 0x36, 0xf5, 0x35, 0xf5, 0x34, 0xaf, 0x37, //0x8d10,
+ 0xae, 0x36, 0xad, 0x35, 0xac, 0x34, 0x90, 0x0e, 0x6a, 0x12, 0x0d, 0xf6, 0x8f, 0x37, 0x8e, 0x36, //0x8d20,
+ 0x8d, 0x35, 0x8c, 0x34, 0x90, 0x0e, 0x72, 0x12, 0x06, 0x7c, 0xef, 0x45, 0x37, 0xf5, 0x37, 0xee, //0x8d30,
+ 0x45, 0x36, 0xf5, 0x36, 0xed, 0x45, 0x35, 0xf5, 0x35, 0xec, 0x45, 0x34, 0xf5, 0x34, 0xe4, 0xf5, //0x8d40,
+ 0x22, 0xf5, 0x23, 0x85, 0x37, 0x31, 0x85, 0x36, 0x30, 0x85, 0x35, 0x2f, 0x85, 0x34, 0x2e, 0x12, //0x8d50,
+ 0x0f, 0x46, 0xe4, 0xf5, 0x22, 0xf5, 0x23, 0x90, 0x0e, 0x72, 0x12, 0x0d, 0xea, 0x12, 0x0f, 0x46, //0x8d60,
+ 0xe4, 0xf5, 0x22, 0xf5, 0x23, 0x90, 0x0e, 0x6e, 0x12, 0x0d, 0xea, 0x02, 0x0f, 0x46, 0xe5, 0x40, //0x8d70,
+ 0x24, 0xf2, 0xf5, 0x37, 0xe5, 0x3f, 0x34, 0x43, 0xf5, 0x36, 0xe5, 0x3e, 0x34, 0xa2, 0xf5, 0x35, //0x8d80,
+ 0xe5, 0x3d, 0x34, 0x28, 0xf5, 0x34, 0xe5, 0x37, 0xff, 0xe4, 0xfe, 0xfd, 0xfc, 0x78, 0x18, 0x12, //0x8d90,
+ 0x06, 0x69, 0x8f, 0x40, 0x8e, 0x3f, 0x8d, 0x3e, 0x8c, 0x3d, 0xe5, 0x37, 0x54, 0xa0, 0xff, 0xe5, //0x8da0,
+ 0x36, 0xfe, 0xe4, 0xfd, 0xfc, 0x78, 0x07, 0x12, 0x06, 0x56, 0x78, 0x10, 0x12, 0x0f, 0x9a, 0xe4, //0x8db0,
+ 0xff, 0xfe, 0xe5, 0x35, 0xfd, 0xe4, 0xfc, 0x78, 0x0e, 0x12, 0x06, 0x56, 0x12, 0x0f, 0x9d, 0xe4, //0x8dc0,
+ 0xff, 0xfe, 0xfd, 0xe5, 0x34, 0xfc, 0x78, 0x18, 0x12, 0x06, 0x56, 0x78, 0x08, 0x12, 0x0f, 0x9a, //0x8dd0,
+ 0x22, 0x8f, 0x3b, 0x8e, 0x3a, 0x8d, 0x39, 0x8c, 0x38, 0x22, 0x12, 0x06, 0x7c, 0x8f, 0x31, 0x8e, //0x8de0,
+ 0x30, 0x8d, 0x2f, 0x8c, 0x2e, 0x22, 0x93, 0xf9, 0xf8, 0x02, 0x06, 0x69, 0x00, 0x00, 0x00, 0x00, //0x8df0,
+ 0x12, 0x01, 0x17, 0x08, 0x31, 0x15, 0x53, 0x54, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0x13, 0x01, //0x8e00,
+ 0x10, 0x01, 0x56, 0x40, 0x1a, 0x30, 0x29, 0x7e, 0x00, 0x30, 0x04, 0x20, 0xdf, 0x30, 0x05, 0x40, //0x8e10,
+ 0xbf, 0x50, 0x03, 0x00, 0xfd, 0x50, 0x27, 0x01, 0xfe, 0x60, 0x00, 0x11, 0x00, 0x3f, 0x05, 0x30, //0x8e20,
+ 0x00, 0x3f, 0x06, 0x22, 0x00, 0x3f, 0x01, 0x2a, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x36, 0x06, 0x07, //0x8e30,
+ 0x00, 0x3f, 0x0b, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x40, 0xbf, 0x30, 0x01, 0x00, //0x8e40,
+ 0xbf, 0x30, 0x29, 0x70, 0x00, 0x3a, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, 0x36, 0x03, 0x36, //0x8e50,
+ 0x02, 0x41, 0x44, 0x58, 0x20, 0x18, 0x10, 0x0a, 0x04, 0x04, 0x00, 0x03, 0xff, 0x64, 0x00, 0x00, //0x8e60,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x06, 0x06, 0x00, 0x03, 0x51, 0x00, 0x7a, //0x8e70,
+ 0x50, 0x3c, 0x28, 0x1e, 0x10, 0x10, 0x50, 0x2d, 0x28, 0x16, 0x10, 0x10, 0x02, 0x00, 0x10, 0x0c, //0x8e80,
+ 0x10, 0x04, 0x0c, 0x6e, 0x06, 0x05, 0x00, 0xa5, 0x5a, 0x00, 0xae, 0x35, 0xaf, 0x36, 0xe4, 0xfd, //0x8e90,
+ 0xed, 0xc3, 0x95, 0x37, 0x50, 0x33, 0x12, 0x0f, 0xe2, 0xe4, 0x93, 0xf5, 0x38, 0x74, 0x01, 0x93, //0x8ea0,
+ 0xf5, 0x39, 0x45, 0x38, 0x60, 0x23, 0x85, 0x39, 0x82, 0x85, 0x38, 0x83, 0xe0, 0xfc, 0x12, 0x0f, //0x8eb0,
+ 0xe2, 0x74, 0x03, 0x93, 0x52, 0x04, 0x12, 0x0f, 0xe2, 0x74, 0x02, 0x93, 0x42, 0x04, 0x85, 0x39, //0x8ec0,
+ 0x82, 0x85, 0x38, 0x83, 0xec, 0xf0, 0x0d, 0x80, 0xc7, 0x22, 0x78, 0xbe, 0xe6, 0xd3, 0x08, 0xff, //0x8ed0,
+ 0xe6, 0x64, 0x80, 0xf8, 0xef, 0x64, 0x80, 0x98, 0x22, 0x93, 0xff, 0x7e, 0x00, 0xe6, 0xfc, 0x08, //0x8ee0,
+ 0xe6, 0xfd, 0x12, 0x04, 0xc1, 0x78, 0xc1, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0xd3, 0xef, 0x9d, 0xee, //0x8ef0,
+ 0x9c, 0x22, 0x78, 0xbd, 0xd3, 0xe6, 0x64, 0x80, 0x94, 0x80, 0x22, 0x25, 0xe0, 0x24, 0x0a, 0xf8, //0x8f00,
+ 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x22, 0xe5, 0x3c, 0xd3, 0x94, 0x00, 0x40, 0x0b, 0x90, 0x0e, 0x88, //0x8f10,
+ 0x12, 0x0b, 0xf1, 0x90, 0x0e, 0x86, 0x80, 0x09, 0x90, 0x0e, 0x82, 0x12, 0x0b, 0xf1, 0x90, 0x0e, //0x8f20,
+ 0x80, 0xe4, 0x93, 0xf5, 0x44, 0xa3, 0xe4, 0x93, 0xf5, 0x43, 0xd2, 0x06, 0x30, 0x06, 0x03, 0xd3, //0x8f30,
+ 0x80, 0x01, 0xc3, 0x92, 0x0e, 0x22, 0xa2, 0xaf, 0x92, 0x32, 0xc2, 0xaf, 0xe5, 0x23, 0x45, 0x22, //0x8f40,
+ 0x90, 0x0e, 0x5d, 0x60, 0x0e, 0x12, 0x0f, 0xcb, 0xe0, 0xf5, 0x2c, 0x12, 0x0f, 0xc8, 0xe0, 0xf5, //0x8f50,
+ 0x2d, 0x80, 0x0c, 0x12, 0x0f, 0xcb, 0xe5, 0x30, 0xf0, 0x12, 0x0f, 0xc8, 0xe5, 0x31, 0xf0, 0xa2, //0x8f60,
+ 0x32, 0x92, 0xaf, 0x22, 0xd2, 0x01, 0xc2, 0x02, 0xe4, 0xf5, 0x1f, 0xf5, 0x1e, 0xd2, 0x35, 0xd2, //0x8f70,
+ 0x33, 0xd2, 0x36, 0xd2, 0x01, 0xc2, 0x02, 0xf5, 0x1f, 0xf5, 0x1e, 0xd2, 0x35, 0xd2, 0x33, 0x22, //0x8f80,
+ 0xfb, 0xd3, 0xed, 0x9b, 0x74, 0x80, 0xf8, 0x6c, 0x98, 0x22, 0x12, 0x06, 0x69, 0xe5, 0x40, 0x2f, //0x8f90,
+ 0xf5, 0x40, 0xe5, 0x3f, 0x3e, 0xf5, 0x3f, 0xe5, 0x3e, 0x3d, 0xf5, 0x3e, 0xe5, 0x3d, 0x3c, 0xf5, //0x8fa0,
+ 0x3d, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x3f, 0x0d, 0xe0, 0xf5, 0x33, 0xe5, 0x33, //0x8fb0,
+ 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x0e, 0x5f, 0xe4, 0x93, 0xfe, 0x74, 0x01, //0x8fc0,
+ 0x93, 0xf5, 0x82, 0x8e, 0x83, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0xcd, 0x02, //0x8fd0,
+ 0x0c, 0x98, 0x8f, 0x82, 0x8e, 0x83, 0x75, 0xf0, 0x04, 0xed, 0x02, 0x06, 0xa5, //0x8fe0
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pmic.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pmic.c
index aeabf5e716..174fd3bdac 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pmic.c
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pmic.c
@@ -798,47 +798,47 @@ static rt_err_t rt_hw_pmic_init_register(void)
stpmu1_write_reg(BUCK_ICC_TURNOFF_REG, 0x30);
stpmu1_write_reg(LDO_ICC_TURNOFF_REG, 0x3b);
- /* vddcore */
- STPMU1_Regulator_Voltage_Set(STPMU1_BUCK1, 1200);
- STPMU1_Regulator_Enable(STPMU1_BUCK1);
+ /* vddcore */
+ STPMU1_Regulator_Voltage_Set(STPMU1_BUCK1, 1200);
+ STPMU1_Regulator_Enable(STPMU1_BUCK1);
- /* vddddr */
- STPMU1_Regulator_Voltage_Set(STPMU1_BUCK2, 1350);
- STPMU1_Regulator_Enable(STPMU1_BUCK2);
+ /* vddddr */
+ STPMU1_Regulator_Voltage_Set(STPMU1_BUCK2, 1350);
+ STPMU1_Regulator_Enable(STPMU1_BUCK2);
- /* vdd */
- STPMU1_Regulator_Voltage_Set(STPMU1_BUCK3, 3300);
- STPMU1_Regulator_Enable(STPMU1_BUCK3);
+ /* vdd */
+ STPMU1_Regulator_Voltage_Set(STPMU1_BUCK3, 3300);
+ STPMU1_Regulator_Enable(STPMU1_BUCK3);
- /* 3v3 */
- STPMU1_Regulator_Voltage_Set(STPMU1_BUCK4, 3300);
- STPMU1_Regulator_Enable(STPMU1_BUCK4);
+ /* 3v3 */
+ STPMU1_Regulator_Voltage_Set(STPMU1_BUCK4, 3300);
+ STPMU1_Regulator_Enable(STPMU1_BUCK4);
- /* vdda */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO1, 2900);
- STPMU1_Regulator_Enable(STPMU1_LDO1);
+ /* vdda */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO1, 2900);
+ STPMU1_Regulator_Enable(STPMU1_LDO1);
- /* 2v8 */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO2, 2800);
- STPMU1_Regulator_Enable(STPMU1_LDO2);
+ /* 2v8 */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO2, 2800);
+ STPMU1_Regulator_Enable(STPMU1_LDO2);
- /* vtt_ddr lod3 mode buck2/2 */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO3, 0xFFFF);
- STPMU1_Regulator_Enable(STPMU1_LDO3);
+ /* vtt_ddr lod3 mode buck2/2 */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO3, 0xFFFF);
+ STPMU1_Regulator_Enable(STPMU1_LDO3);
- /* vdd_usb */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO4, 3300);
- STPMU1_Regulator_Enable(STPMU1_LDO4);
+ /* vdd_usb */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO4, 3300);
+ STPMU1_Regulator_Enable(STPMU1_LDO4);
- /* vdd_sd */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO5, 2900);
- STPMU1_Regulator_Enable(STPMU1_LDO5);
+ /* vdd_sd */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO5, 2900);
+ STPMU1_Regulator_Enable(STPMU1_LDO5);
- /* 1v8 */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO6, 1800);
- STPMU1_Regulator_Enable(STPMU1_LDO6);
+ /* 1v8 */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO6, 1800);
+ STPMU1_Regulator_Enable(STPMU1_LDO6);
- STPMU1_Regulator_Enable(STPMU1_VREFDDR);
+ STPMU1_Regulator_Enable(STPMU1_VREFDDR);
return RT_EOK;
}
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.c
new file mode 100644
index 0000000000..d02902ca3e
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.c
@@ -0,0 +1,1602 @@
+/**
+ ******************************************************************************
+ * @file mfxstm32l152.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the MFXSTM32L152
+ * IO Expander devices.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; 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 "mfxstm32l152.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Component
+ * @{
+ */
+
+/** @defgroup MFXSTM32L152
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Types_Definitions
+ * @{
+ */
+
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Defines
+ * @{
+ */
+#define MFXSTM32L152_MAX_INSTANCE 3
+
+/* Private macro -------------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Macros
+ * @{
+ */
+
+/* Private variables ---------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Variables
+ * @{
+ */
+
+/* Touch screen driver structure initialization */
+TS_DrvTypeDef mfxstm32l152_ts_drv =
+{
+ mfxstm32l152_Init,
+ mfxstm32l152_ReadID,
+ mfxstm32l152_Reset,
+
+ mfxstm32l152_TS_Start,
+ mfxstm32l152_TS_DetectTouch,
+ mfxstm32l152_TS_GetXY,
+
+ mfxstm32l152_TS_EnableIT,
+ mfxstm32l152_TS_ClearIT,
+ mfxstm32l152_TS_ITStatus,
+ mfxstm32l152_TS_DisableIT,
+};
+
+/* IO driver structure initialization */
+IO_DrvTypeDef mfxstm32l152_io_drv =
+{
+ mfxstm32l152_Init,
+ mfxstm32l152_ReadID,
+ mfxstm32l152_Reset,
+
+ mfxstm32l152_IO_Start,
+ mfxstm32l152_IO_Config,
+ mfxstm32l152_IO_WritePin,
+ mfxstm32l152_IO_ReadPin,
+
+ mfxstm32l152_IO_EnableIT,
+ mfxstm32l152_IO_DisableIT,
+ mfxstm32l152_IO_ITStatus,
+ mfxstm32l152_IO_ClearIT,
+};
+
+/* IDD driver structure initialization */
+IDD_DrvTypeDef mfxstm32l152_idd_drv =
+{
+ mfxstm32l152_Init,
+ mfxstm32l152_DeInit,
+ mfxstm32l152_ReadID,
+ mfxstm32l152_Reset,
+ mfxstm32l152_LowPower,
+ mfxstm32l152_WakeUp,
+
+ mfxstm32l152_IDD_Start,
+ mfxstm32l152_IDD_Config,
+ mfxstm32l152_IDD_GetValue,
+
+ mfxstm32l152_IDD_EnableIT,
+ mfxstm32l152_IDD_ClearIT,
+ mfxstm32l152_IDD_GetITStatus,
+ mfxstm32l152_IDD_DisableIT,
+
+ mfxstm32l152_Error_EnableIT,
+ mfxstm32l152_Error_ClearIT,
+ mfxstm32l152_Error_GetITStatus,
+ mfxstm32l152_Error_DisableIT,
+ mfxstm32l152_Error_ReadSrc,
+ mfxstm32l152_Error_ReadMsg
+};
+
+
+/* mfxstm32l152 instances by address */
+uint8_t mfxstm32l152[MFXSTM32L152_MAX_INSTANCE] = {0};
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Function_Prototypes
+ * @{
+ */
+static uint8_t mfxstm32l152_GetInstance(uint16_t DeviceAddr);
+static uint8_t mfxstm32l152_ReleaseInstance(uint16_t DeviceAddr);
+static void mfxstm32l152_reg24_setPinValue(uint16_t DeviceAddr, uint8_t RegisterAddr, uint32_t PinPosition, uint8_t PinValue );
+
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Initialize the mfxstm32l152 and configure the needed hardware resources
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_Init(uint16_t DeviceAddr)
+{
+ uint8_t instance;
+ uint8_t empty;
+
+ /* Check if device instance already exists */
+ instance = mfxstm32l152_GetInstance(DeviceAddr);
+
+ /* To prevent double initialization */
+ if(instance == 0xFF)
+ {
+ /* Look for empty instance */
+ empty = mfxstm32l152_GetInstance(0);
+
+ if(empty < MFXSTM32L152_MAX_INSTANCE)
+ {
+ /* Register the current device instance */
+ mfxstm32l152[empty] = DeviceAddr;
+
+ /* Initialize IO BUS layer */
+ MFX_IO_Init();
+ }
+ }
+
+ mfxstm32l152_SetIrqOutPinPolarity(DeviceAddr, MFXSTM32L152_OUT_PIN_POLARITY_HIGH);
+ mfxstm32l152_SetIrqOutPinType(DeviceAddr, MFXSTM32L152_OUT_PIN_TYPE_PUSHPULL);
+}
+
+/**
+ * @brief DeInitialize the mfxstm32l152 and unconfigure the needed hardware resources
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_DeInit(uint16_t DeviceAddr)
+{
+ uint8_t instance;
+
+ /* release existing instance */
+ instance = mfxstm32l152_ReleaseInstance(DeviceAddr);
+
+ /* De-Init only if instance was previously registered */
+ if(instance != 0xFF)
+ {
+ /* De-Initialize IO BUS layer */
+ MFX_IO_DeInit();
+ }
+}
+
+/**
+ * @brief Reset the mfxstm32l152 by Software.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_Reset(uint16_t DeviceAddr)
+{
+ /* Soft Reset */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, MFXSTM32L152_SWRST);
+
+ /* Wait for a delay to ensure registers erasing */
+ rt_thread_delay(10);
+}
+
+/**
+ * @brief Put mfxstm32l152 Device in Low Power standby mode
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_LowPower(uint16_t DeviceAddr)
+{
+ /* Enter standby mode */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, MFXSTM32L152_STANDBY);
+
+ /* enable wakeup pin */
+ MFX_IO_EnableWakeupPin();
+}
+
+/**
+ * @brief WakeUp mfxstm32l152 from standby mode
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_WakeUp(uint16_t DeviceAddr)
+{
+ uint8_t instance;
+
+ /* Check if device instance already exists */
+ instance = mfxstm32l152_GetInstance(DeviceAddr);
+
+ /* if instance does not exist, first initialize pins*/
+ if(instance == 0xFF)
+ {
+ /* enable wakeup pin */
+ MFX_IO_EnableWakeupPin();
+ }
+
+ /* toggle wakeup pin */
+ MFX_IO_Wakeup();
+}
+
+/**
+ * @brief Read the MFXSTM32L152 IO Expander device ID.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval The Device ID (two bytes).
+ */
+uint16_t mfxstm32l152_ReadID(uint16_t DeviceAddr)
+{
+ uint8_t id;
+
+ /* Wait for a delay to ensure the state of registers */
+ rt_thread_mdelay(1);
+
+ /* Initialize IO BUS layer */
+ MFX_IO_Init();
+
+ id = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_ID);
+
+ /* Return the device ID value */
+ return (id);
+}
+
+/**
+ * @brief Read the MFXSTM32L152 device firmware version.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval The Device FW version (two bytes).
+ */
+uint16_t mfxstm32l152_ReadFwVersion(uint16_t DeviceAddr)
+{
+ uint8_t data[2];
+
+ MFX_IO_ReadMultiple((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_FW_VERSION_MSB, data, sizeof(data)) ;
+
+ /* Recompose MFX firmware value */
+ return ((data[0] << 8) | data[1]);
+}
+
+/**
+ * @brief Enable the interrupt mode for the selected IT source
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Source: The interrupt source to be configured, could be:
+ * @arg MFXSTM32L152_IRQ_GPIO: IO interrupt
+ * @arg MFXSTM32L152_IRQ_IDD : IDD interrupt
+ * @arg MFXSTM32L152_IRQ_ERROR : Error interrupt
+ * @arg MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt
+ * @arg MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty
+ * @arg MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered
+ * @arg MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full
+ * @arg MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow
+ * @retval None
+ */
+void mfxstm32l152_EnableITSource(uint16_t DeviceAddr, uint8_t Source)
+{
+ uint8_t tmp = 0;
+
+ /* Get the current value of the INT_EN register */
+ tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN);
+
+ /* Set the interrupts to be Enabled */
+ tmp |= Source;
+
+ /* Set the register */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN, tmp);
+}
+
+/**
+ * @brief Disable the interrupt mode for the selected IT source
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Source: The interrupt source to be configured, could be:
+ * @arg MFXSTM32L152_IRQ_GPIO: IO interrupt
+ * @arg MFXSTM32L152_IRQ_IDD : IDD interrupt
+ * @arg MFXSTM32L152_IRQ_ERROR : Error interrupt
+ * @arg MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt
+ * @arg MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty
+ * @arg MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered
+ * @arg MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full
+ * @arg MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow
+ * @retval None
+ */
+void mfxstm32l152_DisableITSource(uint16_t DeviceAddr, uint8_t Source)
+{
+ uint8_t tmp = 0;
+
+ /* Get the current value of the INT_EN register */
+ tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN);
+
+ /* Set the interrupts to be Enabled */
+ tmp &= ~Source;
+
+ /* Set the register */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN, tmp);
+}
+
+
+/**
+ * @brief Returns the selected Global interrupt source pending bit value
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Source: the Global interrupt source to be checked, could be:
+ * @arg MFXSTM32L152_IRQ_GPIO: IO interrupt
+ * @arg MFXSTM32L152_IRQ_IDD : IDD interrupt
+ * @arg MFXSTM32L152_IRQ_ERROR : Error interrupt
+ * @arg MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt
+ * @arg MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty
+ * @arg MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered
+ * @arg MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full
+ * @arg MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow
+ * @retval The value of the checked Global interrupt source status.
+ */
+uint8_t mfxstm32l152_GlobalITStatus(uint16_t DeviceAddr, uint8_t Source)
+{
+ /* Return the global IT source status (pending or not)*/
+ return((MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_PENDING) & Source));
+}
+
+/**
+ * @brief Clear the selected Global interrupt pending bit(s)
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Source: the Global interrupt source to be cleared, could be any combination
+ * of the below values. The acknowledge signal for MFXSTM32L152_GPIOs configured in input
+ * with interrupt is not on this register but in IRQ_GPI_ACK1, IRQ_GPI_ACK2 registers.
+ * @arg MFXSTM32L152_IRQ_IDD : IDD interrupt
+ * @arg MFXSTM32L152_IRQ_ERROR : Error interrupt
+ * @arg MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt
+ * @arg MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty
+ * @arg MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered
+ * @arg MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full
+ * @arg MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow
+ * /\/\ IMPORTANT NOTE /\/\ must not use MFXSTM32L152_IRQ_GPIO as argument, see IRQ_GPI_ACK1 and IRQ_GPI_ACK2 registers
+ * @retval None
+ */
+void mfxstm32l152_ClearGlobalIT(uint16_t DeviceAddr, uint8_t Source)
+{
+ /* Write 1 to the bits that have to be cleared */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_ACK, Source);
+}
+
+/**
+ * @brief Set the global interrupt Polarity of IRQ_OUT_PIN.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Polarity: the IT mode polarity, could be one of the following values:
+ * @arg MFXSTM32L152_OUT_PIN_POLARITY_LOW: Interrupt output line is active Low edge
+ * @arg MFXSTM32L152_OUT_PIN_POLARITY_HIGH: Interrupt line output is active High edge
+ * @retval None
+ */
+void mfxstm32l152_SetIrqOutPinPolarity(uint16_t DeviceAddr, uint8_t Polarity)
+{
+ uint8_t tmp = 0;
+
+ /* Get the current register value */
+ tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT);
+
+ /* Mask the polarity bits */
+ tmp &= ~(uint8_t)0x02;
+
+ /* Modify the Interrupt Output line configuration */
+ tmp |= Polarity;
+
+ /* Set the new register value */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT, tmp);
+
+ /* Wait for 1 ms for MFX to change IRQ_out pin config, before activate it */
+ rt_thread_delay(1);
+
+}
+
+/**
+ * @brief Set the global interrupt Type of IRQ_OUT_PIN.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Type: Interrupt line activity type, could be one of the following values:
+ * @arg MFXSTM32L152_OUT_PIN_TYPE_OPENDRAIN: Open Drain output Interrupt line
+ * @arg MFXSTM32L152_OUT_PIN_TYPE_PUSHPULL: Push Pull output Interrupt line
+ * @retval None
+ */
+void mfxstm32l152_SetIrqOutPinType(uint16_t DeviceAddr, uint8_t Type)
+{
+ uint8_t tmp = 0;
+
+ /* Get the current register value */
+ tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT);
+
+ /* Mask the type bits */
+ tmp &= ~(uint8_t)0x01;
+
+ /* Modify the Interrupt Output line configuration */
+ tmp |= Type;
+
+ /* Set the new register value */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT, tmp);
+
+ /* Wait for 1 ms for MFX to change IRQ_out pin config, before activate it */
+ rt_thread_delay(1);
+
+}
+
+
+/* ------------------------------------------------------------------ */
+/* ----------------------- GPIO ------------------------------------- */
+/* ------------------------------------------------------------------ */
+
+
+/**
+ * @brief Start the IO functionality used and enable the AF for selected IO pin(s).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param AF_en: 0 to disable, else enabled.
+ * @retval None
+ */
+void mfxstm32l152_IO_Start(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ uint8_t mode;
+
+ /* Get the current register value */
+ mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL);
+
+ /* Set the IO Functionalities to be Enabled */
+ mode |= MFXSTM32L152_GPIO_EN;
+
+ /* Enable ALTERNATE functions */
+ /* AGPIO[0..3] can be either IDD or GPIO */
+ /* AGPIO[4..7] can be either TS or GPIO */
+ /* if IDD or TS are enabled no matter the value this bit GPIO are not available for those pins */
+ /* however the MFX will waste some cycles to to handle these potential GPIO (pooling, etc) */
+ /* so if IDD and TS are both active it is better to let ALTERNATE off (0) */
+ /* if however IDD or TS are not connected then set it on gives more GPIOs availability */
+ /* remind that AGPIO are less efficient then normal GPIO (They use pooling rather then EXTI */
+ if (IO_Pin > 0xFFFF)
+ {
+ mode |= MFXSTM32L152_ALTERNATE_GPIO_EN;
+ }
+ else
+ {
+ mode &= ~MFXSTM32L152_ALTERNATE_GPIO_EN;
+ }
+
+ /* Write the new register value */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode);
+
+ /* Wait for 1 ms for MFX to change IRQ_out pin config, before activate it */
+ rt_thread_delay(1);
+}
+
+/**
+ * @brief Configures the IO pin(s) according to IO mode structure value.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The output pin to be set or reset. This parameter can be one
+ * of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+ * @param IO_Mode: The IO pin mode to configure, could be one of the following values:
+ * @arg IO_MODE_INPUT
+ * @arg IO_MODE_OUTPUT
+ * @arg IO_MODE_IT_RISING_EDGE
+ * @arg IO_MODE_IT_FALLING_EDGE
+ * @arg IO_MODE_IT_LOW_LEVEL
+ * @arg IO_MODE_IT_HIGH_LEVEL
+ * @arg IO_MODE_INPUT_PU,
+ * @arg IO_MODE_INPUT_PD,
+ * @arg IO_MODE_OUTPUT_OD_PU,
+ * @arg IO_MODE_OUTPUT_OD_PD,
+ * @arg IO_MODE_OUTPUT_PP_PU,
+ * @arg IO_MODE_OUTPUT_PP_PD,
+ * @arg IO_MODE_IT_RISING_EDGE_PU
+ * @arg IO_MODE_IT_FALLING_EDGE_PU
+ * @arg IO_MODE_IT_LOW_LEVEL_PU
+ * @arg IO_MODE_IT_HIGH_LEVEL_PU
+ * @arg IO_MODE_IT_RISING_EDGE_PD
+ * @arg IO_MODE_IT_FALLING_EDGE_PD
+ * @arg IO_MODE_IT_LOW_LEVEL_PD
+ * @arg IO_MODE_IT_HIGH_LEVEL_PD
+ * @retval None
+ */
+uint8_t mfxstm32l152_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode)
+{
+ uint8_t error_code = 0;
+
+ /* Configure IO pin according to selected IO mode */
+ switch(IO_Mode)
+ {
+ case IO_MODE_OFF: /* Off or analog mode */
+ case IO_MODE_ANALOG: /* Off or analog mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ break;
+
+ case IO_MODE_INPUT: /* Input mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ break;
+
+ case IO_MODE_INPUT_PU: /* Input mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ break;
+
+ case IO_MODE_INPUT_PD: /* Input mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ break;
+
+ case IO_MODE_OUTPUT: /* Output mode */
+ case IO_MODE_OUTPUT_PP_PD: /* Output mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_PUSH_PULL);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ break;
+
+ case IO_MODE_OUTPUT_PP_PU: /* Output mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_PUSH_PULL);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ break;
+
+ case IO_MODE_OUTPUT_OD_PD: /* Output mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_OPEN_DRAIN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ break;
+
+ case IO_MODE_OUTPUT_OD_PU: /* Output mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_OPEN_DRAIN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ break;
+
+ case IO_MODE_IT_RISING_EDGE: /* Interrupt rising edge mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_RISING_EDGE_PU: /* Interrupt rising edge mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_RISING_EDGE_PD: /* Interrupt rising edge mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_FALLING_EDGE: /* Interrupt falling edge mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_FALLING_EDGE_PU: /* Interrupt falling edge mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_FALLING_EDGE_PD: /* Interrupt falling edge mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_LOW_LEVEL: /* Low level interrupt mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_LOW_LEVEL_PU: /* Low level interrupt mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_LOW_LEVEL_PD: /* Low level interrupt mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_HIGH_LEVEL: /* High level interrupt mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_HIGH_LEVEL_PU: /* High level interrupt mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_HIGH_LEVEL_PD: /* High level interrupt mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ default:
+ error_code = (uint8_t) IO_Mode;
+ break;
+ }
+
+ return error_code;
+}
+
+/**
+ * @brief Initialize the selected IO pin direction.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO pin to be configured. This parameter could be any
+ * combination of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23.
+ * @param Direction: could be MFXSTM32L152_GPIO_DIR_IN or MFXSTM32L152_GPIO_DIR_OUT.
+ * @retval None
+ */
+void mfxstm32l152_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction)
+{
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_DIR1, IO_Pin, Direction);
+}
+
+/**
+ * @brief Set the global interrupt Type.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO pin to be configured. This parameter could be any
+ * combination of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23.
+ * @param Evt: Interrupt line activity type, could be one of the following values:
+ * @arg MFXSTM32L152_IRQ_GPI_EVT_LEVEL: Interrupt line is active in level model
+ * @arg MFXSTM32L152_IRQ_GPI_EVT_EDGE: Interrupt line is active in edge model
+ * @retval None
+ */
+void mfxstm32l152_IO_SetIrqEvtMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Evt)
+{
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_EVT1, IO_Pin, Evt);
+ rt_thread_delay(1);
+}
+
+/**
+ * @brief Configure the Edge for which a transition is detectable for the
+ * selected pin.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO pin to be configured. This parameter could be any
+ * combination of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23.
+ * @param Evt: Interrupt line activity type, could be one of the following values:
+ * @arg MFXSTM32L152_IRQ_GPI_TYPE_LLFE: Interrupt line is active in Low Level or Falling Edge
+ * @arg MFXSTM32L152_IRQ_GPI_TYPE_HLRE: Interrupt line is active in High Level or Rising Edge
+ * @retval None
+ */
+void mfxstm32l152_IO_SetIrqTypeMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Type)
+{
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE1, IO_Pin, Type);
+ rt_thread_delay(1);
+}
+
+/**
+ * @brief When GPIO is in output mode, puts the corresponding GPO in High (1) or Low (0) level.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The output pin to be set or reset. This parameter can be one
+ * of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+ * @param PinState: The new IO pin state.
+ * @retval None
+ */
+void mfxstm32l152_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState)
+{
+ /* Apply the bit value to the selected pin */
+ if (PinState != 0)
+ {
+ /* Set the SET register */
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPO_SET1, IO_Pin, 1);
+ }
+ else
+ {
+ /* Set the CLEAR register */
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPO_CLR1, IO_Pin, 1);
+ }
+}
+
+/**
+ * @brief Return the state of the selected IO pin(s).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The output pin to be set or reset. This parameter can be one
+ * of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+ * @retval IO pin(s) state.
+ */
+uint32_t mfxstm32l152_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ uint32_t tmp1 = 0;
+ uint32_t tmp2 = 0;
+ uint32_t tmp3 = 0;
+
+ if(IO_Pin & 0x000000FF)
+ {
+ tmp1 = (uint32_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_STATE1);
+ }
+ if(IO_Pin & 0x0000FF00)
+ {
+ tmp2 = (uint32_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_STATE2);
+ }
+ if(IO_Pin & 0x00FF0000)
+ {
+ tmp3 = (uint32_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_STATE3);
+ }
+
+ tmp3 = tmp1 + (tmp2 << 8) + (tmp3 << 16);
+
+ return(tmp3 & IO_Pin);
+}
+
+/**
+ * @brief Enable the global IO interrupt source.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_IO_EnableIT(uint16_t DeviceAddr)
+{
+ MFX_IO_ITConfig();
+
+ /* Enable global IO IT source */
+ mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_GPIO);
+}
+
+/**
+ * @brief Disable the global IO interrupt source.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_IO_DisableIT(uint16_t DeviceAddr)
+{
+ /* Disable global IO IT source */
+ mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_GPIO);
+}
+
+/**
+ * @brief Enable interrupt mode for the selected IO pin(s).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO interrupt to be enabled. This parameter could be any
+ * combination of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+ * @retval None
+ */
+void mfxstm32l152_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_SRC1, IO_Pin, 1);
+}
+
+/**
+ * @brief Disable interrupt mode for the selected IO pin(s).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO interrupt to be disabled. This parameter could be any
+ * combination of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+ * @retval None
+ */
+void mfxstm32l152_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_SRC1, IO_Pin, 0);
+}
+
+
+/**
+ * @brief Check the status of the selected IO interrupt pending bit
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO interrupt to be checked could be:
+ * @arg MFXSTM32L152_GPIO_PIN_x Where x can be from 0 to 23.
+ * @retval Status of the checked IO pin(s).
+ */
+uint32_t mfxstm32l152_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ /* Get the Interrupt status */
+ uint8_t tmp1 = 0;
+ uint16_t tmp2 = 0;
+ uint32_t tmp3 = 0;
+
+ if(IO_Pin & 0xFF)
+ {
+ tmp1 = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING1);
+ }
+ if(IO_Pin & 0xFFFF00)
+ {
+ tmp2 = (uint16_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING2);
+ }
+ if(IO_Pin & 0xFFFF0000)
+ {
+ tmp3 = (uint32_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING3);
+ }
+
+ tmp3 = tmp1 + (tmp2 << 8) + (tmp3 << 16);
+
+ return(tmp3 & IO_Pin);
+}
+
+/**
+ * @brief Clear the selected IO interrupt pending bit(s). It clear automatically also the general MFXSTM32L152_REG_ADR_IRQ_PENDING
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: the IO interrupt to be cleared, could be:
+ * @arg MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23.
+ * @retval None
+ */
+void mfxstm32l152_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ /* Clear the IO IT pending bit(s) by acknowledging */
+ /* it cleans automatically also the Global IRQ_GPIO */
+ /* normally this function is called under interrupt */
+ uint8_t pin_0_7, pin_8_15, pin_16_23;
+
+ pin_0_7 = IO_Pin & 0x0000ff;
+ pin_8_15 = IO_Pin >> 8;
+ pin_8_15 = pin_8_15 & 0x00ff;
+ pin_16_23 = IO_Pin >> 16;
+
+ if (pin_0_7)
+ {
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_ACK1, pin_0_7);
+ }
+ if (pin_8_15)
+ {
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_ACK2, pin_8_15);
+ }
+ if (pin_16_23)
+ {
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_ACK3, pin_16_23);
+ }
+}
+
+
+/**
+ * @brief Enable the AF for aGPIO.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_IO_EnableAF(uint16_t DeviceAddr)
+{
+ uint8_t mode;
+
+ /* Get the current register value */
+ mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL);
+
+ /* Enable ALTERNATE functions */
+ /* AGPIO[0..3] can be either IDD or GPIO */
+ /* AGPIO[4..7] can be either TS or GPIO */
+ /* if IDD or TS are enabled no matter the value this bit GPIO are not available for those pins */
+ /* however the MFX will waste some cycles to to handle these potential GPIO (pooling, etc) */
+ /* so if IDD and TS are both active it is better to let ALTERNATE disabled (0) */
+ /* if however IDD or TS are not connected then set it on gives more GPIOs availability */
+ /* remind that AGPIO are less efficient then normal GPIO (they use pooling rather then EXTI) */
+ mode |= MFXSTM32L152_ALTERNATE_GPIO_EN;
+
+ /* Write the new register value */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode);
+}
+
+/**
+ * @brief Disable the AF for aGPIO.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+ void mfxstm32l152_IO_DisableAF(uint16_t DeviceAddr)
+{
+ uint8_t mode;
+
+ /* Get the current register value */
+ mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL);
+
+ /* Enable ALTERNATE functions */
+ /* AGPIO[0..3] can be either IDD or GPIO */
+ /* AGPIO[4..7] can be either TS or GPIO */
+ /* if IDD or TS are enabled no matter the value this bit GPIO are not available for those pins */
+ /* however the MFX will waste some cycles to to handle these potential GPIO (pooling, etc) */
+ /* so if IDD and TS are both active it is better to let ALTERNATE disabled (0) */
+ /* if however IDD or TS are not connected then set it on gives more GPIOs availability */
+ /* remind that AGPIO are less efficient then normal GPIO (they use pooling rather then EXTI) */
+ mode &= ~MFXSTM32L152_ALTERNATE_GPIO_EN;
+
+ /* Write the new register value */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode);
+
+}
+
+
+/* ------------------------------------------------------------------ */
+/* --------------------- TOUCH SCREEN ------------------------------- */
+/* ------------------------------------------------------------------ */
+
+/**
+ * @brief Configures the touch Screen Controller (Single point detection)
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None.
+ */
+void mfxstm32l152_TS_Start(uint16_t DeviceAddr)
+{
+ uint8_t mode;
+
+ /* Get the current register value */
+ mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL);
+
+ /* Set the Functionalities to be Enabled */
+ mode |= MFXSTM32L152_TS_EN;
+
+ /* Set the new register value */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode);
+
+ /* Wait for 2 ms */
+ rt_thread_delay(2);
+
+ /* Select 2 nF filter capacitor */
+ /* Configuration:
+ - Touch average control : 4 samples
+ - Touch delay time : 500 uS
+ - Panel driver setting time: 500 uS
+ */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_SETTLING, 0x32);
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_TOUCH_DET_DELAY, 0x5);
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_AVE, 0x04);
+
+ /* Configure the Touch FIFO threshold: single point reading */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_FIFO_TH, 0x01);
+
+ /* Clear the FIFO memory content. */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_FIFO_TH, MFXSTM32L152_TS_CLEAR_FIFO);
+
+ /* Touch screen control configuration :
+ - No window tracking index
+ */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_TRACK, 0x00);
+
+
+ /* Clear all the IT status pending bits if any */
+ mfxstm32l152_IO_ClearIT(DeviceAddr, 0xFFFFFF);
+
+ /* Wait for 1 ms delay */
+ rt_thread_delay(1);
+}
+
+/**
+ * @brief Return if there is touch detected or not.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Touch detected state.
+ */
+uint8_t mfxstm32l152_TS_DetectTouch(uint16_t DeviceAddr)
+{
+ uint8_t state;
+ uint8_t ret = 0;
+
+ state = MFX_IO_Read(DeviceAddr, MFXSTM32L152_TS_FIFO_STA);
+ state = ((state & (uint8_t)MFXSTM32L152_TS_CTRL_STATUS) == (uint8_t)MFXSTM32L152_TS_CTRL_STATUS);
+
+ if(state > 0)
+ {
+ if(MFX_IO_Read(DeviceAddr, MFXSTM32L152_TS_FIFO_LEVEL) > 0)
+ {
+ ret = 1;
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Get the touch screen X and Y positions values
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param X: Pointer to X position value
+ * @param Y: Pointer to Y position value
+ * @retval None.
+ */
+void mfxstm32l152_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y)
+{
+ uint8_t data_xy[3];
+
+ MFX_IO_ReadMultiple(DeviceAddr, MFXSTM32L152_TS_XY_DATA, data_xy, sizeof(data_xy)) ;
+
+ /* Calculate positions values */
+ *X = (data_xy[1]<<4) + (data_xy[0]>>4);
+ *Y = (data_xy[2]<<4) + (data_xy[0]&4);
+
+ /* Reset the FIFO memory content. */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_FIFO_TH, MFXSTM32L152_TS_CLEAR_FIFO);
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_TS_EnableIT(uint16_t DeviceAddr)
+{
+ MFX_IO_ITConfig();
+
+ /* Enable global TS IT source */
+ mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_TS_DET);
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_TS_DisableIT(uint16_t DeviceAddr)
+{
+ /* Disable global TS IT source */
+ mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_TS_DET);
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval TS interrupts status
+ */
+uint8_t mfxstm32l152_TS_ITStatus(uint16_t DeviceAddr)
+{
+ /* Return TS interrupts status */
+ return(mfxstm32l152_GlobalITStatus(DeviceAddr, MFXSTM32L152_IRQ_TS));
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_TS_ClearIT(uint16_t DeviceAddr)
+{
+ /* Clear the global TS IT source */
+ mfxstm32l152_ClearGlobalIT(DeviceAddr, MFXSTM32L152_IRQ_TS);
+}
+
+/* ------------------------------------------------------------------ */
+/* --------------------- IDD MEASUREMENT ---------------------------- */
+/* ------------------------------------------------------------------ */
+
+/**
+ * @brief Launch IDD current measurement
+ * @param DeviceAddr: Device address on communication Bus
+ * @retval None.
+ */
+void mfxstm32l152_IDD_Start(uint16_t DeviceAddr)
+{
+ uint8_t mode = 0;
+
+ /* Get the current register value */
+ mode = MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL);
+
+ /* Set the Functionalities to be enabled */
+ mode |= MFXSTM32L152_IDD_CTRL_REQ;
+
+ /* Start measurement campaign */
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL, mode);
+}
+
+/**
+ * @brief Configures the IDD current measurement
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param MfxIddConfig: Parameters depending on hardware config.
+ * @retval None
+ */
+void mfxstm32l152_IDD_Config(uint16_t DeviceAddr, IDD_ConfigTypeDef MfxIddConfig)
+{
+ uint8_t value = 0;
+ uint8_t mode = 0;
+
+ /* Get the current register value */
+ mode = MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL);
+
+ if((mode & MFXSTM32L152_IDD_EN) != MFXSTM32L152_IDD_EN)
+ {
+ /* Set the Functionalities to be enabled */
+ mode |= MFXSTM32L152_IDD_EN;
+
+ /* Set the new register value */
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode);
+ }
+
+ /* Control register setting: number of shunts */
+ value = ((MfxIddConfig.ShuntNbUsed << 1) & MFXSTM32L152_IDD_CTRL_SHUNT_NB);
+ value |= (MfxIddConfig.VrefMeasurement & MFXSTM32L152_IDD_CTRL_VREF_DIS);
+ value |= (MfxIddConfig.Calibration & MFXSTM32L152_IDD_CTRL_CAL_DIS);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL, value);
+
+ /* Idd pre delay configuration: unit and value*/
+ value = (MfxIddConfig.PreDelayUnit & MFXSTM32L152_IDD_PREDELAY_UNIT) |
+ (MfxIddConfig.PreDelayValue & MFXSTM32L152_IDD_PREDELAY_VALUE);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_PRE_DELAY, value);
+
+ /* Shunt 0 register value: MSB then LSB */
+ value = (uint8_t) (MfxIddConfig.Shunt0Value >> 8);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT0_MSB, value);
+ value = (uint8_t) (MfxIddConfig.Shunt0Value);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT0_LSB, value);
+
+ /* Shunt 1 register value: MSB then LSB */
+ value = (uint8_t) (MfxIddConfig.Shunt1Value >> 8);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT1_MSB, value);
+ value = (uint8_t) (MfxIddConfig.Shunt1Value);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT1_LSB, value);
+
+ /* Shunt 2 register value: MSB then LSB */
+ value = (uint8_t) (MfxIddConfig.Shunt2Value >> 8);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT2_MSB, value);
+ value = (uint8_t) (MfxIddConfig.Shunt2Value);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT2_LSB, value);
+
+ /* Shunt 3 register value: MSB then LSB */
+ value = (uint8_t) (MfxIddConfig.Shunt3Value >> 8);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT3_MSB, value);
+ value = (uint8_t) (MfxIddConfig.Shunt3Value);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT3_LSB, value);
+
+ /* Shunt 4 register value: MSB then LSB */
+ value = (uint8_t) (MfxIddConfig.Shunt4Value >> 8);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT4_MSB, value);
+ value = (uint8_t) (MfxIddConfig.Shunt4Value);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT4_LSB, value);
+
+ /* Shunt 0 stabilization delay */
+ value = MfxIddConfig.Shunt0StabDelay;
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH0_STABILIZATION, value);
+
+ /* Shunt 1 stabilization delay */
+ value = MfxIddConfig.Shunt1StabDelay;
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH1_STABILIZATION, value);
+
+ /* Shunt 2 stabilization delay */
+ value = MfxIddConfig.Shunt2StabDelay;
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH2_STABILIZATION, value);
+
+ /* Shunt 3 stabilization delay */
+ value = MfxIddConfig.Shunt3StabDelay;
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH3_STABILIZATION, value);
+
+ /* Shunt 4 stabilization delay */
+ value = MfxIddConfig.Shunt4StabDelay;
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH4_STABILIZATION, value);
+
+ /* Idd ampli gain value: MSB then LSB */
+ value = (uint8_t) (MfxIddConfig.AmpliGain >> 8);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_GAIN_MSB, value);
+ value = (uint8_t) (MfxIddConfig.AmpliGain);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_GAIN_LSB, value);
+
+ /* Idd VDD min value: MSB then LSB */
+ value = (uint8_t) (MfxIddConfig.VddMin >> 8);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_VDD_MIN_MSB, value);
+ value = (uint8_t) (MfxIddConfig.VddMin);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_VDD_MIN_LSB, value);
+
+ /* Idd number of measurements */
+ value = MfxIddConfig.MeasureNb;
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_NBR_OF_MEAS, value);
+
+ /* Idd delta delay configuration: unit and value */
+ value = (MfxIddConfig.DeltaDelayUnit & MFXSTM32L152_IDD_DELTADELAY_UNIT) |
+ (MfxIddConfig.DeltaDelayValue & MFXSTM32L152_IDD_DELTADELAY_VALUE);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_MEAS_DELTA_DELAY, value);
+
+ /* Idd number of shut on board */
+ value = MfxIddConfig.ShuntNbOnBoard;
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNTS_ON_BOARD, value);
+}
+
+/**
+ * @brief This function allows to modify number of shunt used for a measurement
+ * @param DeviceAddr: Device address on communication Bus
+ * @retval None.
+ */
+void mfxstm32l152_IDD_ConfigShuntNbLimit(uint16_t DeviceAddr, uint8_t ShuntNbLimit)
+{
+ uint8_t mode = 0;
+
+ /* Get the current register value */
+ mode = MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL);
+
+ /* Clear number of shunt limit */
+ mode &= ~(MFXSTM32L152_IDD_CTRL_SHUNT_NB);
+
+ /* Clear number of shunt limit */
+ mode |= ((ShuntNbLimit << 1) & MFXSTM32L152_IDD_CTRL_SHUNT_NB);
+
+ /* Write noewx desired limit */
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL, mode);
+}
+
+/**
+ * @brief Get Idd current value
+ * @param DeviceAddr: Device address on communication Bus
+ * @param ReadValue: Pointer on value to be read
+ * @retval Idd value in 10 nA.
+ */
+void mfxstm32l152_IDD_GetValue(uint16_t DeviceAddr, uint32_t *ReadValue)
+{
+ uint8_t data[3];
+
+ MFX_IO_ReadMultiple((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_VALUE_MSB, data, sizeof(data)) ;
+
+ /* Recompose Idd current value */
+ *ReadValue = (data[0] << 16) | (data[1] << 8) | data[2];
+
+}
+
+/**
+ * @brief Get Last shunt used for measurement
+ * @param DeviceAddr: Device address on communication Bus
+ * @retval Last shunt used
+ */
+uint8_t mfxstm32l152_IDD_GetShuntUsed(uint16_t DeviceAddr)
+{
+ return(MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT_USED));
+}
+
+/**
+ * @brief Configure mfx to enable Idd interrupt
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_IDD_EnableIT(uint16_t DeviceAddr)
+{
+ MFX_IO_ITConfig();
+
+ /* Enable global IDD interrupt source */
+ mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_IDD);
+}
+
+/**
+ * @brief Clear Idd global interrupt
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_IDD_ClearIT(uint16_t DeviceAddr)
+{
+ /* Clear the global IDD interrupt source */
+ mfxstm32l152_ClearGlobalIT(DeviceAddr, MFXSTM32L152_IRQ_IDD);
+}
+
+/**
+ * @brief get Idd interrupt status
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval IDD interrupts status
+ */
+uint8_t mfxstm32l152_IDD_GetITStatus(uint16_t DeviceAddr)
+{
+ /* Return IDD interrupt status */
+ return(mfxstm32l152_GlobalITStatus(DeviceAddr, MFXSTM32L152_IRQ_IDD));
+}
+
+/**
+ * @brief disable Idd interrupt
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None.
+ */
+void mfxstm32l152_IDD_DisableIT(uint16_t DeviceAddr)
+{
+ /* Disable global IDD interrupt source */
+ mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_IDD);
+}
+
+
+/* ------------------------------------------------------------------ */
+/* --------------------- ERROR MANAGEMENT --------------------------- */
+/* ------------------------------------------------------------------ */
+
+/**
+ * @brief Read Error Source.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Error message code with error source
+ */
+uint8_t mfxstm32l152_Error_ReadSrc(uint16_t DeviceAddr)
+{
+ /* Get the current source register value */
+ return(MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_ERROR_SRC));
+}
+
+/**
+ * @brief Read Error Message
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Error message code with error source
+ */
+uint8_t mfxstm32l152_Error_ReadMsg(uint16_t DeviceAddr)
+{
+ /* Get the current message register value */
+ return(MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_ERROR_MSG));
+}
+
+/**
+ * @brief Enable Error global interrupt
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+
+void mfxstm32l152_Error_EnableIT(uint16_t DeviceAddr)
+{
+ MFX_IO_ITConfig();
+
+ /* Enable global Error interrupt source */
+ mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_ERROR);
+}
+
+/**
+ * @brief Clear Error global interrupt
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_Error_ClearIT(uint16_t DeviceAddr)
+{
+ /* Clear the global Error interrupt source */
+ mfxstm32l152_ClearGlobalIT(DeviceAddr, MFXSTM32L152_IRQ_ERROR);
+}
+
+/**
+ * @brief get Error interrupt status
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Error interrupts status
+ */
+uint8_t mfxstm32l152_Error_GetITStatus(uint16_t DeviceAddr)
+{
+ /* Return Error interrupt status */
+ return(mfxstm32l152_GlobalITStatus(DeviceAddr, MFXSTM32L152_IRQ_ERROR));
+}
+
+/**
+ * @brief disable Error interrupt
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None.
+ */
+void mfxstm32l152_Error_DisableIT(uint16_t DeviceAddr)
+{
+ /* Disable global Error interrupt source */
+ mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_ERROR);
+}
+
+/**
+ * @brief FOR DEBUG ONLY
+ */
+uint8_t mfxstm32l152_ReadReg(uint16_t DeviceAddr, uint8_t RegAddr)
+{
+ /* Get the current register value */
+ return(MFX_IO_Read((uint8_t) DeviceAddr, RegAddr));
+}
+
+void mfxstm32l152_WriteReg(uint16_t DeviceAddr, uint8_t RegAddr, uint8_t Value)
+{
+ /* set the current register value */
+ MFX_IO_Write((uint8_t) DeviceAddr, RegAddr, Value);
+}
+
+/* ------------------------------------------------------------------ */
+/* ----------------------- Private functions ------------------------ */
+/* ------------------------------------------------------------------ */
+/**
+ * @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 mfxstm32l152_GetInstance(uint16_t DeviceAddr)
+{
+ uint8_t idx = 0;
+
+ /* Check all the registered instances */
+ for(idx = 0; idx < MFXSTM32L152_MAX_INSTANCE ; idx ++)
+ {
+ if(mfxstm32l152[idx] == DeviceAddr)
+ {
+ return idx;
+ }
+ }
+
+ return 0xFF;
+}
+
+/**
+ * @brief Release registered device instance
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Index of released device instance, 0xFF if not.
+ */
+static uint8_t mfxstm32l152_ReleaseInstance(uint16_t DeviceAddr)
+{
+ uint8_t idx = 0;
+
+ /* Check for all the registered instances */
+ for(idx = 0; idx < MFXSTM32L152_MAX_INSTANCE ; idx ++)
+ {
+ if(mfxstm32l152[idx] == DeviceAddr)
+ {
+ mfxstm32l152[idx] = 0;
+ return idx;
+ }
+ }
+ return 0xFF;
+}
+
+/**
+ * @brief Internal routine
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param RegisterAddr: Register Address
+ * @param PinPosition: Pin [0:23]
+ * @param PinValue: 0/1
+ * @retval None
+ */
+void mfxstm32l152_reg24_setPinValue(uint16_t DeviceAddr, uint8_t RegisterAddr, uint32_t PinPosition, uint8_t PinValue )
+{
+ uint8_t tmp = 0;
+ uint8_t pin_0_7, pin_8_15, pin_16_23;
+
+ pin_0_7 = PinPosition & 0x0000ff;
+ pin_8_15 = PinPosition >> 8;
+ pin_8_15 = pin_8_15 & 0x00ff;
+ pin_16_23 = PinPosition >> 16;
+
+ if (pin_0_7)
+ {
+ /* Get the current register value */
+ tmp = MFX_IO_Read(DeviceAddr, RegisterAddr);
+
+ /* Set the selected pin direction */
+ if (PinValue != 0)
+ {
+ tmp |= (uint8_t)pin_0_7;
+ }
+ else
+ {
+ tmp &= ~(uint8_t)pin_0_7;
+ }
+
+ /* Set the new register value */
+ MFX_IO_Write(DeviceAddr, RegisterAddr, tmp);
+ }
+
+ if (pin_8_15)
+ {
+ /* Get the current register value */
+ tmp = MFX_IO_Read(DeviceAddr, RegisterAddr+1);
+
+ /* Set the selected pin direction */
+ if (PinValue != 0)
+ {
+ tmp |= (uint8_t)pin_8_15;
+ }
+ else
+ {
+ tmp &= ~(uint8_t)pin_8_15;
+ }
+
+ /* Set the new register value */
+ MFX_IO_Write(DeviceAddr, RegisterAddr+1, tmp);
+ }
+
+ if (pin_16_23)
+ {
+ /* Get the current register value */
+ tmp = MFX_IO_Read(DeviceAddr, RegisterAddr+2);
+
+ /* Set the selected pin direction */
+ if (PinValue != 0)
+ {
+ tmp |= (uint8_t)pin_16_23;
+ }
+ else
+ {
+ tmp &= ~(uint8_t)pin_16_23;
+ }
+
+ /* Set the new register value */
+ MFX_IO_Write(DeviceAddr, RegisterAddr+2, tmp);
+ }
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.h
new file mode 100644
index 0000000000..38ca8a6f6a
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.h
@@ -0,0 +1,853 @@
+/**
+ ******************************************************************************
+ * @file mfxstm32l152.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for the
+ * mfxstm32l152.c IO expander driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; 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 __MFXSTM32L152_H
+#define __MFXSTM32L152_H
+
+#include "board.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Component
+ * @{
+ */
+
+/** @defgroup MFXSTM32L152
+ * @{
+ */
+
+ /**
+ * @brief GPIO: IO Pins definition
+ */
+#define MFXSTM32L152_GPIO_PIN_0 ((uint32_t)0x0001)
+#define MFXSTM32L152_GPIO_PIN_1 ((uint32_t)0x0002)
+#define MFXSTM32L152_GPIO_PIN_2 ((uint32_t)0x0004)
+#define MFXSTM32L152_GPIO_PIN_3 ((uint32_t)0x0008)
+#define MFXSTM32L152_GPIO_PIN_4 ((uint32_t)0x0010)
+#define MFXSTM32L152_GPIO_PIN_5 ((uint32_t)0x0020)
+#define MFXSTM32L152_GPIO_PIN_6 ((uint32_t)0x0040)
+#define MFXSTM32L152_GPIO_PIN_7 ((uint32_t)0x0080)
+
+#define MFXSTM32L152_GPIO_PIN_8 ((uint32_t)0x0100)
+#define MFXSTM32L152_GPIO_PIN_9 ((uint32_t)0x0200)
+#define MFXSTM32L152_GPIO_PIN_10 ((uint32_t)0x0400)
+#define MFXSTM32L152_GPIO_PIN_11 ((uint32_t)0x0800)
+#define MFXSTM32L152_GPIO_PIN_12 ((uint32_t)0x1000)
+#define MFXSTM32L152_GPIO_PIN_13 ((uint32_t)0x2000)
+#define MFXSTM32L152_GPIO_PIN_14 ((uint32_t)0x4000)
+#define MFXSTM32L152_GPIO_PIN_15 ((uint32_t)0x8000)
+
+#define MFXSTM32L152_GPIO_PIN_16 ((uint32_t)0x010000)
+#define MFXSTM32L152_GPIO_PIN_17 ((uint32_t)0x020000)
+#define MFXSTM32L152_GPIO_PIN_18 ((uint32_t)0x040000)
+#define MFXSTM32L152_GPIO_PIN_19 ((uint32_t)0x080000)
+#define MFXSTM32L152_GPIO_PIN_20 ((uint32_t)0x100000)
+#define MFXSTM32L152_GPIO_PIN_21 ((uint32_t)0x200000)
+#define MFXSTM32L152_GPIO_PIN_22 ((uint32_t)0x400000)
+#define MFXSTM32L152_GPIO_PIN_23 ((uint32_t)0x800000)
+
+#define MFXSTM32L152_AGPIO_PIN_0 MFXSTM32L152_GPIO_PIN_16
+#define MFXSTM32L152_AGPIO_PIN_1 MFXSTM32L152_GPIO_PIN_17
+#define MFXSTM32L152_AGPIO_PIN_2 MFXSTM32L152_GPIO_PIN_18
+#define MFXSTM32L152_AGPIO_PIN_3 MFXSTM32L152_GPIO_PIN_19
+#define MFXSTM32L152_AGPIO_PIN_4 MFXSTM32L152_GPIO_PIN_20
+#define MFXSTM32L152_AGPIO_PIN_5 MFXSTM32L152_GPIO_PIN_21
+#define MFXSTM32L152_AGPIO_PIN_6 MFXSTM32L152_GPIO_PIN_22
+#define MFXSTM32L152_AGPIO_PIN_7 MFXSTM32L152_GPIO_PIN_23
+
+#define MFXSTM32L152_GPIO_PINS_ALL ((uint32_t)0xFFFFFF)
+#define IO_PIN_ALL MFXSTM32L152_GPIO_PINS_ALL
+/**
+ * @brief IO Bit SET and Bit RESET enumeration
+ */
+typedef enum
+{
+ IO_PIN_RESET = 0,
+ IO_PIN_SET
+}IO_PinState;
+
+typedef enum
+{
+ IO_MODE_INPUT = 0, /* input floating */
+ IO_MODE_OUTPUT, /* output Push Pull */
+ IO_MODE_IT_RISING_EDGE, /* float input - irq detect on rising edge */
+ IO_MODE_IT_FALLING_EDGE, /* float input - irq detect on falling edge */
+ IO_MODE_IT_LOW_LEVEL, /* float input - irq detect on low level */
+ IO_MODE_IT_HIGH_LEVEL, /* float input - irq detect on high level */
+ /* following modes only available on MFX*/
+ IO_MODE_ANALOG, /* analog mode */
+ IO_MODE_OFF, /* when pin isn't used*/
+ IO_MODE_INPUT_PU, /* input with internal pull up resistor */
+ IO_MODE_INPUT_PD, /* input with internal pull down resistor */
+ IO_MODE_OUTPUT_OD, /* Open Drain output without internal resistor */
+ IO_MODE_OUTPUT_OD_PU, /* Open Drain output with internal pullup resistor */
+ IO_MODE_OUTPUT_OD_PD, /* Open Drain output with internal pulldown resistor */
+ IO_MODE_OUTPUT_PP, /* PushPull output without internal resistor */
+ IO_MODE_OUTPUT_PP_PU, /* PushPull output with internal pullup resistor */
+ IO_MODE_OUTPUT_PP_PD, /* PushPull output with internal pulldown resistor */
+ IO_MODE_IT_RISING_EDGE_PU, /* push up resistor input - irq on rising edge */
+ IO_MODE_IT_RISING_EDGE_PD, /* push dw resistor input - irq on rising edge */
+ IO_MODE_IT_FALLING_EDGE_PU, /* push up resistor input - irq on falling edge */
+ IO_MODE_IT_FALLING_EDGE_PD, /* push dw resistor input - irq on falling edge */
+ IO_MODE_IT_LOW_LEVEL_PU, /* push up resistor input - irq detect on low level */
+ IO_MODE_IT_LOW_LEVEL_PD, /* push dw resistor input - irq detect on low level */
+ IO_MODE_IT_HIGH_LEVEL_PU, /* push up resistor input - irq detect on high level */
+ IO_MODE_IT_HIGH_LEVEL_PD, /* push dw resistor input - irq detect on high level */
+
+}IO_ModeTypedef;
+
+/** @defgroup IO_Driver_structure IO Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(uint16_t);
+ uint16_t (*ReadID)(uint16_t);
+ void (*Reset)(uint16_t);
+
+ void (*Start)(uint16_t, uint32_t);
+ uint8_t (*Config)(uint16_t, uint32_t, IO_ModeTypedef);
+ void (*WritePin)(uint16_t, uint32_t, uint8_t);
+ uint32_t (*ReadPin)(uint16_t, uint32_t);
+
+ void (*EnableIT)(uint16_t);
+ void (*DisableIT)(uint16_t);
+ uint32_t (*ITStatus)(uint16_t, uint32_t);
+ void (*ClearIT)(uint16_t, uint32_t);
+
+}IO_DrvTypeDef;
+
+typedef struct
+{
+ uint16_t AmpliGain; /*!< Specifies ampli gain value
+ */
+ uint16_t VddMin; /*!< Specifies minimum MCU VDD can reach to protect MCU from reset
+ */
+ uint16_t Shunt0Value; /*!< Specifies value of Shunt 0 if existing
+ */
+ uint16_t Shunt1Value; /*!< Specifies value of Shunt 1 if existing
+ */
+ uint16_t Shunt2Value; /*!< Specifies value of Shunt 2 if existing
+ */
+ uint16_t Shunt3Value; /*!< Specifies value of Shunt 3 if existing
+ */
+ uint16_t Shunt4Value; /*!< Specifies value of Shunt 4 if existing
+ */
+ uint16_t Shunt0StabDelay; /*!< Specifies delay of Shunt 0 stabilization if existing
+ */
+ uint16_t Shunt1StabDelay; /*!< Specifies delay of Shunt 1 stabilization if existing
+ */
+ uint16_t Shunt2StabDelay; /*!< Specifies delay of Shunt 2 stabilization if existing
+ */
+ uint16_t Shunt3StabDelay; /*!< Specifies delay of Shunt 3 stabilization if existing
+ */
+ uint16_t Shunt4StabDelay; /*!< Specifies delay of Shunt 4 stabilization if existing
+ */
+ uint8_t ShuntNbOnBoard; /*!< Specifies number of shunts that are present on board
+ This parameter can be a value of @ref IDD_shunt_number */
+ uint8_t ShuntNbUsed; /*!< Specifies number of shunts used for measurement
+ This parameter can be a value of @ref IDD_shunt_number */
+ uint8_t VrefMeasurement; /*!< Specifies if Vref is automatically measured before each Idd measurement
+ This parameter can be a value of @ref IDD_Vref_Measurement */
+ uint8_t Calibration; /*!< Specifies if calibration is done before each Idd measurement
+ */
+ uint8_t PreDelayUnit; /*!< Specifies Pre delay unit
+ This parameter can be a value of @ref IDD_PreDelay */
+ uint8_t PreDelayValue; /*!< Specifies Pre delay value in selected unit
+ */
+ uint8_t MeasureNb; /*!< Specifies number of Measure to be performed
+ This parameter can be a value between 1 and 256 */
+ uint8_t DeltaDelayUnit; /*!< Specifies Delta delay unit
+ This parameter can be a value of @ref IDD_DeltaDelay */
+ uint8_t DeltaDelayValue; /*!< Specifies Delta delay between 2 measures
+ value can be between 1 and 128 */
+}IDD_ConfigTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup IDD_Driver_structure IDD Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(uint16_t);
+ void (*DeInit)(uint16_t);
+ uint16_t (*ReadID)(uint16_t);
+ void (*Reset)(uint16_t);
+ void (*LowPower)(uint16_t);
+ void (*WakeUp)(uint16_t);
+ void (*Start)(uint16_t);
+ void (*Config)(uint16_t,IDD_ConfigTypeDef);
+ void (*GetValue)(uint16_t, uint32_t *);
+ void (*EnableIT)(uint16_t);
+ void (*ClearIT)(uint16_t);
+ uint8_t (*GetITStatus)(uint16_t);
+ void (*DisableIT)(uint16_t);
+ void (*ErrorEnableIT)(uint16_t);
+ void (*ErrorClearIT)(uint16_t);
+ uint8_t (*ErrorGetITStatus)(uint16_t);
+ void (*ErrorDisableIT)(uint16_t);
+ uint8_t (*ErrorGetSrc)(uint16_t);
+ uint8_t (*ErrorGetCode)(uint16_t);
+}IDD_DrvTypeDef;
+
+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;
+
+/* Exported types ------------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Exported_Types
+ * @{
+ */
+typedef struct
+{
+ uint8_t SYS_CTRL;
+ uint8_t ERROR_SRC;
+ uint8_t ERROR_MSG;
+ uint8_t IRQ_OUT;
+ uint8_t IRQ_SRC_EN;
+ uint8_t IRQ_PENDING;
+ uint8_t IDD_CTRL;
+ uint8_t IDD_PRE_DELAY;
+ uint8_t IDD_SHUNT0_MSB;
+ uint8_t IDD_SHUNT0_LSB;
+ uint8_t IDD_SHUNT1_MSB;
+ uint8_t IDD_SHUNT1_LSB;
+ uint8_t IDD_SHUNT2_MSB;
+ uint8_t IDD_SHUNT2_LSB;
+ uint8_t IDD_SHUNT3_MSB;
+ uint8_t IDD_SHUNT3_LSB;
+ uint8_t IDD_SHUNT4_MSB;
+ uint8_t IDD_SHUNT4_LSB;
+ uint8_t IDD_GAIN_MSB;
+ uint8_t IDD_GAIN_LSB;
+ uint8_t IDD_VDD_MIN_MSB;
+ uint8_t IDD_VDD_MIN_LSB;
+ uint8_t IDD_VALUE_MSB;
+ uint8_t IDD_VALUE_MID;
+ uint8_t IDD_VALUE_LSB;
+ uint8_t IDD_CAL_OFFSET_MSB;
+ uint8_t IDD_CAL_OFFSET_LSB;
+ uint8_t IDD_SHUNT_USED;
+}IDD_dbgTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Exported_Constants
+ * @{
+ */
+
+ /**
+ * @brief MFX COMMON defines
+ */
+
+ /**
+ * @brief Register address: chip IDs (R)
+ */
+#define MFXSTM32L152_REG_ADR_ID ((uint8_t)0x00)
+ /**
+ * @brief Register address: chip FW_VERSION (R)
+ */
+#define MFXSTM32L152_REG_ADR_FW_VERSION_MSB ((uint8_t)0x01)
+#define MFXSTM32L152_REG_ADR_FW_VERSION_LSB ((uint8_t)0x00)
+ /**
+ * @brief Register address: System Control Register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_SYS_CTRL ((uint8_t)0x40)
+ /**
+ * @brief Register address: Vdd monitoring (R)
+ */
+#define MFXSTM32L152_REG_ADR_VDD_REF_MSB ((uint8_t)0x06)
+#define MFXSTM32L152_REG_ADR_VDD_REF_LSB ((uint8_t)0x07)
+ /**
+ * @brief Register address: Error source
+ */
+#define MFXSTM32L152_REG_ADR_ERROR_SRC ((uint8_t)0x03)
+ /**
+ * @brief Register address: Error Message
+ */
+#define MFXSTM32L152_REG_ADR_ERROR_MSG ((uint8_t)0x04)
+
+ /**
+ * @brief Reg Addr IRQs: to config the pin that informs Main MCU that MFX events appear
+ */
+#define MFXSTM32L152_REG_ADR_MFX_IRQ_OUT ((uint8_t)0x41)
+ /**
+ * @brief Reg Addr IRQs: to select the events which activate the MFXSTM32L152_IRQ_OUT signal
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_SRC_EN ((uint8_t)0x42)
+ /**
+ * @brief Reg Addr IRQs: the Main MCU must read the IRQ_PENDING register to know the interrupt reason
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_PENDING ((uint8_t)0x08)
+ /**
+ * @brief Reg Addr IRQs: the Main MCU must acknowledge it thanks to a writing access to the IRQ_ACK register
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_ACK ((uint8_t)0x44)
+
+ /**
+ * @brief MFXSTM32L152_REG_ADR_ID choices
+ */
+#define MFXSTM32L152_ID_1 ((uint8_t)0x7B)
+#define MFXSTM32L152_ID_2 ((uint8_t)0x79)
+
+ /**
+ * @brief MFXSTM32L152_REG_ADR_SYS_CTRL choices
+ */
+#define MFXSTM32L152_SWRST ((uint8_t)0x80)
+#define MFXSTM32L152_STANDBY ((uint8_t)0x40)
+#define MFXSTM32L152_ALTERNATE_GPIO_EN ((uint8_t)0x08) /* by the way if IDD and TS are enabled they take automatically the AF pins*/
+#define MFXSTM32L152_IDD_EN ((uint8_t)0x04)
+#define MFXSTM32L152_TS_EN ((uint8_t)0x02)
+#define MFXSTM32L152_GPIO_EN ((uint8_t)0x01)
+
+ /**
+ * @brief MFXSTM32L152_REG_ADR_ERROR_SRC choices
+ */
+#define MFXSTM32L152_IDD_ERROR_SRC ((uint8_t)0x04) /* Error raised by Idd */
+#define MFXSTM32L152_TS_ERROR_SRC ((uint8_t)0x02) /* Error raised by Touch Screen */
+#define MFXSTM32L152_GPIO_ERROR_SRC ((uint8_t)0x01) /* Error raised by Gpio */
+
+ /**
+ * @brief MFXSTM32L152_REG_ADR_MFX_IRQ_OUT choices
+ */
+#define MFXSTM32L152_OUT_PIN_TYPE_OPENDRAIN ((uint8_t)0x00)
+#define MFXSTM32L152_OUT_PIN_TYPE_PUSHPULL ((uint8_t)0x01)
+#define MFXSTM32L152_OUT_PIN_POLARITY_LOW ((uint8_t)0x00)
+#define MFXSTM32L152_OUT_PIN_POLARITY_HIGH ((uint8_t)0x02)
+
+ /**
+ * @brief REG_ADR_IRQ_SRC_EN, REG_ADR_IRQ_PENDING & REG_ADR_IRQ_ACK choices
+ */
+#define MFXSTM32L152_IRQ_TS_OVF ((uint8_t)0x80) /* TouchScreen FIFO Overflow irq*/
+#define MFXSTM32L152_IRQ_TS_FULL ((uint8_t)0x40) /* TouchScreen FIFO Full irq*/
+#define MFXSTM32L152_IRQ_TS_TH ((uint8_t)0x20) /* TouchScreen FIFO threshold triggered irq*/
+#define MFXSTM32L152_IRQ_TS_NE ((uint8_t)0x10) /* TouchScreen FIFO Not Empty irq*/
+#define MFXSTM32L152_IRQ_TS_DET ((uint8_t)0x08) /* TouchScreen Detect irq*/
+#define MFXSTM32L152_IRQ_ERROR ((uint8_t)0x04) /* Error message from MFXSTM32L152 firmware irq */
+#define MFXSTM32L152_IRQ_IDD ((uint8_t)0x02) /* IDD function irq */
+#define MFXSTM32L152_IRQ_GPIO ((uint8_t)0x01) /* General GPIO irq (only for SRC_EN and PENDING) */
+#define MFXSTM32L152_IRQ_ALL ((uint8_t)0xFF) /* All global interrupts */
+#define MFXSTM32L152_IRQ_TS (MFXSTM32L152_IRQ_TS_DET | MFXSTM32L152_IRQ_TS_NE | MFXSTM32L152_IRQ_TS_TH | MFXSTM32L152_IRQ_TS_FULL | MFXSTM32L152_IRQ_TS_OVF )
+
+
+ /**
+ * @brief GPIO: 24 programmable input/output called MFXSTM32L152_GPIO[23:0] are provided
+ */
+
+ /**
+ * @brief Reg addr: GPIO DIRECTION (R/W): GPIO pins direction: (0) input, (1) output.
+ */
+#define MFXSTM32L152_REG_ADR_GPIO_DIR1 ((uint8_t)0x60) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPIO_DIR2 ((uint8_t)0x61) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPIO_DIR3 ((uint8_t)0x62) /* agpio [0:7] */
+ /**
+ * @brief Reg addr: GPIO TYPE (R/W): If GPIO in output: (0) output push pull, (1) output open drain.
+ * If GPIO in input: (0) input without pull resistor, (1) input with pull resistor.
+ */
+#define MFXSTM32L152_REG_ADR_GPIO_TYPE1 ((uint8_t)0x64) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPIO_TYPE2 ((uint8_t)0x65) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPIO_TYPE3 ((uint8_t)0x66) /* agpio [0:7] */
+ /**
+ * @brief Reg addr: GPIO PULL_UP_PULL_DOWN (R/W): discussion open with Jean Claude
+ */
+#define MFXSTM32L152_REG_ADR_GPIO_PUPD1 ((uint8_t)0x68) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPIO_PUPD2 ((uint8_t)0x69) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPIO_PUPD3 ((uint8_t)0x6A) /* agpio [0:7] */
+ /**
+ * @brief Reg addr: GPIO SET (W): When GPIO is in output mode, write (1) puts the corresponding GPO in High level.
+ */
+#define MFXSTM32L152_REG_ADR_GPO_SET1 ((uint8_t)0x6C) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPO_SET2 ((uint8_t)0x6D) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPO_SET3 ((uint8_t)0x6E) /* agpio [0:7] */
+ /**
+ * @brief Reg addr: GPIO CLEAR (W): When GPIO is in output mode, write (1) puts the corresponding GPO in Low level.
+ */
+#define MFXSTM32L152_REG_ADR_GPO_CLR1 ((uint8_t)0x70) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPO_CLR2 ((uint8_t)0x71) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPO_CLR3 ((uint8_t)0x72) /* agpio [0:7] */
+ /**
+ * @brief Reg addr: GPIO STATE (R): Give state of the GPIO pin.
+ */
+#define MFXSTM32L152_REG_ADR_GPIO_STATE1 ((uint8_t)0x10) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPIO_STATE2 ((uint8_t)0x11) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPIO_STATE3 ((uint8_t)0x12) /* agpio [0:7] */
+
+ /**
+ * @brief GPIO IRQ_GPIs
+ */
+/* GPIOs can INDIVIDUALLY generate interruption to the Main MCU thanks to the MFXSTM32L152_IRQ_OUT signal */
+/* the general MFXSTM32L152_IRQ_GPIO_SRC_EN shall be enabled too */
+ /**
+ * @brief GPIO IRQ_GPI_SRC1/2/3 (R/W): registers enable or not the feature to generate irq
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_SRC1 ((uint8_t)0x48) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_SRC2 ((uint8_t)0x49) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_SRC3 ((uint8_t)0x4A) /* agpio [0:7] */
+ /**
+ * @brief GPIO IRQ_GPI_EVT1/2/3 (R/W): Irq generated on level (0) or edge (1).
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_EVT1 ((uint8_t)0x4C) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_EVT2 ((uint8_t)0x4D) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_EVT3 ((uint8_t)0x4E) /* agpio [0:7] */
+ /**
+ * @brief GPIO IRQ_GPI_TYPE1/2/3 (R/W): Irq generated on (0) : Low level or Falling edge. (1) : High level or Rising edge.
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE1 ((uint8_t)0x50) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE2 ((uint8_t)0x51) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE3 ((uint8_t)0x52) /* agpio [0:7] */
+ /**
+ * @brief GPIO IRQ_GPI_PENDING1/2/3 (R): irq occurs
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING1 ((uint8_t)0x0C) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING2 ((uint8_t)0x0D) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING3 ((uint8_t)0x0E) /* agpio [0:7] */
+ /**
+ * @brief GPIO IRQ_GPI_ACK1/2/3 (W): Write (1) to acknowledge IRQ event
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_ACK1 ((uint8_t)0x54) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_ACK2 ((uint8_t)0x55) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_ACK3 ((uint8_t)0x56) /* agpio [0:7] */
+
+
+ /**
+ * @brief GPIO: IO Pins definition
+ */
+#define MFXSTM32L152_GPIO_PIN_0 ((uint32_t)0x0001)
+#define MFXSTM32L152_GPIO_PIN_1 ((uint32_t)0x0002)
+#define MFXSTM32L152_GPIO_PIN_2 ((uint32_t)0x0004)
+#define MFXSTM32L152_GPIO_PIN_3 ((uint32_t)0x0008)
+#define MFXSTM32L152_GPIO_PIN_4 ((uint32_t)0x0010)
+#define MFXSTM32L152_GPIO_PIN_5 ((uint32_t)0x0020)
+#define MFXSTM32L152_GPIO_PIN_6 ((uint32_t)0x0040)
+#define MFXSTM32L152_GPIO_PIN_7 ((uint32_t)0x0080)
+
+#define MFXSTM32L152_GPIO_PIN_8 ((uint32_t)0x0100)
+#define MFXSTM32L152_GPIO_PIN_9 ((uint32_t)0x0200)
+#define MFXSTM32L152_GPIO_PIN_10 ((uint32_t)0x0400)
+#define MFXSTM32L152_GPIO_PIN_11 ((uint32_t)0x0800)
+#define MFXSTM32L152_GPIO_PIN_12 ((uint32_t)0x1000)
+#define MFXSTM32L152_GPIO_PIN_13 ((uint32_t)0x2000)
+#define MFXSTM32L152_GPIO_PIN_14 ((uint32_t)0x4000)
+#define MFXSTM32L152_GPIO_PIN_15 ((uint32_t)0x8000)
+
+#define MFXSTM32L152_GPIO_PIN_16 ((uint32_t)0x010000)
+#define MFXSTM32L152_GPIO_PIN_17 ((uint32_t)0x020000)
+#define MFXSTM32L152_GPIO_PIN_18 ((uint32_t)0x040000)
+#define MFXSTM32L152_GPIO_PIN_19 ((uint32_t)0x080000)
+#define MFXSTM32L152_GPIO_PIN_20 ((uint32_t)0x100000)
+#define MFXSTM32L152_GPIO_PIN_21 ((uint32_t)0x200000)
+#define MFXSTM32L152_GPIO_PIN_22 ((uint32_t)0x400000)
+#define MFXSTM32L152_GPIO_PIN_23 ((uint32_t)0x800000)
+
+#define MFXSTM32L152_AGPIO_PIN_0 MFXSTM32L152_GPIO_PIN_16
+#define MFXSTM32L152_AGPIO_PIN_1 MFXSTM32L152_GPIO_PIN_17
+#define MFXSTM32L152_AGPIO_PIN_2 MFXSTM32L152_GPIO_PIN_18
+#define MFXSTM32L152_AGPIO_PIN_3 MFXSTM32L152_GPIO_PIN_19
+#define MFXSTM32L152_AGPIO_PIN_4 MFXSTM32L152_GPIO_PIN_20
+#define MFXSTM32L152_AGPIO_PIN_5 MFXSTM32L152_GPIO_PIN_21
+#define MFXSTM32L152_AGPIO_PIN_6 MFXSTM32L152_GPIO_PIN_22
+#define MFXSTM32L152_AGPIO_PIN_7 MFXSTM32L152_GPIO_PIN_23
+
+#define MFXSTM32L152_GPIO_PINS_ALL ((uint32_t)0xFFFFFF)
+
+ /**
+ * @brief GPIO: constant
+ */
+#define MFXSTM32L152_GPIO_DIR_IN ((uint8_t)0x0)
+#define MFXSTM32L152_GPIO_DIR_OUT ((uint8_t)0x1)
+#define MFXSTM32L152_IRQ_GPI_EVT_LEVEL ((uint8_t)0x0)
+#define MFXSTM32L152_IRQ_GPI_EVT_EDGE ((uint8_t)0x1)
+#define MFXSTM32L152_IRQ_GPI_TYPE_LLFE ((uint8_t)0x0) /* Low Level Falling Edge */
+#define MFXSTM32L152_IRQ_GPI_TYPE_HLRE ((uint8_t)0x1) /*High Level Raising Edge */
+#define MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR ((uint8_t)0x0)
+#define MFXSTM32L152_GPI_WITH_PULL_RESISTOR ((uint8_t)0x1)
+#define MFXSTM32L152_GPO_PUSH_PULL ((uint8_t)0x0)
+#define MFXSTM32L152_GPO_OPEN_DRAIN ((uint8_t)0x1)
+#define MFXSTM32L152_GPIO_PULL_DOWN ((uint8_t)0x0)
+#define MFXSTM32L152_GPIO_PULL_UP ((uint8_t)0x1)
+
+
+ /**
+ * @brief TOUCH SCREEN Registers
+ */
+
+ /**
+ * @brief Touch Screen Registers
+ */
+#define MFXSTM32L152_TS_SETTLING ((uint8_t)0xA0)
+#define MFXSTM32L152_TS_TOUCH_DET_DELAY ((uint8_t)0xA1)
+#define MFXSTM32L152_TS_AVE ((uint8_t)0xA2)
+#define MFXSTM32L152_TS_TRACK ((uint8_t)0xA3)
+#define MFXSTM32L152_TS_FIFO_TH ((uint8_t)0xA4)
+#define MFXSTM32L152_TS_FIFO_STA ((uint8_t)0x20)
+#define MFXSTM32L152_TS_FIFO_LEVEL ((uint8_t)0x21)
+#define MFXSTM32L152_TS_XY_DATA ((uint8_t)0x24)
+
+ /**
+ * @brief TS registers masks
+ */
+#define MFXSTM32L152_TS_CTRL_STATUS ((uint8_t)0x08)
+#define MFXSTM32L152_TS_CLEAR_FIFO ((uint8_t)0x80)
+
+
+/**
+ * @brief Register address: Idd control register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_CTRL ((uint8_t)0x80)
+
+/**
+ * @brief Register address: Idd pre delay register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_PRE_DELAY ((uint8_t)0x81)
+
+/**
+ * @brief Register address: Idd Shunt registers (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT0_MSB ((uint8_t)0x82)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT0_LSB ((uint8_t)0x83)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT1_MSB ((uint8_t)0x84)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT1_LSB ((uint8_t)0x85)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT2_MSB ((uint8_t)0x86)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT2_LSB ((uint8_t)0x87)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT3_MSB ((uint8_t)0x88)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT3_LSB ((uint8_t)0x89)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT4_MSB ((uint8_t)0x8A)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT4_LSB ((uint8_t)0x8B)
+
+/**
+ * @brief Register address: Idd ampli gain register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_GAIN_MSB ((uint8_t)0x8C)
+#define MFXSTM32L152_REG_ADR_IDD_GAIN_LSB ((uint8_t)0x8D)
+
+/**
+ * @brief Register address: Idd VDD min register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_VDD_MIN_MSB ((uint8_t)0x8E)
+#define MFXSTM32L152_REG_ADR_IDD_VDD_MIN_LSB ((uint8_t)0x8F)
+
+/**
+ * @brief Register address: Idd value register (R)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_VALUE_MSB ((uint8_t)0x14)
+#define MFXSTM32L152_REG_ADR_IDD_VALUE_MID ((uint8_t)0x15)
+#define MFXSTM32L152_REG_ADR_IDD_VALUE_LSB ((uint8_t)0x16)
+
+/**
+ * @brief Register address: Idd calibration offset register (R)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_CAL_OFFSET_MSB ((uint8_t)0x18)
+#define MFXSTM32L152_REG_ADR_IDD_CAL_OFFSET_LSB ((uint8_t)0x19)
+
+/**
+ * @brief Register address: Idd shunt used offset register (R)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT_USED ((uint8_t)0x1A)
+
+/**
+ * @brief Register address: shunt stabilisation delay registers (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_SH0_STABILIZATION ((uint8_t)0x90)
+#define MFXSTM32L152_REG_ADR_IDD_SH1_STABILIZATION ((uint8_t)0x91)
+#define MFXSTM32L152_REG_ADR_IDD_SH2_STABILIZATION ((uint8_t)0x92)
+#define MFXSTM32L152_REG_ADR_IDD_SH3_STABILIZATION ((uint8_t)0x93)
+#define MFXSTM32L152_REG_ADR_IDD_SH4_STABILIZATION ((uint8_t)0x94)
+
+/**
+ * @brief Register address: Idd number of measurements register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_NBR_OF_MEAS ((uint8_t)0x96)
+
+/**
+ * @brief Register address: Idd delta delay between 2 measurements register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_MEAS_DELTA_DELAY ((uint8_t)0x97)
+
+/**
+ * @brief Register address: Idd number of shunt on board register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_SHUNTS_ON_BOARD ((uint8_t)0x98)
+
+
+
+/** @defgroup IDD_Control_Register_Defines IDD Control Register Defines
+ * @{
+ */
+/**
+ * @brief IDD control register masks
+ */
+#define MFXSTM32L152_IDD_CTRL_REQ ((uint8_t)0x01)
+#define MFXSTM32L152_IDD_CTRL_SHUNT_NB ((uint8_t)0x0E)
+#define MFXSTM32L152_IDD_CTRL_VREF_DIS ((uint8_t)0x40)
+#define MFXSTM32L152_IDD_CTRL_CAL_DIS ((uint8_t)0x80)
+
+/**
+ * @brief IDD Shunt Number
+ */
+#define MFXSTM32L152_IDD_SHUNT_NB_1 ((uint8_t) 0x01)
+#define MFXSTM32L152_IDD_SHUNT_NB_2 ((uint8_t) 0x02)
+#define MFXSTM32L152_IDD_SHUNT_NB_3 ((uint8_t) 0x03)
+#define MFXSTM32L152_IDD_SHUNT_NB_4 ((uint8_t) 0x04)
+#define MFXSTM32L152_IDD_SHUNT_NB_5 ((uint8_t) 0x05)
+
+/**
+ * @brief Vref Measurement
+ */
+#define MFXSTM32L152_IDD_VREF_AUTO_MEASUREMENT_ENABLE ((uint8_t) 0x00)
+#define MFXSTM32L152_IDD_VREF_AUTO_MEASUREMENT_DISABLE ((uint8_t) 0x70)
+
+/**
+ * @brief IDD Calibration
+ */
+#define MFXSTM32L152_IDD_AUTO_CALIBRATION_ENABLE ((uint8_t) 0x00)
+#define MFXSTM32L152_IDD_AUTO_CALIBRATION_DISABLE ((uint8_t) 0x80)
+/**
+ * @}
+ */
+
+/** @defgroup IDD_PreDelay_Defines IDD PreDelay Defines
+ * @{
+ */
+/**
+ * @brief IDD PreDelay masks
+ */
+#define MFXSTM32L152_IDD_PREDELAY_UNIT ((uint8_t) 0x80)
+#define MFXSTM32L152_IDD_PREDELAY_VALUE ((uint8_t) 0x7F)
+
+
+/**
+ * @brief IDD PreDelay unit
+ */
+#define MFXSTM32L152_IDD_PREDELAY_0_5_MS ((uint8_t) 0x00)
+#define MFXSTM32L152_IDD_PREDELAY_20_MS ((uint8_t) 0x80)
+/**
+ * @}
+ */
+
+/** @defgroup IDD_DeltaDelay_Defines IDD Delta DElay Defines
+ * @{
+ */
+/**
+ * @brief IDD Delta Delay masks
+ */
+#define MFXSTM32L152_IDD_DELTADELAY_UNIT ((uint8_t) 0x80)
+#define MFXSTM32L152_IDD_DELTADELAY_VALUE ((uint8_t) 0x7F)
+
+
+/**
+ * @brief IDD Delta Delay unit
+ */
+#define MFXSTM32L152_IDD_DELTADELAY_0_5_MS ((uint8_t) 0x00)
+#define MFXSTM32L152_IDD_DELTADELAY_20_MS ((uint8_t) 0x80)
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Exported macro ------------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Exported_Functions
+ * @{
+ */
+
+/**
+ * @brief MFXSTM32L152 Control functions
+ */
+void mfxstm32l152_Init(uint16_t DeviceAddr);
+void mfxstm32l152_DeInit(uint16_t DeviceAddr);
+void mfxstm32l152_Reset(uint16_t DeviceAddr);
+uint16_t mfxstm32l152_ReadID(uint16_t DeviceAddr);
+uint16_t mfxstm32l152_ReadFwVersion(uint16_t DeviceAddr);
+void mfxstm32l152_LowPower(uint16_t DeviceAddr);
+void mfxstm32l152_WakeUp(uint16_t DeviceAddr);
+
+void mfxstm32l152_EnableITSource(uint16_t DeviceAddr, uint8_t Source);
+void mfxstm32l152_DisableITSource(uint16_t DeviceAddr, uint8_t Source);
+uint8_t mfxstm32l152_GlobalITStatus(uint16_t DeviceAddr, uint8_t Source);
+void mfxstm32l152_ClearGlobalIT(uint16_t DeviceAddr, uint8_t Source);
+
+void mfxstm32l152_SetIrqOutPinPolarity(uint16_t DeviceAddr, uint8_t Polarity);
+void mfxstm32l152_SetIrqOutPinType(uint16_t DeviceAddr, uint8_t Type);
+
+
+/**
+ * @brief MFXSTM32L152 IO functionalities functions
+ */
+void mfxstm32l152_IO_Start(uint16_t DeviceAddr, uint32_t IO_Pin);
+uint8_t mfxstm32l152_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode);
+void mfxstm32l152_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState);
+uint32_t mfxstm32l152_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin);
+void mfxstm32l152_IO_EnableIT(uint16_t DeviceAddr);
+void mfxstm32l152_IO_DisableIT(uint16_t DeviceAddr);
+uint32_t mfxstm32l152_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin);
+void mfxstm32l152_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+
+void mfxstm32l152_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction);
+void mfxstm32l152_IO_EnableAF(uint16_t DeviceAddr);
+void mfxstm32l152_IO_DisableAF(uint16_t DeviceAddr);
+void mfxstm32l152_IO_SetIrqTypeMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Type);
+void mfxstm32l152_IO_SetIrqEvtMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Evt);
+void mfxstm32l152_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+void mfxstm32l152_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+
+/**
+ * @brief MFXSTM32L152 Touch screen functionalities functions
+ */
+void mfxstm32l152_TS_Start(uint16_t DeviceAddr);
+uint8_t mfxstm32l152_TS_DetectTouch(uint16_t DeviceAddr);
+void mfxstm32l152_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y);
+void mfxstm32l152_TS_EnableIT(uint16_t DeviceAddr);
+void mfxstm32l152_TS_DisableIT(uint16_t DeviceAddr);
+uint8_t mfxstm32l152_TS_ITStatus (uint16_t DeviceAddr);
+void mfxstm32l152_TS_ClearIT (uint16_t DeviceAddr);
+
+/**
+ * @brief MFXSTM32L152 IDD current measurement functionalities functions
+ */
+void mfxstm32l152_IDD_Start(uint16_t DeviceAddr);
+void mfxstm32l152_IDD_Config(uint16_t DeviceAddr, IDD_ConfigTypeDef MfxIddConfig);
+void mfxstm32l152_IDD_ConfigShuntNbLimit(uint16_t DeviceAddr, uint8_t ShuntNbLimit);
+void mfxstm32l152_IDD_GetValue(uint16_t DeviceAddr, uint32_t *ReadValue);
+uint8_t mfxstm32l152_IDD_GetShuntUsed(uint16_t DeviceAddr);
+void mfxstm32l152_IDD_EnableIT(uint16_t DeviceAddr);
+void mfxstm32l152_IDD_ClearIT(uint16_t DeviceAddr);
+uint8_t mfxstm32l152_IDD_GetITStatus(uint16_t DeviceAddr);
+void mfxstm32l152_IDD_DisableIT(uint16_t DeviceAddr);
+
+/**
+ * @brief MFXSTM32L152 Error management functions
+ */
+uint8_t mfxstm32l152_Error_ReadSrc(uint16_t DeviceAddr);
+uint8_t mfxstm32l152_Error_ReadMsg(uint16_t DeviceAddr);
+void mfxstm32l152_Error_EnableIT(uint16_t DeviceAddr);
+void mfxstm32l152_Error_ClearIT(uint16_t DeviceAddr);
+uint8_t mfxstm32l152_Error_GetITStatus(uint16_t DeviceAddr);
+void mfxstm32l152_Error_DisableIT(uint16_t DeviceAddr);
+
+uint8_t mfxstm32l152_ReadReg(uint16_t DeviceAddr, uint8_t RegAddr);
+void mfxstm32l152_WriteReg(uint16_t DeviceAddr, uint8_t RegAddr, uint8_t Value);
+
+
+
+/**
+ * @brief iobus prototypes (they should be defined in common/stm32_iobus.h)
+ */
+void MFX_IO_Init(void);
+void MFX_IO_DeInit(void);
+void MFX_IO_ITConfig (void);
+void MFX_IO_EnableWakeupPin(void);
+void MFX_IO_Wakeup(void);
+void MFX_IO_Delay(uint32_t delay);
+void MFX_IO_Write(uint16_t addr, uint8_t reg, uint8_t value);
+uint8_t MFX_IO_Read(uint16_t addr, uint8_t reg);
+uint16_t MFX_IO_ReadMultiple(uint16_t addr, uint8_t reg, uint8_t *buffer, uint16_t length);
+
+/**
+ * @}
+ */
+
+/* Touch screen driver structure */
+extern TS_DrvTypeDef mfxstm32l152_ts_drv;
+
+/* IO driver structure */
+extern IO_DrvTypeDef mfxstm32l152_io_drv;
+
+/* IDD driver structure */
+extern IDD_DrvTypeDef mfxstm32l152_idd_drv;
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MFXSTM32L152_H */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/