Browse Source

[update] stm32mp1-ev1 bsp drivers

thread-liu 4 years ago
parent
commit
5dea3cdc27

+ 1 - 10
bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c

@@ -22,8 +22,6 @@
 /* Includes ------------------------------------------------------------------*/
 #include "main.h"
 /* USER CODE BEGIN Includes */
-#include "stpmic.h"
-#include "rtconfig.h"
 /* USER CODE END Includes */
 
 /* Private typedef -----------------------------------------------------------*/
@@ -75,14 +73,7 @@ void HAL_MspInit(void)
   /* System interrupt init*/
 
   /* USER CODE BEGIN MspInit 1 */
-  if(IS_ENGINEERING_BOOT_MODE())
-  {
-#if defined(BSP_USING_ADC) || defined(BSP_USING_DAC)      
-    /* Configure PMIC */
-    BSP_PMIC_Init();
-    BSP_PMIC_InitRegulators();
-#endif
-  }
+
   /* USER CODE END MspInit 1 */
 }
 

+ 66 - 36
bsp/stm32/stm32mp157a-st-ev1/board/Kconfig

@@ -15,6 +15,19 @@ menu "Onboard Peripheral Drivers"
         select BSP_USING_UART4
         default y
 
+    config BSP_USING_PMIC
+        bool "Enable PMIC"
+        select BSP_USING_I2C
+        select BSP_USING_I2C3
+        default y
+
+    config BSP_USING_NAND
+        bool "Enable FMC (MT29F8G08ABACAH4)"
+        select RT_USING_FMC
+        select RT_USING_MTD_NAND
+        select RT_MTD_NAND_DEBUG
+        default n
+
 endmenu
 
 menu "On-chip Peripheral Drivers"
@@ -22,11 +35,6 @@ menu "On-chip Peripheral Drivers"
         bool "Enable GPIO"
         select RT_USING_PIN
         default y
-        
-    config BSP_USING_WWDG
-        bool "Enable WWDG"
-        select RT_USING_WWDG
-        default n
 
     menuconfig BSP_USING_UART
         bool "Enable UART"
@@ -46,7 +54,7 @@ menu "On-chip Peripheral Drivers"
                 bool "Enable UART3 TX DMA"
                 depends on BSP_USING_UART3 && RT_SERIAL_USING_DMA
                 default n
-		
+
             config BSP_USING_UART4
                 bool "Enable UART4"
                 default y
@@ -79,16 +87,6 @@ menu "On-chip Peripheral Drivers"
             config BSP_USING_TIM17
                 bool "Enable TIM17"
                 default n
-
-        endif
-    menuconfig BSP_USING_LPTIM
-        bool "Enable lptimer"
-        default n
-        select RT_USING_LPTIMER
-        if BSP_USING_LPTIM
-            config BSP_USING_LPTIM1
-                bool "Enable LPTIM1"
-                default n
         endif
 
     menuconfig BSP_USING_PWM
@@ -126,52 +124,84 @@ menu "On-chip Peripheral Drivers"
                 default n
         endif
 
-    menuconfig BSP_USING_I2C1
-        bool "Enable I2C1 BUS (software simulation)"
+    menuconfig BSP_USING_I2C
+        bool "Enable I2C BUS (software simulation)"
         select RT_USING_I2C
         select RT_USING_I2C_BITOPS
         select RT_USING_PIN
         default n
-        if BSP_USING_I2C1
-            comment "Notice: PD7 --> 55; PG15 --> 111" 
-            config BSP_I2C1_SCL_PIN
-                int "I2C1 scl pin number"
-                range 1 176
-                default 55
-            config BSP_I2C1_SDA_PIN
-                int "I2C1 sda pin number"
-                range 1 176
-                default 111
-
+        if BSP_USING_I2C
+            menuconfig BSP_USING_I2C1
+                bool "Enable I2C1 BUS (software simulation)"
+                default n
+                if BSP_USING_I2C1
+                    comment "Notice: PD7 --> 55; PG15 --> 111"
+                    config BSP_I2C1_SCL_PIN
+                        int "I2C1 scl pin number"
+                        range 1 176
+                        default 55
+                    config BSP_I2C1_SDA_PIN
+                        int "I2C1 sda pin number"
+                        range 1 176
+                        default 111
+                endif
+            menuconfig BSP_USING_I2C2
+                bool "Enable I2C2 BUS (software simulation)"
+                default n
+                if BSP_USING_I2C2
+                    comment "Notice: PH4 --> 116; PH5 --> 117"
+                    config BSP_I2C2_SCL_PIN
+                        int "i2c2 scl pin number"
+                        range 1 176
+                        default 116
+                    config BSP_I2C2_SDA_PIN
+                        int "I2C2 sda pin number"
+                        range 1 176
+                        default 117
+                endif
+	    menuconfig BSP_USING_I2C3
+                bool "Enable I2C3 BUS (software simulation)"
+                default n
+                if BSP_USING_I2C3
+                    comment "Notice: PZ4 --> 180; PZ5 --> 181"
+                    config BSP_I2C3_SCL_PIN
+                        int "i2c3 scl pin number"
+                        range 1 191
+                        default 180
+                    config BSP_I2C3_SDA_PIN
+                        int "I2C3 sda pin number"
+                        range 1 191
+                        default 181
+                endif
         endif
-        
+
     menuconfig BSP_USING_SPI
         bool "Enable SPI BUS"
         select RT_USING_SPI
         default n
-        if BSP_USING_SPI  
+        if BSP_USING_SPI
             config BSP_USING_SPI5
                 bool "Enable SPI5 BUS"
-                default n        
+                default n
 
             config BSP_SPI5_TX_USING_DMA
                 bool "Enable SPI5 TX DMA"
                 depends on BSP_USING_SPI5
                 default n
-                
+
             config BSP_SPI5_RX_USING_DMA
                 bool "Enable SPI5 RX DMA"
                 depends on BSP_USING_SPI5
                 select BSP_SPI5_TX_USING_DMA
-                default n  
+                default n
         endif
 
  source "../libraries/HAL_Drivers/Kconfig"
-    
+
 endmenu
 
 menu "Board extended module Drivers"
 
 endmenu
- 
+
 endmenu

+ 4 - 12
bsp/stm32/stm32mp157a-st-ev1/board/SConscript

