Merge pull request #3882 from thread-liu/mp1-ev1
[update] stm32mp1-ev1 bsp drivers
This commit is contained in:
commit
8247336afd
|
@ -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 */
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
@ -23,11 +36,6 @@ menu "On-chip Peripheral Drivers"
|
|||
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"
|
||||
select RT_USING_SERIAL
|
||||
|
@ -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,12 +124,16 @@ 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_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
|
||||
|
@ -142,7 +144,35 @@ menu "On-chip Peripheral Drivers"
|
|||
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
|
||||
|
|
|
@ -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']
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 = ® /* 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 ®ulators_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
|
|
@ -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,7 +25,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32mp1xx_hal.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
@ -46,59 +45,286 @@ typedef enum
|
|||
|
||||
/* 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;
|
||||
|
||||
/**
|
||||
* @}
|
||||
/* 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
|
||||
*
|
||||
*/
|
||||
|
||||
/** @defgroup STM32MP15XX_EVAL_STPMU_Exported_Constants Exported Constants
|
||||
* @{
|
||||
*/
|
||||
#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
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
#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
|
||||
}
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -152,6 +152,12 @@
|
|||
|
||||
/* samples: kernel and components samples */
|
||||
|
||||
|
||||
/* Privated Packages of RealThread */
|
||||
|
||||
|
||||
/* Network Utilities */
|
||||
|
||||
#define SOC_FAMILY_STM32
|
||||
#define SOC_SERIES_STM32MP1
|
||||
|
||||
|
|
Loading…
Reference in New Issue