@@ -13,19 +13,11 @@ CubeMX_Config/Common/System/system_stm32mp1xx.c
 CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
 ''')
 
-if GetDepend(['BSP_USING_ADC']):
-    src += Glob('ports/drv_hard_i2c.c')
-    src += Glob('ports/stpmic.c')
+if GetDepend(['BSP_USING_PMIC']):
+    src += Glob('ports/drv_pmic.c')
 
-if GetDepend(['BSP_USING_DAC']):
-    src += Glob('ports/drv_hard_i2c.c')
-    src += Glob('ports/stpmic.c')
-
-if GetDepend(['BSP_USING_WWDG']):
-    src += Glob('ports/drv_wwdg.c')
-
-if GetDepend(['BSP_USING_LPTIM']):
-    src += Glob('ports/drv_lptim.c')
+if GetDepend(['BSP_USING_NAND']):
+    src += Glob('ports/drv_nand.c')
 
 path =  [cwd]
 path += [cwd + '/CubeMX_Config/CM4/Inc']

+ 0 - 124
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_hard_i2c.c

@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author            Notes
- * 2020-06-18     thread-liu        the first version
- */
-
-#include <board.h>
-#include "drv_hard_i2c.h"
-
-//#define DRV_DEBUG
-#define LOG_TAG             "drv.hardi2c"
-#include <drv_log.h>
-
-I2C_HandleTypeDef hI2c4;
-
-int32_t BSP_I2C4_Init(void)
-{
-    int32_t status = RT_EOK;
-
-    if (HAL_I2C_GetState(&hI2c4) == HAL_I2C_STATE_RESET)
-    {
-        if (MX_I2C4_Init(&hI2c4) != HAL_OK)
-        {
-            status = -RT_EBUSY;
-        }
-       /* Init the I2C Msp */
-        if (HAL_I2C_Init(&hI2c4) != HAL_OK)
-        {
-            LOG_D("I2C4 Init Error!\n");
-            status = -RT_EBUSY;
-        } 
-    }
-    return status;
-}
-
-int32_t BSP_I2C4_DeInit(void)
-{
-    int32_t status = RT_EOK;
-    
-    HAL_I2C_MspDeInit(&hI2c4);  
-
-    /* Init the I2C */  
-    if (HAL_I2C_DeInit(&hI2c4) != HAL_OK)
-    {
-        status = -RT_EEMPTY;
-    }
-
-    return status;
-}
-
-HAL_StatusTypeDef MX_I2C4_Init(I2C_HandleTypeDef *hI2c)
-{
-    hI2c4.Instance              = I2C4;   
-    hI2c->Init.Timing           = I2C4_TIMING;
-    hI2c->Init.OwnAddress1      = STPMU1_I2C_ADDRESS;
-    hI2c->Init.AddressingMode   = I2C_ADDRESSINGMODE_7BIT;
-    hI2c->Init.DualAddressMode  = I2C_DUALADDRESS_DISABLE;
-    hI2c->Init.OwnAddress2      = 0;
-    hI2c->Init.OwnAddress2Masks = I2C_OA2_NOMASK;
-    hI2c->Init.GeneralCallMode  = I2C_GENERALCALL_DISABLE;
-    hI2c->Init.NoStretchMode    = I2C_NOSTRETCH_DISABLE;
-  
-    return HAL_I2C_Init(hI2c);
-}
-
-int32_t BSP_I2C4_WriteReg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length)
-{
-    return I2C4_WriteReg(DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length);
-}
-
-int32_t BSP_I2C4_ReadReg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length)
-{
-    return I2C4_ReadReg(DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length);
-}
-
-int32_t BSP_I2C4_WriteReg16(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length)
-{
-    return I2C4_WriteReg(DevAddr, Reg, I2C_MEMADD_SIZE_16BIT, pData, Length);
-}
-
-int32_t BSP_I2C4_ReadReg16(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length)
-{
-    return I2C4_ReadReg(DevAddr, Reg, I2C_MEMADD_SIZE_16BIT, pData, Length);
-}
-
-int32_t BSP_I2C4_IsReady(uint16_t DevAddr, uint32_t Trials)
-{
-    int32_t status = RT_EOK;
-
-    if(HAL_I2C_IsDeviceReady(&hI2c4, DevAddr, Trials, 1000) != HAL_OK)
-    {
-        status = -RT_EBUSY;
-    }
-
-    return status;
-}
-
-static int32_t I2C4_WriteReg(uint16_t DevAddr, uint16_t Reg, uint16_t MemAddSize, uint8_t *pData, uint16_t Length)
-{  
-    int32_t status = -RT_EIO;
-
-    if(HAL_I2C_Mem_Write(&hI2c4, DevAddr, Reg, MemAddSize, pData, Length, 10000) == HAL_OK)
-    {
-        status = RT_EOK;
-    }
-
-    return status;
-}
-
-static int32_t I2C4_ReadReg(uint16_t DevAddr, uint16_t Reg, uint16_t MemAddSize, uint8_t *pData, uint16_t Length)
-{  
-    int32_t status = -RT_EIO;
-
-    if (HAL_I2C_Mem_Read(&hI2c4, DevAddr, Reg, MemAddSize, pData, Length, 10000) == HAL_OK)
-    {
-        status = RT_EOK;
-    }
-
-    return status;
-}

+ 0 - 48
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_hard_i2c.h

@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author            Notes
- * 2020-06-18     thread-liu        the first version
- */
-
-#ifndef __DRV_HARD_I2C_H__
-#define __DRV_HARD_I2C_H__
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32mp1xx_hal.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define STPMU1_I2C_ADDRESS               ((0x33 & 0x7F) << 1)
-
-#ifndef I2C_SPEED
-#define I2C_SPEED                        ((uint32_t)100000)
-#endif /* I2C_SPEED */
-
-#ifndef I2C4_TIMING
-#define I2C4_TIMING                      ((uint32_t)0x10805E89)
-#endif
-
-static int32_t I2C4_WriteReg(uint16_t DevAddr, uint16_t MemAddSize, uint16_t Reg, uint8_t *pData, uint16_t Length);
-static int32_t I2C4_ReadReg(uint16_t DevAddr, uint16_t MemAddSize, uint16_t Reg, uint8_t *pData, uint16_t Length);
-
-int32_t BSP_I2C4_Init(void);
-int32_t BSP_I2C4_DeInit(void);
-int32_t BSP_I2C4_WriteReg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length);
-int32_t BSP_I2C4_ReadReg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length);
-int32_t BSP_I2C4_WriteReg16(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length);
-int32_t BSP_I2C4_ReadReg16(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length);
-int32_t BSP_I2C4_IsReady(uint16_t DevAddr, uint32_t Trials);
-
-HAL_StatusTypeDef MX_I2C4_Init(I2C_HandleTypeDef *hI2c);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

+ 0 - 128
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_lptim.c

@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author          Notes
- * 2020-06-19     thread-liu      first version
- */
-
-#include <board.h>
-
-#ifdef BSP_USING_LPTIM
-#include "drv_config.h"
-#include <string.h>
-#include <stdlib.h>
-
-//#define DRV_DEBUG
-#define LOG_TAG             "drv.lptimer"
-#include <drv_log.h>
-
-LPTIM_HandleTypeDef hlptim1;
-
-void LPTIM1_IRQHandler(void)
-{
-    /* enter interrupt */
-    rt_interrupt_enter();
-    
-    HAL_LPTIM_IRQHandler(&hlptim1);
-    
-    /* leave interrupt */
-    rt_interrupt_leave();
-}
-
-void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim)
-{
-    if(hlptim->Instance == LPTIM1)
-    {
-        rt_kprintf("hello rt-thread!\n");
-    }
-}
-
-static int lptim_control(uint8_t pre_value)
-{
-    if(pre_value > 7)
-    {
-       pre_value = 7; 
-    }
-    hlptim1.Instance->CFGR &= ~(7 << 9);      /* clear PRESC[2:0] */
-    hlptim1.Instance->CFGR |= pre_value << 9; /* set PRESC[2:0]  */
-
-    return RT_EOK;
-}
-
-/**
- * This function initialize the lptim
- */
-static int lptim_init(void)
-{
-    hlptim1.Instance = LPTIM1;
-    hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
-    hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
-    hlptim1.Init.UltraLowPowerClock.Polarity = LPTIM_CLOCKPOLARITY_RISING;
-    hlptim1.Init.UltraLowPowerClock.SampleTime = LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION;
-    hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
-    hlptim1.Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH;
-    hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
-    hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
-    hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
-    hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
-    if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
-    {
-        LOG_D("LPTIM Init Error!\n");
-        return -RT_ERROR;
-    }
-  /* ### Start counting in interrupt mode ############################# */
-    if (HAL_LPTIM_Counter_Start_IT(&hlptim1, 5000) != HAL_OK)
-    {
-        LOG_D("LPTIM Start Counting Error!\n");
-        return -RT_ERROR;
-    }
-    
-    return RT_EOK;
-}
-
-static int lptim_deinit()
-{
-   if (HAL_LPTIM_DeInit(&hlptim1) != HAL_OK)
-   {
-        LOG_D("LPTIM Deinit Error!\n");
-        return -RT_ERROR;
-   }
-    
-    return RT_EOK;
-}
-
-static int lptim_sample(int argc, char *argv[])
-{
-    if (argc > 1)
-    {
-        if (!strcmp(argv[1], "run"))
-        { 
-           lptim_init(); 
-        }
-        else if (!strcmp(argv[1], "stop"))
-        {
-            lptim_deinit();
-        }
-        else if (!strcmp(argv[1], "set"))
-        {
-            if (argc > 2)
-            {
-               lptim_control(atoi(argv[2]));
-            }     
-        }
-    }
-    else
-    {
-        rt_kprintf("Usage:\n");
-        rt_kprintf("lptim_sample run            - open lptim, shell will printf 'hello rt-thread'\n");
-        rt_kprintf("lptim_sample set            - set the lptim prescaler, lptim_sample set [0 - 7]\n");
-    }
-
-    return RT_EOK;
-}
-MSH_CMD_EXPORT(lptim_sample, low power timer sample);
-
-#endif

+ 670 - 0
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_nand.c

@@ -0,0 +1,670 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2020-06-30     thread-liu   first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <board.h>
+
+#ifdef BSP_USING_NAND
+
+#define DRV_DEBUG
+#define LOG_TAG     "drv.nand"
+#include <drv_log.h>
+#include "drv_nand.h"
+
+#define NAND_RB_PIN GET_PIN(D, 6)
+
+static rt_uint32_t ecc_rdbuf[NAND_MAX_PAGE_SIZE/NAND_ECC_SECTOR_SIZE];	
+static rt_uint32_t ecc_hdbuf[NAND_MAX_PAGE_SIZE/NAND_ECC_SECTOR_SIZE];	
+struct rthw_fmc
+{
+    rt_uint32_t id;
+    struct rt_mutex lock;
+};
+static struct rthw_fmc _device = {0};
+
+static void rt_hw_nand_gpio_init(void)
+{
+    GPIO_InitTypeDef GPIO_InitStruct = {0};
+    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+
+    if (IS_ENGINEERING_BOOT_MODE())
+    {
+        PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FMC;
+        PeriphClkInit.AdcClockSelection = RCC_FMCCLKSOURCE_ACLK;
+        if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+        {
+            Error_Handler();
+        }
+    }
+    __HAL_RCC_FMC_CLK_ENABLE();
+    __HAL_RCC_GPIOD_CLK_ENABLE();
+    __HAL_RCC_GPIOE_CLK_ENABLE();
+    __HAL_RCC_GPIOG_CLK_ENABLE();
+
+    /* PD6 R/B */
+    GPIO_InitStruct.Pin = GPIO_PIN_6;
+    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+    /* PG9 NCE */
+    GPIO_InitStruct.Pin = GPIO_PIN_9;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+    GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
+    HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
+
+    /* PD0,1,4,5,11,12,14,15 */
+    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 |
+                          GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_15;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+    /* PE7,8,9,10 */
+    GPIO_InitStruct.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
+    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+}
+
+/* nand delay */
+static void rt_hw_nand_delay(volatile uint32_t i)
+{
+    while (i > 0)
+    {
+        i--;
+    }
+}
+
+/* read nand flash status */
+static rt_err_t rt_hw_nand_read_status(void)
+{
+    rt_err_t result = RT_EOK;
+
+    NAND_CMD_AREA = NAND_READSTA;
+
+    rt_hw_nand_delay(NAND_TWHR_DELAY);
+
+    result = NAND_ADDR_AREA;
+
+    return result;
+}
+
+/* wait nand flash read */
+static rt_err_t rt_hw_nand_wait_ready(void)
+{
+    rt_err_t result = RT_EOK;
+    static uint32_t time = 0;
+
+    while (1)
+    {
+        result = rt_hw_nand_read_status();
+
+        if (result & NAND_READY)
+        {
+            break;
+        }
+        time++;
+        if (time >= 0X1FFFFFFF)
+        {
+            return RT_ETIMEOUT;
+        }
+    }
+
+    return RT_EOK;
+}
+
+/* set nand mode */
+static rt_err_t rt_hw_nand_set_mode(uint8_t mode)
+{
+    NAND_CMD_AREA = NAND_FEATURE;
+    NAND_DATA_AREA = 0x01;
+    NAND_ADDR_AREA = mode;
+    NAND_ADDR_AREA = 0;
+    NAND_ADDR_AREA = 0;
+    NAND_ADDR_AREA = 0;
+
+    if (rt_hw_nand_wait_ready() == RT_EOK)
+    {
+        return RT_EOK;
+    }
+    else
+    {
+        return RT_ERROR;
+    }
+}
+
+/* reset nand flash */
+static rt_err_t rt_hw_nand_reset(void)
+{
+    NAND_CMD_AREA = NAND_RESET;
+
+    if (rt_hw_nand_wait_ready() == RT_EOK)
+    {
+        return RT_EOK; /* success */
+    }
+    else
+    {
+        return RT_ERROR;
+    }
+}
+
+/* read nand flash id */
+static rt_err_t _read_id(struct rt_mtd_nand_device *device)
+{
+    RT_ASSERT(device != RT_NULL);
+
+    uint8_t deviceid[5];
+
+    NAND_CMD_AREA = NAND_READID; /* read id command */
+    NAND_DATA_AREA = 0x00;
+
+    deviceid[0] = NAND_ADDR_AREA; /* Byte 0 */
+    deviceid[1] = NAND_ADDR_AREA; /* Byte 1 */
+    deviceid[2] = NAND_ADDR_AREA; /* Byte 2 */
+    deviceid[3] = NAND_ADDR_AREA; /* Byte 3 */
+    deviceid[4] = NAND_ADDR_AREA; /* Byte 4 */
+
+    _device.id = ((uint32_t)deviceid[4]) << 24 | ((uint32_t)deviceid[3]) << 16 | ((uint32_t)deviceid[2]) << 8 | deviceid[1];
+
+    LOG_D("nand id: 0x%08x", _device.id);
+
+    return RT_EOK;
+}
+
+static rt_uint8_t rt_hw_nand_ecc_check(rt_uint32_t generatedEcc, rt_uint32_t readEcc, rt_uint8_t* data)
+{
+#define ECC_MASK28    0x0FFFFFFF          /* 28 valid ECC parity bits. */
+#define ECC_MASK      0x05555555          /* 14 ECC parity bits.       */
+
+    rt_uint32_t count, bitNum, byteAddr;
+    rt_uint32_t mask;
+    rt_uint32_t syndrome;
+    rt_uint32_t eccP;                            /* 14 even ECC parity bits. */
+    rt_uint32_t eccPn;                           /* 14 odd ECC parity bits.  */
+
+    syndrome = (generatedEcc ^ readEcc) & ECC_MASK28;
+
+    if (syndrome == 0)   
+    {
+        return (RT_EOK);                     /* No errors in data. */
+    }
+     
+    eccPn = syndrome & ECC_MASK;              /* Get 14 odd parity bits.  */
+    eccP  = (syndrome >> 1) & ECC_MASK;       /* Get 14 even parity bits. */
+
+    if ((eccPn ^ eccP) == ECC_MASK)           /* 1-bit correctable error ? */
+    {
+        bitNum = (eccP & 0x01) |
+                 ((eccP >> 1) & 0x02) |
+                 ((eccP >> 2) & 0x04);
+        LOG_D("ECC bit %d\n",bitNum);
+        byteAddr = ((eccP >> 6) & 0x001) |
+                   ((eccP >> 7) & 0x002) |
+                   ((eccP >> 8) & 0x004) |
+                   ((eccP >> 9) & 0x008) |
+                   ((eccP >> 10) & 0x010) |
+                   ((eccP >> 11) & 0x020) |
+                   ((eccP >> 12) & 0x040) |
+                   ((eccP >> 13) & 0x080) |
+                   ((eccP >> 14) & 0x100) |
+                   ((eccP >> 15) & 0x200) |
+                   ((eccP >> 16) & 0x400) ;
+
+        data[ byteAddr ] ^= 1 << bitNum;
+
+        return RT_EOK;
+    }
+
+    /* Count number of one's in the syndrome. */
+    count = 0;
+    mask  = 0x00800000;
+    while (mask)
+    {
+        if (syndrome & mask)
+            count++;
+        mask >>= 1;
+    }
+
+    if (count == 1)           /* Error in the ECC itself. */
+        return RT_EIO;
+
+    return RT_EIO;       /* Unable to correct data. */
+
+#undef ECC_MASK
+#undef ECC_MASK24
+}
+
+static rt_err_t _read_page(struct rt_mtd_nand_device *device,
+                           rt_off_t page,
+                           rt_uint8_t *data,
+                           rt_uint32_t data_len,
+                           rt_uint8_t *spare,
+                           rt_uint32_t spare_len)
+{
+    RT_ASSERT(device != RT_NULL);
+
+    rt_uint32_t index, i, tickstart, eccnum;
+    rt_err_t result;
+    rt_uint8_t *p = RT_NULL;
+    
+    page = page + device->block_start * device->pages_per_block;
+    if (page / device->pages_per_block > device->block_end)
+    {
+        return -RT_EIO;
+    }
+    
+    rt_mutex_take(&_device.lock, RT_WAITING_FOREVER);
+    if (data && data_len)
+    {
+        NAND_CMD_AREA  = NAND_AREA_A;
+        NAND_DATA_AREA = (rt_uint8_t)0;
+        NAND_DATA_AREA = (rt_uint8_t)(0 >> 8);
+        NAND_DATA_AREA = (rt_uint8_t)page;
+        NAND_DATA_AREA = (rt_uint8_t)(page >> 8);
+        NAND_DATA_AREA = (rt_uint8_t)(page >> 16);
+        NAND_CMD_AREA  = NAND_AREA_TRUE1;
+        
+        rt_hw_nand_delay(10);
+        
+        /* not an integer multiple of NAND ECC SECTOR SIZE, no ECC checks*/
+        if (data_len % NAND_ECC_SECTOR_SIZE)
+        {
+            for (i = 0; i < data_len; i++)
+            {
+                *data++ = NAND_ADDR_AREA;
+            }
+        }
+        else
+        {
+            eccnum = data_len/NAND_ECC_SECTOR_SIZE;			
+            p = data;
+            for (index = 0; index < 4; index++)
+            {
+                FMC_Bank3_R->PCR |= 1<<6;	/* enable ecc */ 
+            
+                for (i = 0; i < NAND_ECC_SECTOR_SIZE; i++)				
+                {
+                    *data++ = NAND_ADDR_AREA;
+                }		
+                /* Get tick */
+                tickstart = rt_tick_get();
+                /* Wait until FIFO is empty */
+                while ((FMC_Bank3_R->SR & (1 << 6)) == RESET)
+                {
+                    /* Check for the Timeout */
+                    if ((rt_tick_get() - tickstart) > 10000)
+                    {
+                        result = RT_ETIMEOUT;
+                        goto _exit;
+                    }
+                }
+                ecc_hdbuf[index] = FMC_Bank3_R->HECCR;	/* read hardware ecc */
+                FMC_Bank3_R->PCR &= ~(1<<6);		    /* disable ecc */
+            }
+            i = device->page_size + 0x10;
+            
+            rt_hw_nand_delay(10);
+            
+            NAND_CMD_AREA  = 0x05;
+            NAND_DATA_AREA = (rt_uint8_t)i;
+            NAND_DATA_AREA = (rt_uint8_t)(i>>8);
+            NAND_CMD_AREA  = 0xE0;
+            
+            rt_hw_nand_delay(10);
+            
+            data =(rt_uint8_t*)&ecc_rdbuf[0]; 
+            for (i = 0; i < 4*eccnum; i++)
+            {
+                *data++ = NAND_ADDR_AREA;
+            }		
+            /* check ecc */
+            for(i  = 0;  i< eccnum; i++)
+            {
+                if(ecc_rdbuf[i] != ecc_hdbuf[i])
+                {
+                    result = rt_hw_nand_ecc_check(ecc_hdbuf[i], ecc_rdbuf[i], p + NAND_ECC_SECTOR_SIZE*i);
+                    if (result != RT_EOK)
+                    {
+                        goto _exit;
+                    }
+                } 
+            }
+        }
+    }    
+    if (spare && spare_len)
+    {
+        NAND_CMD_AREA  = NAND_AREA_A;
+        NAND_DATA_AREA = (rt_uint8_t)0;
+        NAND_DATA_AREA = (rt_uint8_t)(0 >> 8);
+        NAND_DATA_AREA = (rt_uint8_t)page;
+        NAND_DATA_AREA = (rt_uint8_t)(page >> 8);
+        NAND_DATA_AREA = (rt_uint8_t)(page >> 16);
+        NAND_CMD_AREA  = NAND_AREA_TRUE1;
+        rt_thread_delay(10);
+
+        for (i = 0; i < spare_len; i ++)
+        {
+            *spare++ = NAND_ADDR_AREA;
+        }
+    }
+    
+    if (rt_hw_nand_wait_ready() != RT_EOK)
+    {
+        result = RT_ETIMEOUT;
+        goto _exit;
+    }
+
+_exit:
+    rt_mutex_release(&_device.lock);
+
+    return result;
+}
+
+static rt_err_t _write_page(struct rt_mtd_nand_device *device,
+                            rt_off_t page,
+                            const rt_uint8_t *data,
+                            rt_uint32_t data_len,
+                            const rt_uint8_t *spare,
+                            rt_uint32_t spare_len)
+{
+    RT_ASSERT(device != RT_NULL);
+
+    rt_err_t result = RT_EOK;
+    rt_uint32_t eccnum;
+    rt_uint32_t i, index;
+    rt_uint32_t tickstart = 0;
+
+    page = page + device->block_start * device->pages_per_block;
+    if (page / device->pages_per_block > device->block_end)
+    {
+        return -RT_EIO;
+    }
+
+    rt_mutex_take(&_device.lock, RT_WAITING_FOREVER);
+
+    if (data && data_len)
+    {
+        NAND_CMD_AREA = NAND_WRITE0;
+
+        NAND_DATA_AREA = (rt_uint8_t)0;
+        NAND_DATA_AREA = (rt_uint8_t)(0 >> 8);
+        NAND_DATA_AREA = (rt_uint8_t)(page & 0xFF);
+        NAND_DATA_AREA = (rt_uint8_t)(page >> 8);
+        NAND_DATA_AREA = (rt_uint8_t)(page >> 16);
+        
+        rt_hw_nand_delay(10);
+        
+        if (data_len % NAND_ECC_SECTOR_SIZE)
+        { 
+            /* read nand flash */
+            for (i = 0; i < data_len; i++)
+            {
+                NAND_ADDR_AREA = *data++;
+            }
+        }
+        else
+        {
+            eccnum   = data_len/NAND_ECC_SECTOR_SIZE;	
+            for (index = 0; index < eccnum; index++)
+            {
+                FMC_Bank3_R->PCR |= 1<<6;				/* enable ecc */ 
+                
+                for (i = 0; i < NAND_ECC_SECTOR_SIZE; i++)				
+                {
+                    NAND_ADDR_AREA = *data++;
+                }		
+                /* Get tick */
+                tickstart = rt_tick_get();
+                /* Wait until FIFO is empty */
+                while ((FMC_Bank3_R->SR & (1 << 6)) == RESET)
+                {
+                    /* Check for the Timeout */
+                    if ((rt_tick_get() - tickstart) > 10000)
+                    {
+                        result = RT_ETIMEOUT;
+                        goto _exit;
+                    }
+                }
+                ecc_hdbuf[index] = FMC_Bank3_R->HECCR;	/* read hardware ecc */
+                FMC_Bank3_R->PCR &= ~(1<<6);			/* disable ecc */
+            }
+            
+            i = device->page_size + 0x10;
+            rt_hw_nand_delay(10);
+            NAND_CMD_AREA  = 0x85;
+            NAND_DATA_AREA = (rt_uint8_t)i;
+            NAND_DATA_AREA = (rt_uint8_t)(i>>8);
+            rt_hw_nand_delay(10);
+            
+            data = (uint8_t*)&ecc_hdbuf[0];
+
+            for (index = 0; index < eccnum; index++)		
+            { 
+                for (i = 0; i < 4; i++)				 
+                {
+                    NAND_ADDR_AREA = *data++;
+                }
+            }              
+        }
+    }
+    NAND_CMD_AREA = NAND_WRITE_TURE1;
+    if (rt_hw_nand_wait_ready() != RT_EOK)
+    {
+        result = -RT_EIO;
+        goto _exit;
+    }
+        
+    if (spare && spare_len)
+    {
+        NAND_CMD_AREA = NAND_WRITE0;
+        NAND_DATA_AREA = (rt_uint8_t)(4096 & 0xFF);
+        NAND_DATA_AREA = (rt_uint8_t)(4096 >> 8);
+        NAND_DATA_AREA = (rt_uint8_t)(page & 0xFF);
+        NAND_DATA_AREA = (rt_uint8_t)(page >> 8);
+        NAND_DATA_AREA = (rt_uint8_t)(page >> 16);
+
+        for (i = 4; i < spare_len; i++)
+        {
+            NAND_ADDR_AREA = spare[i];
+        }
+        NAND_CMD_AREA = NAND_WRITE_TURE1;
+        if (rt_hw_nand_wait_ready() != RT_EOK)
+        {
+            result = -RT_EIO;
+            goto _exit;
+        }
+    }
+_exit:
+    rt_mutex_release(&_device.lock);
+
+    return result;
+}
+
+/* erase one block */
+static rt_err_t _erase_block(struct rt_mtd_nand_device *device, rt_uint32_t block)
+{
+    RT_ASSERT(device != RT_NULL);
+    unsigned int block_num;
+    rt_err_t result = RT_EOK;
+
+    block = block + device->block_start;
+    block_num = block << 6;
+
+    rt_mutex_take(&_device.lock, RT_WAITING_FOREVER);
+
+    NAND_CMD_AREA = NAND_ERASE0;
+    NAND_DATA_AREA = (uint8_t)block_num;
+    NAND_DATA_AREA = (uint8_t)(block_num >> 8);
+    NAND_DATA_AREA = (uint8_t)(block_num >> 16);
+    NAND_CMD_AREA = NAND_ERASE1;
+
+    rt_thread_delay(NAND_TBERS_DELAY);
+
+    if (rt_hw_nand_wait_ready() != RT_EOK)
+    {
+        result = -RT_ERROR;
+    }
+
+    rt_mutex_release(&_device.lock);
+
+    return result;
+}
+
+static rt_err_t _page_copy(struct rt_mtd_nand_device *device,
+                           rt_off_t src_page,
+                           rt_off_t dst_page)
+{
+    RT_ASSERT(device != RT_NULL);
+    rt_err_t result = RT_EOK;
+    rt_uint32_t source_block = 0, dest_block = 0;
+
+    src_page = src_page + device->block_start * device->pages_per_block;
+    dst_page = dst_page + device->block_start * device->pages_per_block;
+    source_block = src_page / device->pages_per_block;
+    dest_block = dst_page / device->pages_per_block;
+    if ((source_block % 2) != (dest_block % 2))
+    {
+        return RT_MTD_ESRC;
+    }
+
+    NAND_CMD_AREA = NAND_MOVEDATA_CMD0;
+    NAND_DATA_AREA = (rt_uint8_t)(0 & 0xFF);
+    NAND_DATA_AREA = (rt_uint8_t)(0 >> 8);
+    NAND_DATA_AREA = (rt_uint8_t)(src_page & 0xFF);
+    NAND_DATA_AREA = (rt_uint8_t)(src_page >> 8);
+    NAND_DATA_AREA = (rt_uint8_t)(src_page >> 16);
+    NAND_CMD_AREA = NAND_MOVEDATA_CMD1;
+
+    rt_hw_nand_delay(10);
+
+    NAND_CMD_AREA = NAND_MOVEDATA_CMD2;
+    NAND_DATA_AREA = ((rt_uint8_t)(0 & 0xFF));
+    NAND_DATA_AREA = ((rt_uint8_t)(0 >> 8));
+    NAND_DATA_AREA = ((rt_uint8_t)(dst_page & 0xFF));
+    NAND_DATA_AREA = ((rt_uint8_t)(dst_page >> 8));
+    NAND_DATA_AREA = ((rt_uint8_t)(dst_page >> 16));
+    NAND_CMD_AREA = (NAND_MOVEDATA_CMD3);
+
+    if (rt_hw_nand_wait_ready() != RT_EOK)
+    {
+        result = -RT_ERROR;
+    }
+
+    return result;
+}
+
+static rt_err_t _check_block(struct rt_mtd_nand_device *device, rt_uint32_t block)
+{
+    RT_ASSERT(device != RT_NULL);
+    return (RT_MTD_EOK);
+}
+
+static rt_err_t _mark_bad(struct rt_mtd_nand_device *device, rt_uint32_t block)
+{
+    RT_ASSERT(device != RT_NULL);
+    return (RT_MTD_EOK);
+}
+
+static const struct rt_mtd_nand_driver_ops ops =
+    {
+        _read_id,
+        _read_page,
+        _write_page,
+        _page_copy,
+        _erase_block,
+        _check_block,
+        _mark_bad,
+};
+static struct rt_mtd_nand_device nand_dev;
+
+static rt_err_t nand_init(struct rt_mtd_nand_device *device)
+{
+    RT_ASSERT(device != RT_NULL);
+    uint32_t tempreg = 0;
+
+    rt_hw_nand_gpio_init();
+
+    tempreg |= 0 << 1;          /* disable Wait feature enable bit */
+    tempreg |= 0 << 4;          /* Data bus width 8*/
+    tempreg |= 0 << 6;          /* disable ECC */
+    tempreg |= 1 << 17;         /* ECC page 512 BYTE */
+    tempreg |= 5 << 9;          /* set TCLR */
+    tempreg |= 5 << 13;         /* set TAR */
+    FMC_Bank3_R->PCR = tempreg; /* set nand control register */
+
+    tempreg &= 0;
+    tempreg |= 3 << 0;  /* set MEMSET  */
+    tempreg |= 5 << 8;  /* set MEMWAIT */
+    tempreg |= 2 << 16; /* set MEMHOLD */
+    tempreg |= 3 << 24; /* set MEMHIZ  */
+    FMC_Bank3_R->PMEM = tempreg;
+    FMC_Bank3_R->PATT = 0;                     /* Attribute memory space timing registers */
+    FMC_Bank3_R->PCR |= 1 << 2;                /* NAND Flash memory bank enable bit */
+    FMC_Bank1_R->BTCR[0] |= (uint32_t)1 << 31; /* enable fmc */
+
+    rt_hw_nand_reset(); /* reset nand flash*/
+    rt_thread_delay(100);
+
+    /* read id */
+    _read_id(&nand_dev);
+
+    if (_device.id != MT29F8G08ABACAH4)
+    {
+        LOG_E("nand id 0x%08x not support", _device.id);
+        return RT_ERROR; /* can't find nand flash */
+    }
+
+    rt_hw_nand_set_mode(4); /* set mode 4, high speed mode*/
+
+    return RT_EOK;
+}
+
+int rt_hw_nand_init(void)
+{
+    rt_err_t result = RT_EOK;
+
+    rt_pin_mode(NAND_RB_PIN, PIN_MODE_INPUT_PULLUP); /* nand flash R/B pin */
+
+    result = nand_init(&nand_dev);
+    if (result != RT_EOK)
+    {
+        LOG_D("nand flash init error!");
+        return RT_ERROR;
+    }
+    rt_mutex_init(&_device.lock, "nand", RT_IPC_FLAG_FIFO);
+
+    nand_dev.page_size       = 4096;
+    nand_dev.pages_per_block = 224;
+    nand_dev.plane_num       = 2;
+    nand_dev.oob_size        = 64;
+    nand_dev.oob_free        = 64 - ((4096) * 3 / 256);
+    nand_dev.block_start     = 0;
+    nand_dev.block_end       = 4095;
+
+    nand_dev.block_total = nand_dev.block_end - nand_dev.block_start;
+    nand_dev.ops = &ops;
+
+    result = rt_mtd_nand_register_device("nand", &nand_dev);
+    if (result != RT_EOK)
+    {
+        rt_device_unregister(&nand_dev.parent);
+        return RT_ERROR;
+    }
+
+    rt_kprintf("nand flash init success, id: 0x%08x\n", _device.id);
+
+    return RT_EOK;
+}
+
+INIT_DEVICE_EXPORT(rt_hw_nand_init);
+
+#endif

+ 59 - 0
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_nand.h

@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2020-00-30     thread-liu   first version
+ */
+
+#ifndef __DRV_NAND_H__
+#define __DRV_NAND_H__
+
+#include "board.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define NAND_MAX_PAGE_SIZE              4096
+#define NAND_ECC_SECTOR_SIZE            512
+
+#define NAND_TWHR_DELAY                 25
+#define NAND_TBERS_DELAY                4
+
+#define MT29F8G08ABACAH4                0x64A690D3 /* id */
+
+#define NAND_ADDR                       ((rt_uint32_t)0x80000000) /* nand base address */
+#define NAND_ADDR_AREA                  (*(__IO rt_uint8_t *)NAND_ADDR)
+#define NAND_CMD_AREA                   (*(__IO rt_uint8_t *)(NAND_ADDR | 1 << 16))  /*  command */
+#define NAND_DATA_AREA                  (*(__IO rt_uint8_t *)(NAND_ADDR | 1 << 17)) /*  data */
+
+/* nand flash command */
+#define NAND_READID                     0x90
+#define NAND_FEATURE                    0xEF
+#define NAND_RESET                      0xFF
+#define NAND_READSTA                    0x70
+#define NAND_AREA_A                     0x00
+#define NAND_AREA_TRUE1                 0x30
+#define NAND_WRITE0                     0x80
+#define NAND_WRITE_TURE1                0x10
+#define NAND_ERASE0                     0x60
+#define NAND_ERASE1                     0xD0
+#define NAND_MOVEDATA_CMD0              0x00
+#define NAND_MOVEDATA_CMD1              0x35
+#define NAND_MOVEDATA_CMD2              0x85
+#define NAND_MOVEDATA_CMD3              0x10
+
+/* nand flash status */
+#define NAND_READY                      0x40 /* read */
+#define NAND_ECC1BITERR                 0x03 /* ECC 1bit err */
+#define NAND_ECC2BITERR                 0x04 /* ECC 2bit or more err */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 905 - 0
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pmic.c

@@ -0,0 +1,905 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2020-06-18     thread-liu        the first version
+ */
+
+#include <board.h>
+
+#if defined(BSP_USING_PMIC)
+
+#include <drv_pmic.h>
+#include <string.h>
+
+//#define DRV_DEBUG
+#define LOG_TAG              "drv.pmic"
+#include <drv_log.h>
+
+static struct rt_i2c_bus_device *pmic_dev = RT_NULL;
+
+/* i2c read reg */
+static rt_err_t read_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t len, rt_uint8_t *buf)
+{
+    struct rt_i2c_msg msg[2] = {0, 0};
+
+    RT_ASSERT(bus != RT_NULL);
+    
+    msg[0].addr  = STPMU1_I2C_ADDRESS;     /* Slave address */
+    msg[0].flags = RT_I2C_WR;              /* Write flag */
+    msg[0].buf   = &reg;                   /* Slave register address */
+    msg[0].len   = 1;                      /* Number of bytes sent */
+        
+    msg[1].addr  = STPMU1_I2C_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; //cmd
+    buf[1] = data;
+
+    msgs.addr  = STPMU1_I2C_ADDRESS;
+    msgs.flags = RT_I2C_WR;
+    msgs.buf   = buf;
+    msgs.len   = 2;
+
+    if (rt_i2c_transfer(bus, &msgs, 1) == 1)
+    {
+        return RT_EOK;
+    }
+
+    return RT_ERROR;
+}
+
+/* register direct access */
+static rt_err_t stpmu1_read_reg(uint8_t register_id)
+{
+    rt_err_t status = RT_EOK;
+    uint8_t result = 0;
+
+    status = read_reg(pmic_dev, register_id, 1, &result);
+
+    /* Check the communication status */
+    if(status != RT_EOK)
+    {
+        Error_Handler();
+    }
+    
+    return result;
+}
+
+static void stpmu1_write_reg(uint8_t register_id, uint8_t value)
+{
+    uint32_t status = RT_EOK;
+    uint8_t readval = 0;
+    
+    status = write_reg(pmic_dev, register_id, (rt_uint8_t)value);
+
+    /* Check the communication status */
+    if(status != RT_EOK)
+    {
+        Error_Handler();
+    }
+    /* verify register content */
+    if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40))
+    {
+        readval = stpmu1_read_reg(register_id);
+        if (readval != value)
+        {
+            Error_Handler();
+        }
+    }
+}
+
+/** PMIC init  */
+static uint32_t BSP_PMIC_MspInit(void)
+{
+    GPIO_InitTypeDef  GPIO_InitStruct = {0};
+
+    __HAL_RCC_GPIOA_CLK_ENABLE();
+    GPIO_InitStruct.Pin       = GPIO_PIN_0;
+    GPIO_InitStruct.Mode      = GPIO_MODE_IT_FALLING;
+    GPIO_InitStruct.Pull      = GPIO_PULLUP; 
+    GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;
+    GPIO_InitStruct.Alternate = 0 ;
+    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+    HAL_NVIC_SetPriority(EXTI0_IRQn, 0x03, 0x00);
+    HAL_NVIC_EnableIRQ(EXTI0_IRQn);
+
+    return RT_EOK;
+}
+
+static uint32_t BSP_PMIC_MspDeInit(void)
+{
+    __HAL_RCC_GPIOA_CLK_DISABLE();
+
+    HAL_NVIC_DisableIRQ(EXTI0_IRQn);
+
+    HAL_GPIO_DeInit(GPIOA,GPIO_PIN_0);
+
+    return RT_EOK;
+}
+
+uint16_t buck1_voltage_table[] = {
+  600,
+  625,
+  650,
+  675,
+  700,
+  725,
+  750,
+  775,
+  800,
+  825,
+  850,
+  875,
+  900,
+  925,
+  950,
+  975,
+  1000,
+  1025,
+  1050,
+  1075,
+  1100,
+  1125,
+  1150,
+  1175,
+  1200,
+  1225,
+  1250,
+  1275,
+  1300,
+  1325,
+  1350,
+  1350,// 31  1,35
+};
+
+uint16_t buck2_voltage_table[] = {
+  1000, // 1
+  1000, //
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1050, // 1,05
+  1050, // 1,05
+  1100, // 1,1
+  1100, // 1,1
+  1150, // 1,15
+  1150, // 1,15
+  1200, // 1,2
+  1200, // 1,2
+  1250, // 1,25
+  1250, // 1,25
+  1300, // 1,3
+  1300, // 1,3
+  1350, // 1,35
+  1350, // 1,35
+  1400, // 1,4
+  1400, // 1,4
+  1450, // 1,45
+  1450, // 1,45
+  1500, // 1,5
+};
+
+uint16_t buck3_voltage_table[] = {
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1000, // 1
+  1100, // 1,1
+  1100, // 1,1
+  1100, // 1,1
+  1100, // 1,1
+  1200, // 1,2
+  1200, // 1,2
+  1200, // 1,2
+  1200, // 1,2
+  1300, // 1,3
+  1300, // 1,3
+  1300, // 1,3
+  1300, // 1,3
+  1400, // 1,4
+  1400, // 1,4
+  1400, // 1,4
+  1400, // 1,4
+  1500, // 1,5
+  1600, // 1,6
+  1700, // 1,7
+  1800, // 1,8
+  1900, // 1,9
+  2000, // 2
+  2100, // 2,1
+  2200, // 2,2
+  2300, // 2,3
+  2400, // 2,4
+  2500, // 2,5
+  2600, // 2,6
+  2700, // 2,7
+  2800, // 2,8
+  2900, // 2,9
+  3000, // 3
+  3100, // 3,1
+  3200, // 3,2
+  3300, // 3,3
+  3400, // 3,4
+};
+
+uint16_t buck4_voltage_table[] = {
+  600,
+  625,
+  650,
+  675,
+  700,
+  725,
+  750,
+  775,
+  800,
+  825,
+  850,
+  875,
+  900,
+  925,
+  950,
+  975,
+  1000,
+  1025,
+  1050,
+  1075,
+  1100,
+  1125,
+  1150,
+  1175,
+  1200,
+  1225,
+  1250,
+  1275,
+  1300,
+  1300,
+  1350,
+  1350,// 31  1,35
+  1400,// 32  1,40
+  1400,// 33  1,40
+  1450,// 34  1,45
+  1450,// 35  1,45
+  1500,// 36  1,5
+  1600,// 37  1,6
+  1700,// 38  1,7
+  1800,// 39  1,8
+  1900,// 40  1,9
+  2000,// 41  2,0
+  2100,// 42  2,1
+  2200,// 43  2,2
+  2300,// 44  2,3
+  2400,// 45  2,4
+  2500,// 46  2,5
+  2600,// 47  2,6
+  2700,// 48  2,7
+  2800,// 49  2,8
+  2900,// 50  2,9
+  3000,// 51  3,0
+  3100,// 52  3,1
+  3200,// 53  3,2
+  3300,// 54  3,3
+  3400,// 55  3,4
+  3500,// 56  3,5
+  3600,// 57  3,6
+  3700,// 58  3,7
+  3800,// 59  3,8
+  3900,// 60  3,9
+};
+
+uint16_t ldo1_voltage_table[] = {
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1800, // 1,8
+  1900, // 1,9
+  2000, // 2
+  2100, // 2,1
+  2200, // 2,2
+  2300, // 2,3
+  2400, // 2,4
+  2500, // 2,5
+  2600, // 2,6
+  2700, // 2,7
+  2800, // 2,8
+  2900, // 2,9
+  3000, // 3
+  3100, // 3,1
+  3200, // 3,2
+  3300, // 3,3
+};
+
+uint16_t ldo2_voltage_table[] = {
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1800, // 1,8
+  1900, // 1,9
+  2000, // 2
+  2100, // 2,1
+  2200, // 2,2
+  2300, // 2,3
+  2400, // 2,4
+  2500, // 2,5
+  2600, // 2,6
+  2700, // 2,7
+  2800, // 2,8
+  2900, // 2,9
+  3000, // 3
+  3100, // 3,1
+  3200, // 3,2
+  3300, // 3,3
+};
+
+uint16_t ldo3_voltage_table[] = {
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1800, // 1,8
+  1900, // 1,9
+  2000, // 2
+  2100, // 2,1
+  2200, // 2,2
+  2300, // 2,3
+  2400, // 2,4
+  2500, // 2,5
+  2600, // 2,6
+  2700, // 2,7
+  2800, // 2,8
+  2900, // 2,9
+  3000, // 3
+  3100, // 3,1
+  3200, // 3,2
+  3300, // 3,3
+  3300, // 3,3
+  3300, // 3,3
+  3300, // 3,3
+  3300, // 3,3
+  3300, // 3,3
+  3300, // 3,3
+  0xFFFF, // VREFDDR
+};
+
+
+uint16_t ldo5_voltage_table[] = {
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1700, // 1,7
+  1800, // 1,8
+  1900, // 1,9
+  2000, // 2
+  2100, // 2,1
+  2200, // 2,2
+  2300, // 2,3
+  2400, // 2,4
+  2500, // 2,5
+  2600, // 2,6
+  2700, // 2,7
+  2800, // 2,8
+  2900, // 2,9
+  3000, // 3
+  3100, // 3,1
+  3200, // 3,2
+  3300, // 3,3
+  3400, // 3,4
+  3500, // 3,5
+  3600, // 3,6
+  3700, // 3,7
+  3800, // 3,8
+  3900, // 3,9
+};
+
+uint16_t ldo6_voltage_table[] = {
+  900, // 0,9
+  1000, // 1,0
+  1100, // 1,1
+  1200, // 1,2
+  1300, // 1,3
+  1400, // 1,4
+  1500, // 1,5
+  1600, // 1,6
+  1700, // 1,7
+  1800, // 1,8
+  1900, // 1,9
+  2000, // 2
+  2100, // 2,1
+  2200, // 2,2
+  2300, // 2,3
+  2400, // 2,4
+  2500, // 2,5
+  2600, // 2,6
+  2700, // 2,7
+  2800, // 2,8
+  2900, // 2,9
+  3000, // 3
+  3100, // 3,1
+  3200, // 3,2
+  3300, // 3,3
+};
+
+uint16_t ldo4_voltage_table[] = {
+  3300, // 3,3
+};
+
+uint16_t vref_ddr_voltage_table[] = {
+  3300, // 3,3
+};
+
+/*
+  Table of Regulators in PMIC SoC
+*/
+static regul_struct regulators_table[] = {
+    {
+      .id                 = STPMU1_BUCK1,
+      .voltage_table      = buck1_voltage_table,
+      .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
+      .control_reg        = BUCK1_CONTROL_REG,
+      .low_power_reg      = BUCK1_PWRCTRL_REG,
+      .rank               = OTP_RANK_BUCK1,
+    },
+    {
+      .id                 = STPMU1_BUCK2,
+      .voltage_table      = buck2_voltage_table,
+      .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
+      .control_reg        = BUCK2_CONTROL_REG,
+      .low_power_reg      = BUCK2_PWRCTRL_REG,
+      .rank               = OTP_RANK_BUCK2,
+    },
+    {
+      .id                 = STPMU1_BUCK3,
+      .voltage_table      = buck3_voltage_table,
+      .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
+      .control_reg        = BUCK3_CONTROL_REG,
+      .low_power_reg      = BUCK3_PWRCTRL_REG,
+      .rank               = OTP_RANK_BUCK3,
+    },
+    {
+      .id                 = STPMU1_BUCK4,
+      .voltage_table      = buck4_voltage_table,
+      .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
+      .control_reg        = BUCK4_CONTROL_REG,
+      .low_power_reg      = BUCK4_PWRCTRL_REG,
+      .rank               = OTP_RANK_BUCK4,
+    },
+    {
+      .id                 = STPMU1_LDO1,
+      .voltage_table      = ldo1_voltage_table,
+      .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
+      .control_reg        = LDO1_CONTROL_REG,
+      .low_power_reg      = LDO1_PWRCTRL_REG,
+      .rank               = OTP_RANK_LDO1,
+    },
+    {
+      .id                 = STPMU1_LDO2,
+      .voltage_table      = ldo2_voltage_table,
+      .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
+      .control_reg        = LDO2_CONTROL_REG,
+      .low_power_reg      = LDO2_PWRCTRL_REG,
+      .rank               = OTP_RANK_LDO2,
+    },
+    {
+      .id                 = STPMU1_LDO3,
+      .voltage_table      = ldo3_voltage_table,
+      .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
+      .control_reg        = LDO3_CONTROL_REG,
+      .low_power_reg      = LDO3_PWRCTRL_REG,
+      .rank               = OTP_RANK_LDO3,
+    },
+    {
+      .id                 = STPMU1_LDO4,
+      .voltage_table      = ldo4_voltage_table,
+      .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
+      .control_reg        = LDO4_CONTROL_REG,
+      .low_power_reg      = LDO4_PWRCTRL_REG,
+      .rank               = OTP_RANK_LDO4,
+    },
+    {
+      .id                 = STPMU1_LDO5,
+      .voltage_table      = ldo5_voltage_table ,
+      .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
+      .control_reg        = LDO5_CONTROL_REG,
+      .low_power_reg      = LDO5_PWRCTRL_REG,
+      .rank               = OTP_RANK_LDO5,
+    },
+    {
+      .id                 = STPMU1_LDO6,
+      .voltage_table      = ldo6_voltage_table ,
+      .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
+      .control_reg        = LDO6_CONTROL_REG,
+      .low_power_reg      = LDO6_PWRCTRL_REG,
+      .rank               = OTP_RANK_LDO6,
+    },
+    {
+      .id                 = STPMU1_VREFDDR,
+      .voltage_table      = vref_ddr_voltage_table ,
+      .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
+      .control_reg        = VREF_DDR_CONTROL_REG,
+      .low_power_reg      = VREF_DDR_PWRCTRL_REG,
+      .rank               = OTP_RANK_VREFDDR,
+    },
+};
+
+#define MAX_REGUL  ARRAY_SIZE(regulators_table)
+static regul_struct *STPMU1_Get_Regulator_Data(PMIC_RegulId_TypeDef id)
+{
+    uint8_t i;
+
+    for (i = 0 ; i < MAX_REGUL ; i++ )
+    {
+        if (id == regulators_table[i].id)
+        {
+            return &regulators_table[i];
+        }
+    }
+    /* id not found */
+    Error_Handler();
+    return NULL;
+}
+
+static uint8_t STPMU1_Voltage_Find_Index(PMIC_RegulId_TypeDef id, uint16_t milivolts)
+{
+    regul_struct *regul = STPMU1_Get_Regulator_Data(id);
+    uint8_t i;
+    for ( i = 0 ; i < regul->voltage_table_size ; i++)
+    {
+        if ( regul->voltage_table[i] == milivolts ) 
+        {
+          LOG_D("idx:%d for %dmV\n\r", (int)i, (int)milivolts);
+          return i;
+        }
+    }
+    /* voltage not found */
+    Error_Handler();
+    return 0;
+}
+
+void STPMU1_Enable_Interrupt(PMIC_IRQn IRQn)
+{
+    uint8_t irq_reg , irq_reg_value ;
+
+    if (IRQn >= IRQ_NR)
+    {
+        return ;
+    }
+    /* IRQ register is IRQ Number divided by 8 */
+    irq_reg = IRQn >> 3 ;
+
+    /* value to be set in IRQ register corresponds to BIT(7-N) where N is the Interrupt id modulo 8 */
+    irq_reg_value = 1 << ( 7 - ( IRQn%8 ) );
+
+    /* Clear previous event stored in latch */
+    stpmu1_write_reg(ITCLEARLATCH1_REG+irq_reg, irq_reg_value );
+
+    /* Clear relevant mask to enable interrupt */
+    stpmu1_write_reg(ITCLEARMASK1_REG+irq_reg, irq_reg_value );
+
+}
+
+void STPMU1_Disable_Interrupt(PMIC_IRQn IRQn)
+{
+    uint8_t irq_reg , irq_reg_value ;
+
+    if (IRQn >= IRQ_NR)
+    {
+        return ;
+    }
+    /* IRQ register is IRQ Number divided by 8 */
+    irq_reg = IRQn >> 3 ;
+
+    /* value to be set in IRQ register corresponds to BIT(7-N) where N is the Interrupt id modulo 8 */
+    irq_reg_value = 1 << ( 7 - ( IRQn%8 ) );
+
+    /* Clear previous event stored in latch */
+    stpmu1_write_reg(ITCLEARLATCH1_REG+irq_reg, irq_reg_value );
+
+    /* Set relevant mask to disable interrupt */
+    stpmu1_write_reg(ITSETMASK1_REG+irq_reg, irq_reg_value );
+}
+
+void BSP_PMIC_INTn_Callback(PMIC_IRQn IRQn)
+{
+    switch (IRQn)
+    {
+    case IT_PONKEY_F:
+        LOG_I("IT_PONKEY_F");
+        break;
+
+    case IT_PONKEY_R:
+        LOG_I("IT_PONKEY_R");
+        break;
+
+    case IT_WAKEUP_F:
+        LOG_I("IT_WAKEUP_F");
+        break;
+
+    case IT_WAKEUP_R:
+        LOG_I("IT_WAKEUP_R");
+        break;
+
+    case IT_VBUS_OTG_F:
+        LOG_I("IT_VBUS_OTG_F");
+        break;
+
+    case IT_SWOUT_F:
+        LOG_I("IT_SWOUT_F");
+        break;
+
+    case IT_TWARN_R:
+        LOG_I("IT_TWARN_R");
+        break;
+
+    case IT_TWARN_F:
+        LOG_I("IT_TWARN_F");
+        break;
+
+    default:
+        LOG_I("%d",IRQn);
+        break;
+    }
+    LOG_I(" Interrupt received\n\r");
+}
+
+void STPMU1_INTn_Callback(PMIC_IRQn IRQn) 
+{
+    BSP_PMIC_INTn_Callback(IRQn);
+}
+
+void STPMU1_IrqHandler(void)
+{
+    uint8_t irq_reg,mask,latch_events,i;
+
+    for (irq_reg = 0 ; irq_reg < STM32_PMIC_NUM_IRQ_REGS ; irq_reg++)
+    {
+        /* Get latch events & active mask from register */
+        mask = stpmu1_read_reg(ITMASK1_REG+irq_reg);
+        latch_events = stpmu1_read_reg(ITLATCH1_REG+irq_reg) & ~mask ;
+
+        /* Go through all bits for each register */
+        for (i = 0 ; i < 8 ; i++ )
+        {
+            if ( latch_events & ( 1 << i ) )
+            {
+                /* Callback with parameter computes as "PMIC Interrupt" enum */
+                STPMU1_INTn_Callback( (PMIC_IRQn )(irq_reg*8 + (7-i)));
+            }
+        }
+        /* Clear events in appropriate register for the event with mask set */
+        stpmu1_write_reg(ITCLEARLATCH1_REG+irq_reg, latch_events );
+    }
+}
+
+static void STPMU1_Register_Update(uint8_t register_id, uint8_t value, uint8_t mask)
+{
+    uint8_t initial_value ;
+
+    initial_value = stpmu1_read_reg(register_id);
+
+    /* Clear bits to update */
+    initial_value &= ~mask;
+
+    /* Update appropriate bits*/
+    initial_value |= ( value & mask );
+
+    /* Send new value on I2C Bus */
+    stpmu1_write_reg(register_id, initial_value);
+}
+
+static void STPMU1_Regulator_Enable(PMIC_RegulId_TypeDef id)
+{
+    regul_struct *regul = STPMU1_Get_Regulator_Data(id);
+
+    STPMU1_Register_Update(regul->control_reg,BIT(0),BIT(0));
+}
+
+static void STPMU1_Regulator_Voltage_Set(PMIC_RegulId_TypeDef id,uint16_t milivolts)
+{
+    uint8_t voltage_index = STPMU1_Voltage_Find_Index(id,milivolts);
+    regul_struct *regul = STPMU1_Get_Regulator_Data(id);
+    STPMU1_Register_Update(regul->control_reg, voltage_index<<2 , 0xFC );
+}
+
+void BSP_PMIC_INTn_IRQHandler(void)
+{
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
+
+    STPMU1_IrqHandler();
+}
+
+static rt_err_t rt_hw_pmic_init_register(void)
+{
+    stpmu1_write_reg(MAIN_CONTROL_REG, 0x04);
+    stpmu1_write_reg(VIN_CONTROL_REG, 0xc0);
+    stpmu1_write_reg(USB_CONTROL_REG, 0x30);
+
+    stpmu1_write_reg(MASK_RESET_BUCK_REG, 0x04);
+    stpmu1_write_reg(MASK_RESET_LDO_REG, 0x00);
+    stpmu1_write_reg(MASK_RANK_BUCK_REG, 0x00);
+    stpmu1_write_reg(MASK_RANK_LDO_REG, 0x00);
+    stpmu1_write_reg(BUCK_PULL_DOWN_REG, 0x00);
+    stpmu1_write_reg(LDO14_PULL_DOWN_REG, 0x00);
+    stpmu1_write_reg(LDO56_PULL_DOWN_REG, 0x00);
+    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);
+
+  /* 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);
+
+  /* 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);
+
+  /* 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);
+
+  /* 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);
+
+  /* 1v8 */
+  STPMU1_Regulator_Voltage_Set(STPMU1_LDO6, 1800);
+  STPMU1_Regulator_Enable(STPMU1_LDO6);
+
+  STPMU1_Regulator_Enable(STPMU1_VREFDDR);
+
+    return RT_EOK;
+}
+
+static rt_err_t rt_hw_pmic_init(const char *bus_name)
+{
+    PMIC_IRQn irq;
+    
+    pmic_dev = rt_i2c_bus_device_find(bus_name);
+    
+    if (pmic_dev == RT_NULL)
+    {
+        LOG_E("%s bus not found\n", bus_name);
+        return -RT_ERROR;
+    }
+    
+    if (stpmu1_read_reg(VERSION_STATUS_REG) != PMIC_VERSION_ID)
+    {
+        return -RT_EIO;
+    }
+
+    STPMU1_Enable_Interrupt(IT_PONKEY_R);
+    STPMU1_Enable_Interrupt(IT_PONKEY_F);
+    /* enable all irqs  */
+    for (irq = IT_SWOUT_R; irq < IRQ_NR; irq++) 
+    {
+        STPMU1_Enable_Interrupt(irq);
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t rt_hw_pmic_deinit(void)
+{
+    BSP_PMIC_MspDeInit();
+    
+    return RT_EOK;
+}
+
+static int pmic_init(void)
+{
+    rt_err_t result = RT_EOK;
+    
+    if (IS_ENGINEERING_BOOT_MODE())
+    {
+        BSP_PMIC_MspInit();
+        
+        result = rt_hw_pmic_init("i2c3");
+        if(result != RT_EOK)
+        {
+            LOG_D("stpmic init failed: %02x", result);
+            rt_hw_pmic_deinit();
+            return RT_ERROR;
+        }
+        
+        rt_hw_pmic_init_register();
+    }
+    
+    LOG_I("stpmic init success!");
+        
+    return RT_EOK;
+}
+
+INIT_PREV_EXPORT(pmic_init);
+
+#endif

+ 287 - 87
bsp/stm32/stm32mp157a-st-ev1/board/ports/stpmic.h → bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pmic.h

@@ -1,6 +1,6 @@
 /**
   ******************************************************************************
-  * @file    stm32mp15xx__stpmic1.h
+  * @file    stm32mp15xx_eval_stpmic1.h
   * @author  MCD Application Team
   * @brief   stpmu driver functions used for ST internal validation
   ******************************************************************************
@@ -25,80 +25,306 @@
 extern "C" {
 #endif
 
-/* Includes ------------------------------------------------------------------*/
 #include "stm32mp1xx_hal.h"
 
 /* Exported types ------------------------------------------------------------*/
 typedef enum
 {
-  STPMU1_BUCK1=1,
-  STPMU1_BUCK2,
-  STPMU1_BUCK3,
-  STPMU1_BUCK4,
-  STPMU1_LDO1,
-  STPMU1_LDO2,
-  STPMU1_LDO3,
-  STPMU1_LDO4,
-  STPMU1_LDO5,
-  STPMU1_LDO6,
-  STPMU1_VREFDDR,
+    STPMU1_BUCK1=1,
+    STPMU1_BUCK2,
+    STPMU1_BUCK3,
+    STPMU1_BUCK4,
+    STPMU1_LDO1,
+    STPMU1_LDO2,
+    STPMU1_LDO3,
+    STPMU1_LDO4,
+    STPMU1_LDO5,
+    STPMU1_LDO6,
+    STPMU1_VREFDDR,
 }PMIC_RegulId_TypeDef;
 
 /* IRQ definitions */
 typedef enum {
-
 /* Interrupt Register 1 (0x50 for latch) */
-IT_SWOUT_R,
-IT_SWOUT_F,
-IT_VBUS_OTG_R,
-IT_VBUS_OTG_F,
-IT_WAKEUP_R,
-IT_WAKEUP_F,
-IT_PONKEY_R,
-IT_PONKEY_F,
-
+    IT_SWOUT_R,
+    IT_SWOUT_F,
+    IT_VBUS_OTG_R,
+    IT_VBUS_OTG_F,
+    IT_WAKEUP_R,
+    IT_WAKEUP_F,
+    IT_PONKEY_R,
+    IT_PONKEY_F,
 /* Interrupt Register 2 (0x51 for latch) */
-IT_OVP_BOOST,
-IT_OCP_BOOST,
-IT_OCP_SWOUT,
-IT_OCP_OTG,
-IT_CURLIM_BUCK4,
-IT_CURLIM_BUCK3,
-IT_CURLIM_BUCK2,
-IT_CURLIM_BUCK1,
-
+    IT_OVP_BOOST,
+    IT_OCP_BOOST,
+    IT_OCP_SWOUT,
+    IT_OCP_OTG,
+    IT_CURLIM_BUCK4,
+    IT_CURLIM_BUCK3,
+    IT_CURLIM_BUCK2,
+    IT_CURLIM_BUCK1,
 /* Interrupt Register 3 (0x52 for latch) */
-IT_SHORT_SWOUT,
-IT_SHORT_SWOTG,
-IT_CURLIM_LDO6,
-IT_CURLIM_LDO5,
-IT_CURLIM_LDO4,
-IT_CURLIM_LDO3,
-IT_CURLIM_LDO2,
-IT_CURLIM_LDO1,
-
+    IT_SHORT_SWOUT,
+    IT_SHORT_SWOTG,
+    IT_CURLIM_LDO6,
+    IT_CURLIM_LDO5,
+    IT_CURLIM_LDO4,
+    IT_CURLIM_LDO3,
+    IT_CURLIM_LDO2,
+    IT_CURLIM_LDO1,
 /* Interrupt Register 3 (0x52 for latch) */
-IT_SWIN_R,
-IT_SWIN_F,
-IT_RESERVED_1,
-IT_RESERVED_2,
-IT_VINLOW_R,
-IT_VINLOW_F,
-IT_TWARN_R,
-IT_TWARN_F,
-
-IRQ_NR,
+    IT_SWIN_R,
+    IT_SWIN_F,
+    IT_RESERVED_1,
+    IT_RESERVED_2,
+    IT_VINLOW_R,
+    IT_VINLOW_F,
+    IT_TWARN_R,
+    IT_TWARN_F,
+    IRQ_NR,
 } PMIC_IRQn;
 
-/**
-  * @}
-  */ 
-
-/** @defgroup STM32MP15XX_EVAL_STPMU_Exported_Constants Exported Constants
-  * @{
-  */ 
-
-/* Exported constants --------------------------------------------------------*/
+/* Private typedef -----------------------------------------------------------*/
+typedef struct {
+  PMIC_RegulId_TypeDef id;
+  uint16_t *voltage_table;
+  uint8_t  voltage_table_size;
+  uint8_t  control_reg;
+  uint8_t  low_power_reg;
+  uint8_t  rank ;
+  uint8_t  nvm_info ;
+} regul_struct;
+
+
+/* Those define should reflect NVM_USER section
+ * For ES Eval Configuration this is specified as
+ * 	0xF7,
+ 0x92,
+ 0xC0,
+ 0x02,
+ 0xFA,
+ 0x30,
+ 0x00,
+ 0x33,
+ * */
+#define NVM_SECTOR3_REGISTER_0  0xF7
+#define NVM_SECTOR3_REGISTER_1  0x92
+#define NVM_SECTOR3_REGISTER_2  0xC0
+#define NVM_SECTOR3_REGISTER_3  0x02
+#define NVM_SECTOR3_REGISTER_4  0xFA
+#define NVM_SECTOR3_REGISTER_5  0x30
+#define NVM_SECTOR3_REGISTER_6  0x00
+#define NVM_SECTOR3_REGISTER_7  0x33
+
+/* nvm_vinok_hyst: VINOK hysteresis voltage
+ 00: 200mV
+ 01: 300mV
+ 10: 400mV
+ 11: 500mV
+ *
+ * nvm_vinok: VINOK threshold voltage
+ 00:  3.1v
+ 01:  3.3v
+ 10:  3.5v
+ 11:  4.5v
+ Otp_ldo4_forced :
+ 0:  LDO4 ranks following OTP_RANK_LDO4<1:0>
+ if VBUS_OTG or SWOUT is turn ON condition
+ 1:  LDO4 follows normal ranking procedure
+
+ nvm_longkeypress:
+ 0:  Turn OFF on long key press inactive
+ 1:  Turn OFF on long key press active
+
+ nvm_autoturnon:
+ 0:  PMIC does not start automatically on VIN rising
+ 1:  PMIC starts automatically on VIN rising
+
+ nvm_cc_keepoff :
+ 0:  short circuit does not turn OFF PMIC
+ 1:  short circuit turn OFF PMIC and keep it OFF till CC_flag is reset
+
+ *
+ */
+#define OTP_VINOK_HYST  	((NVM_SECTOR3_REGISTER_0 & 0xC0) >> 6) 	// nvm_vinok_hyst
+#define OTP_VINOK		  	((NVM_SECTOR3_REGISTER_0 & 0x30) >> 4) 	// nvm_vinok
+#define OTP_LDO4_FORCED     ((NVM_SECTOR3_REGISTER_0 & 0x08) >> 3) 	// Otp_ldo4_forced
+#define OTP_LONGKEYPRESSED  ((NVM_SECTOR3_REGISTER_0 & 0x04) >> 2)	// nvm_longkeypress
+#define OTP_AUTOTURNON  	((NVM_SECTOR3_REGISTER_0 & 0x02) >> 1)	// nvm_autoturnon
+#define OTP_CC_KEEPOFF  	((NVM_SECTOR3_REGISTER_0 & 0x01))		// nvm_cc_keepoff
+
+/*
+ * nvm_rank_buck4:
+ 00: rank0
+ 01: rank1
+ 10: rank2
+ 11: rank3
+ nvm_rank_buck3:
+ 00:  rank0
+ 01:  rank1
+ 10:  rank2
+ 11:  rank3
+ nvm_rank_buck2:
+ 00:  rank0
+ 01:  rank1
+ 10:  rank2
+ 11:  rank3
+ nvm_rank_buck1:
+ 00:  rank0
+ 01:  rank1
+ 10:  rank2
+ 11:  rank3
+ *
+ */
+#define OTP_RANK_BUCK4  	((NVM_SECTOR3_REGISTER_1 & 0xC0) >> 6) 	// nvm_rank_buck4
+#define OTP_RANK_BUCK3		((NVM_SECTOR3_REGISTER_1 & 0x30) >> 4) 	// nvm_rank_buck3
+#define OTP_RANK_BUCK2     	((NVM_SECTOR3_REGISTER_1 & 0x0C) >> 2) 	// nvm_rank_buck2
+#define OTP_RANK_BUCK1  	((NVM_SECTOR3_REGISTER_1 & 0x03))		// nvm_rank_buck1
+
+
+/*
+ * nvm_rank_ldo4:
+ 00: rank0
+ 01: rank1
+ 10: rank2
+ 11: rank3
+ nvm_rank_ldo3:
+ 00:  rank0
+ 01:  rank1
+ 10:  rank2
+ 11:  rank3
+ nvm_rank_ldo2:
+ 00:  rank0
+ 01:  rank1
+ 10:  rank2
+ 11:  rank3
+ nvm_rank_ldo1:
+ 00:  rank0
+ 01:  rank1
+ 10:  rank2
+ 11:  rank3
+ *
+ */
+#define OTP_RANK_LDO4  		((NVM_SECTOR3_REGISTER_2 & 0xC0) >> 6) 	// nvm_rank_ldo4
+#define OTP_RANK_LDO3		((NVM_SECTOR3_REGISTER_2 & 0x30) >> 4) 	// nvm_rank_ldo3
+#define OTP_RANK_LDO2     	((NVM_SECTOR3_REGISTER_2 & 0x0C) >> 2) 	// nvm_rank_ldo2
+#define OTP_RANK_LDO1  		((NVM_SECTOR3_REGISTER_2 & 0x03))		// nvm_rank_ldo1
+
+/*
+ * nvm_clamp_output_buck: Clamp output value to 1.3V max
+ 0: output_buck4<5:0> not clamped
+ 1: output_buck4<5:0> to b011100(1.3V)
+
+ nvm_bypass_mode_ldo3: LDO3 forced bypass mode
+ 0: LDO3 not in bypass mode
+ 1: LDO3 in bypass mode
+
+ nvm_rank_vrefddr:
+ 00:  rank0
+ 01:  rank1
+ 10:  rank2
+ 11:  rank3
+
+ nvm_rank_ldo6:
+ 00:  rank0
+ 01:  rank1
+ 10:  rank2
+ 11:  rank3
+
+nvm_rank_ldo5:
+ 00:  rank0
+ 01:  rank1
+ 10:  rank2
+ 11:  rank3
+ *
+ */
+#define OTP_CLAMP_OUTPUT_BUCK4  ((NVM_SECTOR3_REGISTER_3 & 0x80) >> 7) 	// nvm_clamp_output_buck4
+#define OTP_BYPASS_MODE_LDO3  	((NVM_SECTOR3_REGISTER_3 & 0x40) >> 6) 	// nvm_bypass_mode_ldo3
+#define OTP_RANK_VREFDDR		((NVM_SECTOR3_REGISTER_3 & 0x30) >> 4) 	// nvm_rank_vrefddr
+#define OTP_RANK_LDO6     		((NVM_SECTOR3_REGISTER_3 & 0x0C) >> 2) 	// nvm_rank_ldo6
+#define OTP_RANK_LDO5  			((NVM_SECTOR3_REGISTER_3 & 0x03))		// nvm_rank_ldo5
+
+/*
+ * nvm_output_buck4: Buck4 default output selection
+ 00:  1.15V
+ 01:  1.2V
+ 10:  1.8V
+ 11:  3.3V
+ nvm_output_buck3: Buck3 default output selection
+ 00:  1.2V
+ 01:  1.8V
+ 10:  3.0V
+ 11:  3.3V
+ nvm_output_buck2: Buck2 default output selection
+ 00:  1.1V
+ 01:  1.2V
+ 10:  1.35V
+ 11:  1.5V
+ nvm_output_buck1: Buck1 default output selection
+ 00:  1.1V
+ 01:  1.15V
+ 10:  1.2V
+ 11:  1.25V
+ *
+ */
+#define OTP_OUTPUT_BUCK4  		((NVM_SECTOR3_REGISTER_4 & 0xC0) >> 6) 	// nvm_output_buck4
+#define OTP_OUTPUT_BUCK3		((NVM_SECTOR3_REGISTER_4 & 0x30) >> 4) 	// nvm_output_buck3
+#define OTP_OUTPUT_BUCK2     	((NVM_SECTOR3_REGISTER_4 & 0x0C) >> 2) 	// nvm_output_buck2
+#define OTP_OUTPUT_BUCK1  		((NVM_SECTOR3_REGISTER_4 & 0x03))		// nvm_output_buck1
+
+/*
+ * [7]	OTP_SWOFF_BY_BOOST_OVP:
+ 0 -> SWOUT will not turnoff bu boost OVP
+ 1 -> SWOUT will be turnoff by BOOST OVP
+
+ [6]	reserved
+
+ [5:4]	nvm_output_ldo3: LDO3 default output selection
+ 00:  1.8V
+ 01:  2.5V
+ 10:  3.3V
+ 11:  output_buck2<4:0>/2 (VTT termination for DDR3 x32, Analog divider implemented in Analog)
+
+ [3:2]	nvm_output_ldo2: LDO2 default output selection
+ 00: 1.8V
+ 01: 2.5V
+ 10: 2.9V
+ 11: 3.3V
+
+ [1:0]	nvm_output_ldo1: LDO1 default output selection
+ 00: 1.8V
+ 01: 2.5V
+ 10: 2.9V
+ 11: 3.3V
+
+ *
+ */
+#define OTP_SWOFF_BY_BOOST_OVP  ((NVM_SECTOR3_REGISTER_5 & 0x80) >> 7) 	// OTP_SWOFF_BY_BOOST_OVP
+#define OTP_OUTPUT_LDO3			((NVM_SECTOR3_REGISTER_5 & 0x30) >> 4) 	// nvm_output_ldo3
+#define OTP_OUTPUT_LDO2     	((NVM_SECTOR3_REGISTER_5 & 0x0C) >> 2) 	// nvm_output_ldo2
+#define OTP_OUTPUT_LDO1  		((NVM_SECTOR3_REGISTER_5 & 0x03))		// nvm_output_ldo1
+
+/*
+ * 	[7:4]	reserved
+ *
+ [3:2]	nvm_output_ldo6: LDO6 default output selection
+ 00:  1.0V
+ 01:  1.2V
+ 10:  1.8V
+ 11:  3.3V
+
+ [1:0]	nvm_output_ldo5: LDO5 default output selection
+ 00:  1.8V
+ 01:  2.5V
+ 10:  2.9V
+ 11 :  3.3V
+ *
+ */
+
+#define OTP_OUTPUT_LDO6     	((NVM_SECTOR3_REGISTER_6 & 0x0C) >> 2) 	// nvm_output_ldo6
+#define OTP_OUTPUT_LDO5  		((NVM_SECTOR3_REGISTER_6 & 0x03))		// nvm_output_ldo5
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 #define BIT(_x)  (1<<(_x))
 #define STM32_PMIC_NUM_IRQ_REGS       4
 
@@ -280,33 +506,7 @@ IRQ_NR,
 
 #define PMIC_VERSION_ID             0x10
 
-#define NVM_SECTOR3_REGISTER_7      0x33
-//#define STPMU1_I2C_ADDRESS          ((NVM_SECTOR3_REGISTER_7 & 0x7F) << 1 )
-
-/**
-  * @}
-  */ 
-  
-/** @defgroup STM32MP15XX_EVAL_STPMU_Exported_Functions Exported Functions
-  * @{
-  */
-
-/* Exported functions --------------------------------------------------------*/
-uint8_t STPMU1_Register_Read(uint8_t register_id);
-void STPMU1_Register_Write(uint8_t register_id, uint8_t value);
-void STPMU1_Register_Update(uint8_t register_id, uint8_t value, uint8_t mask);
-void STPMU1_Enable_Interrupt(PMIC_IRQn IRQn);
-void STPMU1_Disable_Interrupt(PMIC_IRQn IRQn);
-void STPMU1_Regulator_Enable(PMIC_RegulId_TypeDef id);
-void STPMU1_Regulator_Disable(PMIC_RegulId_TypeDef id);
-uint8_t STPMU1_Is_Regulator_Enabled(PMIC_RegulId_TypeDef id);
-void STPMU1_Regulator_Voltage_Set(PMIC_RegulId_TypeDef id,uint16_t milivolts);
-uint32_t BSP_PMIC_Init(void);
-uint32_t BSP_PMIC_DeInit(void);
-uint32_t BSP_PMIC_Is_Device_Ready(void);
-uint32_t BSP_PMIC_InitRegulators (void);
-__weak void BSP_PMIC_INTn_Callback(PMIC_IRQn IRQn);
-
+#define STPMU1_I2C_ADDRESS          (NVM_SECTOR3_REGISTER_7 & 0x7F)
 
 #ifdef __cplusplus
 }

+ 0 - 103
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_wwdg.c

@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author            Notes
- * 2020-06-18     thread-liu        the first version
- */
-
-#include <board.h>
-
-#if defined(BSP_USING_WWDG)
-#include "drv_config.h"
-#include <string.h>
-#include <stdlib.h>
-
-//#define DRV_DEBUG
-#define LOG_TAG             "drv.wwg"
-#include <drv_log.h>
-
-#define LED5_PIN  GET_PIN(A, 14)
-
-WWDG_HandleTypeDef hwwdg1;  
-
-void WWDG1_IRQHandler(void)
-{
-    /* enter interrupt */
-    rt_interrupt_enter();
-    
-    HAL_WWDG_IRQHandler(&hwwdg1);
-    
-    /* leave interrupt */
-    rt_interrupt_leave();
-}
-
-void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef* hwwdg)
-{
-    static unsigned char led_value = 0x00;
-    
-    led_value = !led_value;
-    
-    if(hwwdg->Instance==WWDG1)
-    {
-        HAL_WWDG_Refresh(&hwwdg1);
-        rt_pin_write(LED5_PIN, led_value);
-    }
-}
-
-static void wwdg_init()
-{
-    rt_pin_mode(LED5_PIN, PIN_MODE_OUTPUT);
-        
-    hwwdg1.Instance       = WWDG1;
-    hwwdg1.Init.Prescaler = WWDG_PRESCALER_8;
-    hwwdg1.Init.Window    = 0X5F;
-    hwwdg1.Init.Counter   = 0x7F;
-    hwwdg1.Init.EWIMode   = WWDG_EWI_ENABLE;
-      
-    if (HAL_WWDG_Init(&hwwdg1) != HAL_OK)
-    {
-        Error_Handler();
-    }
-}
-
-static void wwdg_control(uint8_t pre_value)
-{
-    if(pre_value > 7)
-    {
-       pre_value = 7; 
-    }
-    hwwdg1.Instance->CFR &= ~(7 << 11);     /* clear WDGTB[2:0] */
-    hwwdg1.Instance->CFR |= pre_value << 11; /* set WDGTB[2:0] */	
-}
-
-static int wwdg_sample(int argc, char *argv[])
-{
-    if (argc > 1)
-    {
-        if (!strcmp(argv[1], "run"))
-        { 
-            wwdg_init();
-        }
-        else if (!strcmp(argv[1], "set"))
-        {
-            if (argc > 2)
-            {
-                wwdg_control(atoi(argv[2]));
-            }     
-        }
-    }
-    else
-    {
-        rt_kprintf("Usage:\n");
-        rt_kprintf("wwdg_sample run            - open wwdg, when feed wwdg in wwdg irq, the LD5 will blink\n");
-        rt_kprintf("wwdg_sample set            - set the wwdg prescaler, wwdg_sample set [0 - 7]\n");
-    }
-
-    return RT_EOK;
-}
-MSH_CMD_EXPORT(wwdg_sample, window watch dog sample);
-
-#endif

+ 0 - 1225
bsp/stm32/stm32mp157a-st-ev1/board/ports/stpmic.c

@@ -1,1225 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stpmic.c
-  * @author  MCD Application Team
-  * @brief   This sample code provides hardware semaphore using HSEM for 
-  *          synchronization and mutual exclusion between heterogeneous processors 
-  *          and those not operating under a single, shared operating system.  
-  ******************************************************************************
-  * @attention
-  *
-  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
-  * All rights reserved.</center></h2>
-  *
-  * This software component is licensed by ST under BSD 3-Clause license,
-  * the "License"; You may not use this file except in compliance with the
-  * License. You may obtain a copy of the License at:
-  *                        opensource.org/licenses/BSD-3-Clause
-  *
-  ******************************************************************************
-  */
-
-#include <board.h>
-#include <stpmic.h>
-#include <string.h>
-#include "drv_hard_i2c.h"
-
-/* Definition of PMIC <=> stm32mp1 Signals */
-#define PMIC_INTn_PIN               GPIO_PIN_0
-#define PMIC_INTn_PORT              GPIOA
-#define PMIC_INTn_CLK_ENABLE()      __HAL_RCC_GPIOA_CLK_ENABLE()
-#define PMIC_INTn_CLK_DISABLE()     __HAL_RCC_GPIOA_CLK_DISABLE()
-
-#define BSP_PMIC_PWRCTRL_PIN_Assert()   HAL_GPIO_WritePin(PMIC_PWRCTRL_PORT, PMIC_PWRCTRL_PIN, GPIO_PIN_RESET);
-#define BSP_PMIC_PWRCTRL_PIN_Pull()     HAL_GPIO_WritePin(PMIC_PWRCTRL_PORT, PMIC_PWRCTRL_PIN, GPIO_PIN_SET);
-
-/**
-  * @}
-  */ 
-  
- /** @defgroup STM32MP15XX_EVAL_STPMU_Private_Defines Private Defines
-  * @{
-  */ 
-/* Private typedef -----------------------------------------------------------*/
-typedef struct {
-  PMIC_RegulId_TypeDef id;
-  uint16_t *voltage_table;
-  uint8_t  voltage_table_size;
-  uint8_t  control_reg;
-  uint8_t  low_power_reg;
-  uint8_t  rank ;
-  uint8_t  nvm_info ;
-} regul_struct;
-
-/* Private define ------------------------------------------------------------*/
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-/* Those define should reflect NVM_USER section
- * For ES Eval Configuration this is specified as
- * 	0xF7,
- 0x92,
- 0xC0,
- 0x02,
- 0xFA,
- 0x30,
- 0x00,
- 0x33,
- * */
-#define NVM_SECTOR3_REGISTER_0  0xF7
-#define NVM_SECTOR3_REGISTER_1  0x92
-#define NVM_SECTOR3_REGISTER_2  0xC0
-#define NVM_SECTOR3_REGISTER_3  0x02
-#define NVM_SECTOR3_REGISTER_4  0xFA
-#define NVM_SECTOR3_REGISTER_5  0x30
-#define NVM_SECTOR3_REGISTER_6  0x00
-#define NVM_SECTOR3_REGISTER_7  0x33
-
-/* nvm_vinok_hyst: VINOK hysteresis voltage
- 00: 200mV
- 01: 300mV
- 10: 400mV
- 11: 500mV
- *
- * nvm_vinok: VINOK threshold voltage
- 00:  3.1v
- 01:  3.3v
- 10:  3.5v
- 11:  4.5v
- Otp_ldo4_forced :
- 0:  LDO4 ranks following OTP_RANK_LDO4<1:0>
- if VBUS_OTG or SWOUT is turn ON condition
- 1:  LDO4 follows normal ranking procedure
-
- nvm_longkeypress:
- 0:  Turn OFF on long key press inactive
- 1:  Turn OFF on long key press active
-
- nvm_autoturnon:
- 0:  PMIC doesn’t start automatically on VIN rising
- 1:  PMIC starts automatically on VIN rising
-
- nvm_cc_keepoff :
- 0:  short circuit does not turn OFF PMIC
- 1:  short circuit turn OFF PMIC and keep it OFF till CC_flag is reset
-
- *
- */
-#define OTP_VINOK_HYST  	((NVM_SECTOR3_REGISTER_0 & 0xC0) >> 6) 	// nvm_vinok_hyst
-#define OTP_VINOK		  	((NVM_SECTOR3_REGISTER_0 & 0x30) >> 4) 	// nvm_vinok
-#define OTP_LDO4_FORCED     ((NVM_SECTOR3_REGISTER_0 & 0x08) >> 3) 	// Otp_ldo4_forced
-#define OTP_LONGKEYPRESSED  ((NVM_SECTOR3_REGISTER_0 & 0x04) >> 2)	// nvm_longkeypress
-#define OTP_AUTOTURNON  	((NVM_SECTOR3_REGISTER_0 & 0x02) >> 1)	// nvm_autoturnon
-#define OTP_CC_KEEPOFF  	((NVM_SECTOR3_REGISTER_0 & 0x01))		// nvm_cc_keepoff
-
-/*
- * nvm_rank_buck4:
- 00: rank0
- 01: rank1
- 10: rank2
- 11: rank3
- nvm_rank_buck3:
- 00:  rank0
- 01:  rank1
- 10:  rank2
- 11:  rank3
- nvm_rank_buck2:
- 00:  rank0
- 01:  rank1
- 10:  rank2
- 11:  rank3
- nvm_rank_buck1:
- 00:  rank0
- 01:  rank1
- 10:  rank2
- 11:  rank3
- *
- */
-#define OTP_RANK_BUCK4  	((NVM_SECTOR3_REGISTER_1 & 0xC0) >> 6) 	// nvm_rank_buck4
-#define OTP_RANK_BUCK3		((NVM_SECTOR3_REGISTER_1 & 0x30) >> 4) 	// nvm_rank_buck3
-#define OTP_RANK_BUCK2     	((NVM_SECTOR3_REGISTER_1 & 0x0C) >> 2) 	// nvm_rank_buck2
-#define OTP_RANK_BUCK1  	((NVM_SECTOR3_REGISTER_1 & 0x03))		// nvm_rank_buck1
-
-
-/*
- * nvm_rank_ldo4:
- 00: rank0
- 01: rank1
- 10: rank2
- 11: rank3
- nvm_rank_ldo3:
- 00:  rank0
- 01:  rank1
- 10:  rank2
- 11:  rank3
- nvm_rank_ldo2:
- 00:  rank0
- 01:  rank1
- 10:  rank2
- 11:  rank3
- nvm_rank_ldo1:
- 00:  rank0
- 01:  rank1
- 10:  rank2
- 11:  rank3
- *
- */
-#define OTP_RANK_LDO4  		((NVM_SECTOR3_REGISTER_2 & 0xC0) >> 6) 	// nvm_rank_ldo4
-#define OTP_RANK_LDO3		((NVM_SECTOR3_REGISTER_2 & 0x30) >> 4) 	// nvm_rank_ldo3
-#define OTP_RANK_LDO2     	((NVM_SECTOR3_REGISTER_2 & 0x0C) >> 2) 	// nvm_rank_ldo2
-#define OTP_RANK_LDO1  		((NVM_SECTOR3_REGISTER_2 & 0x03))		// nvm_rank_ldo1
-
-/*
- * nvm_clamp_output_buck: Clamp output value to 1.3V max
- 0: output_buck4<5:0> not clamped
- 1: output_buck4<5:0> to b011100(1.3V)
-
- nvm_bypass_mode_ldo3: LDO3 forced bypass mode
- 0: LDO3 not in bypass mode
- 1: LDO3 in bypass mode
-
- nvm_rank_vrefddr:
- 00:  rank0
- 01:  rank1
- 10:  rank2
- 11:  rank3
-
- nvm_rank_ldo6:
- 00:  rank0
- 01:  rank1
- 10:  rank2
- 11:  rank3
-
-nvm_rank_ldo5:
- 00:  rank0
- 01:  rank1
- 10:  rank2
- 11:  rank3
- *
- */
-#define OTP_CLAMP_OUTPUT_BUCK4  ((NVM_SECTOR3_REGISTER_3 & 0x80) >> 7) 	// nvm_clamp_output_buck4
-#define OTP_BYPASS_MODE_LDO3  	((NVM_SECTOR3_REGISTER_3 & 0x40) >> 6) 	// nvm_bypass_mode_ldo3
-#define OTP_RANK_VREFDDR		((NVM_SECTOR3_REGISTER_3 & 0x30) >> 4) 	// nvm_rank_vrefddr
-#define OTP_RANK_LDO6     		((NVM_SECTOR3_REGISTER_3 & 0x0C) >> 2) 	// nvm_rank_ldo6
-#define OTP_RANK_LDO5  			((NVM_SECTOR3_REGISTER_3 & 0x03))		// nvm_rank_ldo5
-
-/*
- * nvm_output_buck4: Buck4 default output selection
- 00:  1.15V
- 01:  1.2V
- 10:  1.8V
- 11:  3.3V
- nvm_output_buck3: Buck3 default output selection
- 00:  1.2V
- 01:  1.8V
- 10:  3.0V
- 11:  3.3V
- nvm_output_buck2: Buck2 default output selection
- 00:  1.1V
- 01:  1.2V
- 10:  1.35V
- 11:  1.5V
- nvm_output_buck1: Buck1 default output selection
- 00:  1.1V
- 01:  1.15V
- 10:  1.2V
- 11:  1.25V
- *
- */
-#define OTP_OUTPUT_BUCK4  		((NVM_SECTOR3_REGISTER_4 & 0xC0) >> 6) 	// nvm_output_buck4
-#define OTP_OUTPUT_BUCK3		((NVM_SECTOR3_REGISTER_4 & 0x30) >> 4) 	// nvm_output_buck3
-#define OTP_OUTPUT_BUCK2     	((NVM_SECTOR3_REGISTER_4 & 0x0C) >> 2) 	// nvm_output_buck2
-#define OTP_OUTPUT_BUCK1  		((NVM_SECTOR3_REGISTER_4 & 0x03))		// nvm_output_buck1
-
-/*
- * [7]	OTP_SWOFF_BY_BOOST_OVP:
- 0 -> SWOUT will not turnoff bu boost OVP
- 1 -> SWOUT will be turnoff by BOOST OVP
-
- [6]	reserved
-
- [5:4]	nvm_output_ldo3: LDO3 default output selection
- 00:  1.8V
- 01:  2.5V
- 10:  3.3V
- 11:  output_buck2<4:0>/2 (VTT termination for DDR3 x32, Analog divider implemented in Analog)
-
- [3:2]	nvm_output_ldo2: LDO2 default output selection
- 00: 1.8V
- 01: 2.5V
- 10: 2.9V
- 11: 3.3V
-
- [1:0]	nvm_output_ldo1: LDO1 default output selection
- 00: 1.8V
- 01: 2.5V
- 10: 2.9V
- 11: 3.3V
-
- *
- */
-#define OTP_SWOFF_BY_BOOST_OVP  ((NVM_SECTOR3_REGISTER_5 & 0x80) >> 7) 	// OTP_SWOFF_BY_BOOST_OVP
-#define OTP_OUTPUT_LDO3			((NVM_SECTOR3_REGISTER_5 & 0x30) >> 4) 	// nvm_output_ldo3
-#define OTP_OUTPUT_LDO2     	((NVM_SECTOR3_REGISTER_5 & 0x0C) >> 2) 	// nvm_output_ldo2
-#define OTP_OUTPUT_LDO1  		((NVM_SECTOR3_REGISTER_5 & 0x03))		// nvm_output_ldo1
-
-/*
- * 	[7:4]	reserved
- *
- [3:2]	nvm_output_ldo6: LDO6 default output selection
- 00:  1.0V
- 01:  1.2V
- 10:  1.8V
- 11:  3.3V
-
- [1:0]	nvm_output_ldo5: LDO5 default output selection
- 00:  1.8V
- 01:  2.5V
- 10:  2.9V
- 11 :  3.3V
- *
- */
-
-#define OTP_OUTPUT_LDO6     	((NVM_SECTOR3_REGISTER_6 & 0x0C) >> 2) 	// nvm_output_ldo6
-#define OTP_OUTPUT_LDO5  		((NVM_SECTOR3_REGISTER_6 & 0x03))		// nvm_output_ldo5
-
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* I2C handler declaration */
-I2C_HandleTypeDef I2cHandle;
-extern I2C_HandleTypeDef hI2c4;
-
-uint16_t buck1_voltage_table[] = {
-  600,
-  625,
-  650,
-  675,
-  700,
-  725,
-  750,
-  775,
-  800,
-  825,
-  850,
-  875,
-  900,
-  925,
-  950,
-  975,
-  1000,
-  1025,
-  1050,
-  1075,
-  1100,
-  1125,
-  1150,
-  1175,
-  1200,
-  1225,
-  1250,
-  1275,
-  1300,
-  1325,
-  1350,
-  1350,// 31  1,35stm32mp15xx_eval_stpmu1.c
-};
-
-uint16_t buck2_voltage_table[] = {
-  1000, // 1
-  1000, //
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1050, // 1,05
-  1050, // 1,05
-  1100, // 1,1
-  1100, // 1,1
-  1150, // 1,15
-  1150, // 1,15
-  1200, // 1,2
-  1200, // 1,2
-  1250, // 1,25
-  1250, // 1,25
-  1300, // 1,3
-  1300, // 1,3
-  1350, // 1,35
-  1350, // 1,35
-  1400, // 1,4
-  1400, // 1,4
-  1450, // 1,45
-  1450, // 1,45
-  1500, // 1,5
-};
-
-uint16_t buck3_voltage_table[] = {
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1000, // 1
-  1100, // 1,1
-  1100, // 1,1
-  1100, // 1,1
-  1100, // 1,1
-  1200, // 1,2
-  1200, // 1,2
-  1200, // 1,2
-  1200, // 1,2
-  1300, // 1,3
-  1300, // 1,3
-  1300, // 1,3
-  1300, // 1,3
-  1400, // 1,4
-  1400, // 1,4
-  1400, // 1,4
-  1400, // 1,4
-  1500, // 1,5
-  1600, // 1,6
-  1700, // 1,7
-  1800, // 1,8
-  1900, // 1,9
-  2000, // 2
-  2100, // 2,1
-  2200, // 2,2
-  2300, // 2,3
-  2400, // 2,4
-  2500, // 2,5
-  2600, // 2,6
-  2700, // 2,7
-  2800, // 2,8
-  2900, // 2,9
-  3000, // 3
-  3100, // 3,1
-  3200, // 3,2
-  3300, // 3,3
-  3400, // 3,4
-};
-
-uint16_t buck4_voltage_table[] = {
-  600,
-  625,
-  650,
-  675,
-  700,
-  725,
-  750,
-  775,
-  800,
-  825,
-  850,
-  875,
-  900,
-  925,
-  950,
-  975,
-  1000,
-  1025,
-  1050,
-  1075,
-  1100,
-  1125,
-  1150,
-  1175,
-  1200,
-  1225,
-  1250,
-  1275,
-  1300,
-  1300,
-  1350,
-  1350,// 31  1,35
-  1400,// 32  1,40
-  1400,// 33  1,40
-  1450,// 34  1,45
-  1450,// 35  1,45
-  1500,// 36  1,5
-  1600,// 37  1,6
-  1700,// 38  1,7
-  1800,// 39  1,8
-  1900,// 40  1,9
-  2000,// 41  2,0
-  2100,// 42  2,1
-  2200,// 43  2,2
-  2300,// 44  2,3
-  2400,// 45  2,4
-  2500,// 46  2,5
-  2600,// 47  2,6
-  2700,// 48  2,7
-  2800,// 49  2,8
-  2900,// 50  2,9
-  3000,// 51  3,0
-  3100,// 52  3,1
-  3200,// 53  3,2
-  3300,// 54  3,3
-  3400,// 55  3,4
-  3500,// 56  3,5
-  3600,// 57  3,6
-  3700,// 58  3,7
-  3800,// 59  3,8
-  3900,// 60  3,9
-};
-
-uint16_t ldo1_voltage_table[] = {
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1800, // 1,8
-  1900, // 1,9
-  2000, // 2
-  2100, // 2,1
-  2200, // 2,2
-  2300, // 2,3
-  2400, // 2,4
-  2500, // 2,5
-  2600, // 2,6
-  2700, // 2,7
-  2800, // 2,8
-  2900, // 2,9
-  3000, // 3
-  3100, // 3,1
-  3200, // 3,2
-  3300, // 3,3
-};
-
-uint16_t ldo2_voltage_table[] = {
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1800, // 1,8
-  1900, // 1,9
-  2000, // 2
-  2100, // 2,1
-  2200, // 2,2
-  2300, // 2,3
-  2400, // 2,4
-  2500, // 2,5
-  2600, // 2,6
-  2700, // 2,7
-  2800, // 2,8
-  2900, // 2,9
-  3000, // 3
-  3100, // 3,1
-  3200, // 3,2
-  3300, // 3,3
-};
-
-uint16_t ldo3_voltage_table[] = {
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1800, // 1,8
-  1900, // 1,9
-  2000, // 2
-  2100, // 2,1
-  2200, // 2,2
-  2300, // 2,3
-  2400, // 2,4
-  2500, // 2,5
-  2600, // 2,6
-  2700, // 2,7
-  2800, // 2,8
-  2900, // 2,9
-  3000, // 3
-  3100, // 3,1
-  3200, // 3,2
-  3300, // 3,3
-  3300, // 3,3
-  3300, // 3,3
-  3300, // 3,3
-  3300, // 3,3
-  3300, // 3,3
-  3300, // 3,3
-  0xFFFF, // VREFDDR
-};
-
-
-uint16_t ldo5_voltage_table[] = {
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1700, // 1,7
-  1800, // 1,8
-  1900, // 1,9
-  2000, // 2
-  2100, // 2,1
-  2200, // 2,2
-  2300, // 2,3
-  2400, // 2,4
-  2500, // 2,5
-  2600, // 2,6
-  2700, // 2,7
-  2800, // 2,8
-  2900, // 2,9
-  3000, // 3
-  3100, // 3,1
-  3200, // 3,2
-  3300, // 3,3
-  3400, // 3,4
-  3500, // 3,5
-  3600, // 3,6
-  3700, // 3,7
-  3800, // 3,8
-  3900, // 3,9
-};
-
-uint16_t ldo6_voltage_table[] = {
-  900, // 0,9
-  1000, // 1,0
-  1100, // 1,1
-  1200, // 1,2
-  1300, // 1,3
-  1400, // 1,4
-  1500, // 1,5
-  1600, // 1,6
-  1700, // 1,7
-  1800, // 1,8
-  1900, // 1,9
-  2000, // 2
-  2100, // 2,1
-  2200, // 2,2
-  2300, // 2,3
-  2400, // 2,4
-  2500, // 2,5
-  2600, // 2,6
-  2700, // 2,7
-  2800, // 2,8
-  2900, // 2,9
-  3000, // 3
-  3100, // 3,1
-  3200, // 3,2
-  3300, // 3,3
-};
-
-
-uint16_t ldo4_voltage_table[] = {
-  3300, // 3,3
-};
-
-uint16_t vref_ddr_voltage_table[] = {
-  3300, // 3,3
-};
-
-/*
-  Table of Regulators in PMIC SoC
-*/
-
-
-
-regul_struct regulators_table[] = {
-    {
-      .id                 = STPMU1_BUCK1,
-      .voltage_table      = buck1_voltage_table,
-      .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
-      .control_reg        = BUCK1_CONTROL_REG,
-      .low_power_reg      = BUCK1_PWRCTRL_REG,
-      .rank               = OTP_RANK_BUCK1,
-    },
-    {
-      .id                 = STPMU1_BUCK2,
-      .voltage_table      = buck2_voltage_table,
-      .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
-      .control_reg        = BUCK2_CONTROL_REG,
-      .low_power_reg      = BUCK2_PWRCTRL_REG,
-      .rank               = OTP_RANK_BUCK2,
-    },
-    {
-      .id                 = STPMU1_BUCK3,
-      .voltage_table      = buck3_voltage_table,
-      .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
-      .control_reg        = BUCK3_CONTROL_REG,
-      .low_power_reg      = BUCK3_PWRCTRL_REG,
-      .rank               = OTP_RANK_BUCK3,
-    },
-    {
-      .id                 = STPMU1_BUCK4,
-      .voltage_table      = buck4_voltage_table,
-      .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
-      .control_reg        = BUCK4_CONTROL_REG,
-      .low_power_reg      = BUCK4_PWRCTRL_REG,
-      .rank               = OTP_RANK_BUCK4,
-    },
-    {
-      .id                 = STPMU1_LDO1,
-      .voltage_table      = ldo1_voltage_table,
-      .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
-      .control_reg        = LDO1_CONTROL_REG,
-      .low_power_reg      = LDO1_PWRCTRL_REG,
-      .rank               = OTP_RANK_LDO1,
-    },
-    {
-      .id                 = STPMU1_LDO2,
-      .voltage_table      = ldo2_voltage_table,
-      .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
-      .control_reg        = LDO2_CONTROL_REG,
-      .low_power_reg      = LDO2_PWRCTRL_REG,
-      .rank               = OTP_RANK_LDO2,
-    },
-
-    {
-      .id                 = STPMU1_LDO3,
-      .voltage_table      = ldo3_voltage_table,
-      .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
-      .control_reg        = LDO3_CONTROL_REG,
-      .low_power_reg      = LDO3_PWRCTRL_REG,
-      .rank               = OTP_RANK_LDO3,
-    },
-    {
-      .id                 = STPMU1_LDO4,
-      .voltage_table      = ldo4_voltage_table,
-      .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
-      .control_reg        = LDO4_CONTROL_REG,
-      .low_power_reg      = LDO4_PWRCTRL_REG,
-      .rank               = OTP_RANK_LDO4,
-    },
-    {
-      .id                 = STPMU1_LDO5,
-      .voltage_table      = ldo5_voltage_table ,
-      .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
-      .control_reg        = LDO5_CONTROL_REG,
-      .low_power_reg      = LDO5_PWRCTRL_REG,
-      .rank               = OTP_RANK_LDO5,
-    },
-    {
-      .id                 = STPMU1_LDO6,
-      .voltage_table      = ldo6_voltage_table ,
-      .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
-      .control_reg        = LDO6_CONTROL_REG,
-      .low_power_reg      = LDO6_PWRCTRL_REG,
-      .rank               = OTP_RANK_LDO6,
-    },
-    {
-      .id                 = STPMU1_VREFDDR,
-      .voltage_table      = vref_ddr_voltage_table ,
-      .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
-      .control_reg        = VREF_DDR_CONTROL_REG,
-      .low_power_reg      = VREF_DDR_PWRCTRL_REG,
-      .rank               = OTP_RANK_VREFDDR,
-    },
-};
-
-#define MAX_REGUL  ARRAY_SIZE(regulators_table)
-
- 
-/* Private function prototypes -----------------------------------------------*/
-void STPMU1_IrqHandler(void);
-void STPMU1_INTn_Callback(PMIC_IRQn IRQn);
-static void My_Error_Handler(void);
-static regul_struct *STPMU1_Get_Regulator_Data(PMIC_RegulId_TypeDef id);
-static uint8_t STPMU1_Voltage_Find_Index(PMIC_RegulId_TypeDef id, uint16_t milivolts);
-
-/* Private functions ---------------------------------------------------------*/
-
-static regul_struct *STPMU1_Get_Regulator_Data(PMIC_RegulId_TypeDef id)
-{
-    uint8_t i ;
-
-    for (i = 0 ; i < MAX_REGUL ; i++ )
-    {
-        if (id == regulators_table[i].id)
-            return &regulators_table[i];
-    }
-    /* id not found */
-    My_Error_Handler();
-    return NULL;
-}
-
-static uint8_t STPMU1_Voltage_Find_Index(PMIC_RegulId_TypeDef id, uint16_t milivolts)
-{
-    regul_struct *regul = STPMU1_Get_Regulator_Data(id);
-    uint8_t i;
-    for ( i = 0 ; i < regul->voltage_table_size ; i++)
-    {
-        if ( regul->voltage_table[i] == milivolts ) {
-          //printf("idx:%d for %dmV\n\r", (int)i, (int)milivolts);
-          return i;
-        }
-    }
-    /* voltage not found */
-    My_Error_Handler();
-    return 0;
-}
-
-void STPMU1_Enable_Interrupt(PMIC_IRQn IRQn)
-{
-    uint8_t irq_reg , irq_reg_value ;
-
-    if (IRQn >= IRQ_NR)
-    return ;
-
-    /* IRQ register is IRQ Number divided by 8 */
-    irq_reg = IRQn >> 3 ;
-
-    /* value to be set in IRQ register corresponds to BIT(7-N) where N is the Interrupt id modulo 8 */
-    irq_reg_value = 1 << ( 7 - ( IRQn%8 ) );
-
-    /* Clear previous event stored in latch */
-    STPMU1_Register_Write(ITCLEARLATCH1_REG+irq_reg, irq_reg_value );
-
-    /* Clear relevant mask to enable interrupt */
-    STPMU1_Register_Write(ITCLEARMASK1_REG+irq_reg, irq_reg_value );
-
-}
-
-extern void STPMU1_Disable_Interrupt(PMIC_IRQn IRQn)
-{
-    uint8_t irq_reg , irq_reg_value ;
-
-    if (IRQn >= IRQ_NR)
-        return ;
-
-    /* IRQ register is IRQ Number divided by 8 */
-    irq_reg = IRQn >> 3 ;
-
-    /* value to be set in IRQ register corresponds to BIT(7-N) where N is the Interrupt id modulo 8 */
-    irq_reg_value = 1 << ( 7 - ( IRQn%8 ) );
-
-    /* Clear previous event stored in latch */
-    STPMU1_Register_Write(ITCLEARLATCH1_REG+irq_reg, irq_reg_value );
-
-    /* Set relevant mask to disable interrupt */
-    STPMU1_Register_Write(ITSETMASK1_REG+irq_reg, irq_reg_value );
-}
-
-
-void STPMU1_IrqHandler(void)
-{
-    uint8_t irq_reg,mask,latch_events,i;
-
-    for (irq_reg = 0 ; irq_reg < STM32_PMIC_NUM_IRQ_REGS ; irq_reg++)
-    {
-        /* Get latch events & active mask from register */
-        mask = STPMU1_Register_Read(ITMASK1_REG+irq_reg);
-        latch_events = STPMU1_Register_Read(ITLATCH1_REG+irq_reg) & ~mask ;
-
-        /* Go through all bits for each register */
-        for (i = 0 ; i < 8 ; i++ )
-        {
-            if ( latch_events & ( 1 << i ) )
-            {
-                /* Callback with parameter computes as "PMIC Interrupt" enum */
-                STPMU1_INTn_Callback( (PMIC_IRQn )(irq_reg*8 + (7-i)));
-            }
-        }
-        /* Clear events in appropriate register for the event with mask set */
-        STPMU1_Register_Write(ITCLEARLATCH1_REG+irq_reg, latch_events );
-    }
-}
-
-
-/**
-  * @brief  This function is executed in case of error occurrence.
-  * @retval None
-  */
-static void My_Error_Handler(void)
-{
-    while(1)
-    {    
-        HAL_Delay(500);
-    } 
-}
-
-
-void STPMU1_Sw_Reset(void)
-{
-    /* Write 1 in bit 0 of MAIN_CONTROL Register */
-    STPMU1_Register_Update(MAIN_CONTROL_REG, SET , SOFTWARE_SWITCH_OFF_ENABLED );
-}
-
-void STPMU1_Regulator_Enable(PMIC_RegulId_TypeDef id)
-{
-    regul_struct *regul = STPMU1_Get_Regulator_Data(id);
-
-    STPMU1_Register_Update(regul->control_reg,BIT(0),BIT(0));
-}
-
-void STPMU1_Regulator_Disable(PMIC_RegulId_TypeDef id)
-{
-    regul_struct *regul = STPMU1_Get_Regulator_Data(id);
-
-    STPMU1_Register_Update(regul->control_reg,0,BIT(0));
-}
-
-uint8_t STPMU1_Is_Regulator_Enabled(PMIC_RegulId_TypeDef id)
-{
-    uint8_t val ;
-
-    regul_struct *regul = STPMU1_Get_Regulator_Data(id);
-
-    val = STPMU1_Register_Read(regul->control_reg);
-
-    return (val&0x1);
-}
-
-void STPMU1_Regulator_Voltage_Set(PMIC_RegulId_TypeDef id,uint16_t milivolts)
-{
-    uint8_t voltage_index = STPMU1_Voltage_Find_Index(id,milivolts);
-    regul_struct *regul = STPMU1_Get_Regulator_Data(id);
-    STPMU1_Register_Update(regul->control_reg, voltage_index<<2 , 0xFC );
-}
-
-/* register direct access */
-uint8_t STPMU1_Register_Read(uint8_t register_id)
-{
-    uint32_t status = RT_EOK;
-    uint8_t Value = 0;
-
-    status = BSP_I2C4_ReadReg(STPMU1_I2C_ADDRESS, (uint16_t)register_id, &Value, 1);
-
-    /* Check the communication status */
-    if(status != RT_EOK)
-    {
-        My_Error_Handler();
-    }
-    return Value;
-}
-
-void STPMU1_Register_Write(uint8_t register_id, uint8_t value)
-{
-    uint32_t status = RT_EOK;
-
-    status = BSP_I2C4_WriteReg(STPMU1_I2C_ADDRESS, (uint16_t)register_id, &value, 1);
-
-    /* Check the communication status */
-    if(status != RT_EOK)
-    {
-        My_Error_Handler();
-    }
-
-    /* verify register content */
-    if ((register_id!=WATCHDOG_CONTROL_REG) && (register_id<=0x40))
-    {
-        uint8_t readval = STPMU1_Register_Read(register_id);
-        if (readval != value)
-        {
-            My_Error_Handler();
-        }
-    }
-}
-
-void STPMU1_Register_Update(uint8_t register_id, uint8_t value, uint8_t mask)
-{
-    uint8_t initial_value ;
-
-    initial_value = STPMU1_Register_Read(register_id);
-
-    /* Clear bits to update */
-    initial_value &= ~mask;
-
-    /* Update appropriate bits*/
-    initial_value |= ( value & mask );
-
-    /* Send new value on I2C Bus */
-    STPMU1_Register_Write(register_id, initial_value);
-
-    return ;
-}
-
-/*
- *
- * PMIC init
- *    pmic provides power supply on this board
- *    it is configured to turn off some power supply in standby mode
- *
- */
-static uint32_t BSP_PMIC_MspInit(I2C_HandleTypeDef *hi2c)
-{
-    uint32_t  status = RT_EOK;
-    GPIO_InitTypeDef  GPIO_InitStruct;
-
-    /*##-1- Configure the I2C clock source, GPIO and Interrupt #*/
-    BSP_I2C4_Init();
-
-    /*##-2- Configure PMIC GPIOs Interface ########################################*/
-
-    /* INTn - Interrupt Line - Active Low (Falling Edge) */
-    PMIC_INTn_CLK_ENABLE();
-    GPIO_InitStruct.Pin       = PMIC_INTn_PIN;
-    GPIO_InitStruct.Mode      = GPIO_MODE_IT_FALLING;
-    GPIO_InitStruct.Pull      = GPIO_PULLUP; 
-    GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;
-    GPIO_InitStruct.Alternate = 0 ;
-    HAL_GPIO_Init(PMIC_INTn_PORT, &GPIO_InitStruct);
-
-    /* Enable and set INTn EXTI Interrupt  */
-#if defined(CORE_CA7)
-    IRQ_SetPriority(EXTI0_IRQn, 0);
-    IRQ_Enable(EXTI0_IRQn);
-#elif defined(CORE_CM4)
-    HAL_NVIC_SetPriority(EXTI0_IRQn, 0x03, 0x00);
-    HAL_NVIC_EnableIRQ(EXTI0_IRQn);
-#endif
-
-    return status;
-}
-
-static uint32_t BSP_PMIC_MspDeInit(I2C_HandleTypeDef *hi2c)
-{
-    uint32_t  status = RT_EOK;
-    /*##-1- Reset I2C Clock / Disable peripherals and GPIO Clocks###############*/
-    status = BSP_I2C4_DeInit();
-
-    /*##-2- Disable PMIC clk ###########################################*/
-    PMIC_INTn_CLK_DISABLE();
-
-    /*##-3- Disable the NVIC for PMIC ##########################################*/
-#if defined(CORE_CA7)
-    IRQ_Disable(EXTI0_IRQn);
-#elif defined(CORE_CM4)
-    HAL_NVIC_DisableIRQ(EXTI0_IRQn);
-#endif
-    HAL_GPIO_DeInit(PMIC_INTn_PORT,PMIC_INTn_PIN);
-
-    return status;
-}
-
-uint32_t BSP_PMIC_Is_Device_Ready(void)
-{
-    int32_t  status = RT_EOK;
-
-    /* Write the TxBuffer1 at @0, then read @0 when device ready */
-    if (BSP_I2C4_IsReady(STPMU1_I2C_ADDRESS, 1) != RT_EOK)
-    {
-        status = -RT_EBUSY;
-    }
-    return status ;
-}
-
-/* Use Xls I2C COnfiguration Tools with I2C Clock config + output clocks requirement */
-#define I2C_TIMING     0x10805E89
-
-uint32_t BSP_PMIC_Init(void)
-{
-    int32_t status = RT_EOK;
-    PMIC_IRQn irq;
-
-    /*##-1- Configure the I2C peripheral ######################################*/
-    BSP_PMIC_MspInit(&hI2c4);
-
-    status = BSP_PMIC_Is_Device_Ready();
-    if (status != RT_EOK )
-    {
-        return status;
-    }
-
-    if (STPMU1_Register_Read(VERSION_STATUS_REG) != 0x00)
-    {
-        status = -RT_EIO;
-        return status;
-    }
-
-    STPMU1_Enable_Interrupt(IT_PONKEY_R);
-    STPMU1_Enable_Interrupt(IT_PONKEY_F);
-    /* enable all irqs  */
-    for (irq = IT_SWOUT_R; irq < IRQ_NR; irq++) 
-    {
-        STPMU1_Enable_Interrupt(irq);
-    }
-
-    return RT_EOK;
-}
-
-uint32_t BSP_PMIC_DeInit(void)
-{
-    uint32_t  status = RT_EOK;
-    if(HAL_I2C_GetState(&hI2c4) != HAL_I2C_STATE_RESET)
-    {
-        /* Deinit the I2C */
-        BSP_PMIC_MspDeInit(&hI2c4);
-    }
-    return status;
-}
-
-/*
- *
- * following are configurations for this board
- * same configuration than linux
- *
- *  BSP_PMIC_InitRegulators set the regulators for boot
- *  BSP_PMIC_PrepareLpStop set the low power registers for LPSTOP mode
- *    should be called by user before entering is CSTOP
- *  BSP_PMIC_PrepareLpStop set the low power registers for STANDBY mode
- *    should be called by user before entering is STANDBY
- *
- *
- */
-/* following are configurations */
-uint32_t BSP_PMIC_InitRegulators(void)
-{
-    uint32_t  status = RT_EOK;
-
-    STPMU1_Register_Write(MAIN_CONTROL_REG, 0x04);
-    STPMU1_Register_Write(VIN_CONTROL_REG, 0xc0);
-    STPMU1_Register_Write(USB_CONTROL_REG, 0x30);
-
-    STPMU1_Register_Write(MASK_RESET_BUCK_REG, 0x04);
-    STPMU1_Register_Write(MASK_RESET_LDO_REG, 0x00);
-    STPMU1_Register_Write(MASK_RANK_BUCK_REG, 0x00);
-    STPMU1_Register_Write(MASK_RANK_LDO_REG, 0x00);
-    STPMU1_Register_Write(BUCK_PULL_DOWN_REG, 0x00);
-    STPMU1_Register_Write(LDO14_PULL_DOWN_REG, 0x00);
-    STPMU1_Register_Write(LDO56_PULL_DOWN_REG, 0x00);
-    STPMU1_Register_Write(BUCK_ICC_TURNOFF_REG, 0x30);
-    STPMU1_Register_Write(LDO_ICC_TURNOFF_REG, 0x3b);
-
-    /* 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);
-
-    /* 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);
-
-    /* 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);
-
-    /* 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_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);
-
-    STPMU1_Regulator_Enable(STPMU1_VREFDDR);
-
-    return status;
-}
-
-uint32_t BSP_PMIC_SwitchOff(void)
-{
-    uint32_t  status = RT_EOK;
-
-    STPMU1_Register_Write(MAIN_CONTROL_REG, 0x01);
-    return status;
-}
-
-__weak void BSP_PMIC_INTn_Callback(PMIC_IRQn IRQn)
-{
-    switch (IRQn)
-    {
-    case IT_PONKEY_F:
-        rt_kprintf("IT_PONKEY_F");
-        break;
-
-    case IT_PONKEY_R:
-        rt_kprintf("IT_PONKEY_R");
-        break;
-
-    case IT_WAKEUP_F:
-        rt_kprintf("IT_WAKEUP_F");
-        break;
-
-    case IT_WAKEUP_R:
-        rt_kprintf("IT_WAKEUP_R");
-        break;
-
-    case IT_VBUS_OTG_F:
-        rt_kprintf("IT_VBUS_OTG_F");
-        break;
-
-    case IT_SWOUT_F:
-        rt_kprintf("IT_SWOUT_F");
-        break;
-
-    case IT_TWARN_R:
-        rt_kprintf("IT_TWARN_R");
-        break;
-
-    case IT_TWARN_F:
-        rt_kprintf("IT_TWARN_F");
-        break;
-
-    default:
-        rt_kprintf("%d",IRQn);
-        break;
-    }
-    rt_kprintf(" Interrupt received\n\r");
-}
-
-void STPMU1_INTn_Callback(PMIC_IRQn IRQn) 
-{
-    BSP_PMIC_INTn_Callback(IRQn);
-}
-
-void BSP_PMIC_INTn_IRQHandler(void)
-{
-    HAL_GPIO_EXTI_IRQHandler(PMIC_INTn_PIN);
-
-    STPMU1_IrqHandler();
-}
-
-void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hI2c4)
-{
-    while(1);
-}

+ 6 - 0
bsp/stm32/stm32mp157a-st-ev1/rtconfig.h

@@ -152,6 +152,12 @@
 
 /* samples: kernel and components samples */
 
+
+/* Privated Packages of RealThread */
+
+
+/* Network Utilities */
+
 #define SOC_FAMILY_STM32
 #define SOC_SERIES_STM32MP1