nandflash相关的一些结构题和操作函数

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

1. Nand_Init()

int NandInit(void)
{       
  // -------------------------------
  // Configure GPIO9 in Alt Funct. A
  // -------------------------------
  *((uint32_t *) (GPIO0_REG_START_ADDR + 0x20)) |= 0x00000200;
        
  nand.addr.pBase       = (volatile uint16_t *) NAND_FLASH_CS0_START_ADDR;
  nand.addr.pCommand    = (volatile uint8_t *) NAND_FLASH_CS0_START_ADDR + 0x00810000;
  nand.addr.pCommonArea = (volatile uint8_t *) NAND_FLASH_CS0_START_ADDR + 0x01020000;
        
  // Map The Space for FSMC Registers
  nand.regs = (FSMCRegs *) 0x10100000;
        
  // --------------------------------------------------
  // Disable all the other CS that we do not use (NOR),
  // keeping high bit 7 for disabling WP.
  // This is a temporary solution to avoid conflicts
  // --------------------------------------------------
  // Bank NOR 0, 1, 2, 3 (to be removed when NOR comes)
  // --------------------------------------------------
  nand.regs->FSMC_BCR1 &= 0x00000080;
  nand.regs->FSMC_BCR2 &= 0x00000080;
  nand.regs->FSMC_BCR3 &= 0x00000080;

  // -----------------------------------------------
  // Set NAND Control Values depending on the CS
  // -----------------------------------------------
  // CONTROL REGISTER
  // -----------------------------------------------
  // address_low        : 0
  // page_length        : 512 (for ECC calculation)
  // ecc_logic          : 0   (enabled when required)
  // bus_width          : 16
  // mem_type           : 1       (NAND)
  // wait_feature       : 1   (linked to GPIO9 Alt. Func. "A")
  // pc_reset           : 0
  // -----------------------------------------------

  nand.regs->FSMC_PCR0 = FMSC_PCR_BUS_WIDTH_16 | FMSC_PCR_MEM_TYPE_NAND
      | FMSC_PCR_BANK_ENABLE | FMSC_PCR_WAIT_ENABLE;

  // ----------------------------------------------
  // Set NAND Timings Registers depending on the CS.
  // -----------------------------------------------
  // COMMON AREA
  // -----------------------------------------------
  // data_bus_hiz_phase         : 0x0D
  // addr_hold_phase            : 0x0D
  // wait_phase                         : 0x0D
  // addr_setup_phase           : 0x0D
  // -----------------------------------------------

  nand.regs->FSMC_PMEM0 = FMSC_PMEM_MEM0HIZ | FMSC_PMEM_MEM0HOLD
      | FMSC_PMEM_MEM0WAIT | FMSC_PMEM_MEM0SET;

  // -----------------------------------------
  // Reset the device and wait till it's ready
  // -----------------------------------------
  *(nand.addr.pCommand) = 0xff;

  // ---------------------------------------------
  // Write the specific command for reading the ID
  // ---------------------------------------------
  *(nand.addr.pCommand)    = 0x90;
  *(nand.addr.pCommonArea) = 0x00;

  // --------------------------------------------
  // Assign the Device ID and the Manifacturer ID
  // --------------------------------------------
  nand.id.uiManID    = (*(nand.addr.pBase) & 0xff);
  nand.id.uiDeviceID = (*(nand.addr.pBase) & 0xff);

  if (nand.id.uiManID != MAKER_ID || nand.id.uiDeviceID != DEVICE_ID)
          return -1;

  // -------------------------------------------------------------------
  // Let's assume that the ECC is implementation is supported by default
  // -------------------------------------------------------------------
  // We support BCH8 (8 correctable bits every 512 bytes of data)
  // -------------------------------------------------------------------

  return 0;
}
2.  FSMCRegs ---FSMC 是Nandflash controller 模块, FSMCRegs表示了该模块的寄存器情况
typedef volatile struct
{
        uint32_t FSMC_BCR0;   // 0x00
        uint32_t FSMC_BTR0;   // 0x04
        uint32_t FSMC_BCR1;   // 0x08
        uint32_t FSMC_BTR1;   // 0x0C
        uint32_t FSMC_BCR2;   // 0x10
        uint32_t FSMC_BTR2;   // 0x14
        uint32_t FSMC_BCR3;   // 0x18
        uint32_t FSMC_BTR3;   // 0x1C
        uint32_t UNUSED0[8];  // [0x18 - 0x40]
        uint32_t FSMC_PCR0;   // 0x40
        uint32_t FSMC_PISR0;  // 0x44
        uint32_t FSMC_PMEM0;  // 0x48
        uint32_t FSMC_PATT0;  // 0x4C
        uint32_t FSMC_PIO0;   // 0x50
        uint32_t FSMC_ECCR0;  // 0x54
        uint32_t FSMC_ECC2R0; // 0x58
        uint32_t FSMC_ECC3R0; // 0x5C
} FSMCRegs;
3.  Nand flash 模块的虚拟内存映射地址定义:

/* CF/CF+/NAND Flash chip-select 0 (SMPS0n LOW) */
#define NAND_FLASH_CS0_START_ADDR       0x40000000
#define NAND_FLASH_CS0_LENGTH           0x10000000
#define NAND_FLASH_CS0_END_ADDR         (NAND_FLASH_CS0_START_ADDR+NAND_FLASH_CS0_LENGTH-1)
  
/* CF/CF+/NAND Flash chip-select 1 (SMPS1n LOW) */
#define NAND_FLASH_CS1_START_ADDR       0x50000000
#define NAND_FLASH_CS1_LENGTH           0x10000000
#define NAND_FLASH_CS1_END_ADDR         (NAND_FLASH_CS1_START_ADDR+NAND_FLASH_CS1_LENGTH-1)

4. 一些nandflash相关的常量定义:

#define PAGE_SIZE                                       DATA_BYTES_PER_SECTOR
#define NAND_SECTOR_SIZE                        PAGE_SIZE               
#define NAND_SECTORS_PER_BLOCK          SECTORS_PER_BLOCK;
#define ECC_WORD_LIMIT                          256                             // 512 Byte data is the max length for ECC.
#define ECC_BYTES_PER_SUB_BLOCK         16                              // Effective number of ECC Byte per block.
#define ECC_WORD_PER_SUB_BLOCK          8                               // Number of ECC Word per block with padding.
#define SIZE_BYTE_SUB_BLOCK                     512                             // Size in Byte per ECC data block.
  
#define PAGE(x)                                         ((x + PAGE_SIZE - 1) / PAGE_SIZE)
  
  /* --------FSMC--PCR------ */
#define FMSC_PCR_BUS_WIDTH_8            (0x0)
#define FMSC_PCR_BUS_WIDTH_16           (0x10) 
#define FMSC_PCR_MEM_TYPE_NAND          (0x8)
#define FMSC_PCR_BANK_ENABLE            (0x4)
#define FMSC_PCR_WAIT_ENABLE            (0x2)
#define FMSC_PCR_PC_RESET                       (0x0)

/* --------FSMC--PMEM  0------ */
#define FMSC_PMEM_MEM0HIZ               (0x00<<24)
#define FMSC_PMEM_MEM0HOLD              (NAND_TIMING_1<<16)
#define FMSC_PMEM_MEM0WAIT              (NAND_TIMING_2<<8)
#define FMSC_PMEM_MEM0SET               (0x00)

#define ERROR_NAND_BAD_BLOCK                            -6

5.  这是初始化时候会校验的nandflash两个出厂值

typedef struct
{
        uint8_t uiManID;
        uint8_t uiDeviceID;
} NAND_Id;
6. Nandflash, 使用时的地址情况定义

typedef struct
{
        volatile uint8_t        *pCommand; // Pointer to command area
        volatile uint8_t        *pCommonArea;// Pointer to common area
        volatile uint8_t        *pAttributeArea;// Pointer to attribute area
        volatile uint16_t       *pBase;// Pointer to I/O area
} NAND_Address;
7. nand_system_context_t --- nand 模块上下文定义,几乎包括了nandflash所有的信息
typedef struct
{
        FSMCRegs                *regs;       // Virtual Address of the mapped register space (FSMC)
        NAND_Id                 id;           // Identity Card for the current device
        NAND_Address    addr;    // Logical Addresses associated to the current NAND device
} nand_system_context_t;
8. ReadNandPages() --- 读取nandflash中指定的从起始页到结束页的内容到buffer中

uint32_t ReadNandPages(uint32_t page, uint8_t *buf, int pageCount, int endPage)
{
  int err;

  seekBlock(page);

  while (pageCount && page <= endPage) {
      cacheNext();
          while (getBlockStatus()) {
          // --------------------------------------------------
          // Every time we meet a bad block, jump to next one
          // --------------------------------------------------
          page++;

          if (page > endPage) {
              puts("ERROR: Too many BAD BLOCKS for this image copy\r\n");
              cacheEnd();
              return 0;
          }

          cacheNext();
      }

      err = readPage((uint16_t *)buf);
      if (err)
        return 0;

      buf += PAGE_SIZE;
      pageCount--;
      page++;
  }

  cacheEnd();

  if (pageCount) {
      puts("ERROR: Partition too small for this image copy\r\n");
      return 0;
  }

  return page;
}
9. 一些nandflash 读写的辅助操作

static void cacheEnd(void)
{         
          *(nand.addr.pCommand) = 0x3f;
}         
          
static void cacheNext(void)
{         
          *(nand.addr.pCommand) = 0x31;
}             
//确定block地址              
static void seekBlock(uint32_t BlockAddress)
{
          *(nand.addr.pCommand) = 0x00;
          SET_BLOCK_ADDRESSING(nand.addr.pCommonArea, 0, BlockAddress);
          *(nand.addr.pCommand) = 0x30;
}     
10。 getBlockStatus() --- 获取block的状态,看是不是坏块。
static int getBlockStatus(void)
{
  uint32_t Data;
      
  // Position to OOB area
  *(nand.addr.pCommand) = 0x05;
  SET_BLOCK_OFFSET(nand.addr.pCommonArea, DATA_BYTES_PER_SECTOR);
  *(nand.addr.pCommand) = 0xE0;

  // Read the first word
  Data = (*nand.addr.pBase);
      
  // -----------------------------------------------------------------------------
  // Verify if the block is bad (return 1 in this case)
  // -----------------------------------------------------------------------------
  // The first byte of the first page spare area tells us if a block is bad (0x00)
  // -----------------------------------------------------------------------------
  return ((0xFF & Data) != 0xFF) ? ERROR_NAND_BAD_BLOCK : 0;
}
11 readPage() --- 读nandflash, 读写都是以page为单位,擦除是以block为单位。

static int readPage(uint16_t *buf)
{
#ifdef CONFIG_ECC
  uint32_t data_pos = 0;
  uint32_t ecc_pos = PAGE_SIZE + ECC_OOB_START;
  int ErrorCounter;
  int block, i, t;

  for (block = 0; block < ECC_BLOCKS_PER_PAGE; block++, buf += ECC_WORD_LIMIT) {

      // Position to read block
      *(nand.addr.pCommand) = 0x05;
      SET_BLOCK_OFFSET(nand.addr.pCommonArea, data_pos);
      *(nand.addr.pCommand) = 0xE0;
      data_pos += SIZE_BYTE_SUB_BLOCK;

      // reset ECC calculation
      nand.regs->FSMC_PCR0 &= ~0x00000040;
      nand.regs->FSMC_PCR0 |=  0x00000040;

      // ----------------------------------
      // Read 512 Bytes of data (128 WORDS)
      // ----------------------------------
      dma_copy16 (buf, (void *)nand.addr.pBase, ECC_WORD_LIMIT, DMA_CR_DSTI);

      // Position to ECC in the OOB area
      *(nand.addr.pCommand) = 0x05;
      SET_BLOCK_OFFSET(nand.addr.pCommonArea, ecc_pos);
      *(nand.addr.pCommand) = 0xE0;
      ecc_pos += ECC_BYTES_PER_SUB_BLOCK;

      // -------------------------------------------------
      // Read 16 Bytes of data (4 WORDS). 14 bytes are ecc
      // -------------------------------------------------
      for (i = 0; i < ECC_WORD_PER_SUB_BLOCK; i++)
        t = *(nand.addr.pBase);

      ErrorCounter = correctData((uint8_t *)buf);

      // -----------------------------
      // 0 or positive means we are OK
      // -----------------------------
      if (ErrorCounter < 0) {
          // ---------------------
          // Impossible to correct
          // ---------------------
          puts("RNP: IMPOSSIBLE TO CORRECT SECTOR SUB_BLOCK\r\n");
          return -1;
      }
  }
#else
  // Position to read block
  *(nand.addr.pCommand) = 0x05;
  SET_BLOCK_OFFSET(nand.addr.pCommonArea, 0);
  *(nand.addr.pCommand) = 0xE0;

  dma_copy16 (buf, (void *)nand.addr.pBase, ECC_WORD_LIMIT * ECC_BLOCKS_PER_PAGE, DMA_CR_DSTI);
#endif

  return 0;
}
12. correctData() --- 这个不知道干啥用的

#ifdef CONFIG_ECC
static int correctData(uint8_t *buf)
{
        const uint8_t flip[8] = {3, 2, 1, 0, 7, 6, 5, 4};
        const struct {
                uint32_t start;
                int shift;
        } pos13[8] = {
          {0, 0}, {1, 5}, {3, 2}, {4, 7},
          {6, 4}, {8, 1}, {9, 6}, {11, 3}
        };
        uint32_t val;
        int i;
        int error_count;
        uint16_t pos;
        uint16_t change;
        uint16_t invert;
        uint8_t ecc_code[14];

    // -----------------------------------------------------
    // Wait for the ECC to be ready
    // -----------------------------------------------------
    while (!(nand.regs->FSMC_PISR0 & 0x8000));

        val = nand.regs->FSMC_ECCR0;
        ecc_code[0] = (val >>  0) & 0xFF;
        ecc_code[1] = (val >>  8) & 0xFF;
        ecc_code[2] = (val >> 16) & 0xFF;
        ecc_code[3] = (val >> 24) & 0xFF;

        val = nand.regs->FSMC_ECC2R0;
        ecc_code[4] = (val >>  0) & 0xFF;
        ecc_code[5] = (val >>  8) & 0xFF;
        ecc_code[6] = (val >> 16) & 0xFF;
        ecc_code[7] = (val >> 24) & 0xFF;

        val = nand.regs->FSMC_ECC3R0;
        ecc_code[8]  = (val >>  0) & 0xFF;
        ecc_code[9]  = (val >>  8) & 0xFF;
        ecc_code[10] = (val >> 16) & 0xFF;
        ecc_code[11] = (val >> 24) & 0xFF;

        val = nand.regs->FSMC_PISR0;
        if (!(val & 0x4000)) {
                ecc_code[12] = (val >>  8) & 0xFF;
                ecc_code[13] = (val >> 16) & 0xFF;
        } else {
                ecc_code[12] = (val >> 16) & 0xFF;
                ecc_code[13] = 0xFF;
        }

    // --------------------------
    // Clear CodeReady status bit
    // --------------------------
    nand.regs->FSMC_PISR0 &= ~0x00008000;

    error_count = (ecc_code[3] & ERROR_COUNT_MASK) >> ERROR_COUNT_POS;

        /* If there are too many ECC errors, then we can't correct this block */
        if (error_count > ERROR_COUNT_MAX)
                return -1;

        for (i = 0; i < error_count; i++) {

                pos  = (ecc_code[pos13[i].start]   >> pos13[i].shift);
                pos |= (ecc_code[pos13[i].start+1] << (8 - pos13[i].shift));
                pos |= (ecc_code[pos13[i].start+2] << (16 - pos13[i].shift));
                pos &= 0x1fff;

                if (pos <= 4095) {

                        change = pos / 8;
                        invert = pos % 8;
                        if (buf[change] & 1<<flip[invert])
                                /* inversion 1->0 */
                                buf[change] = (buf[change] & ~(1<<flip[invert]));
                        else
                                /* inversion 0->1 */
                                buf[change] = (buf[change] | 1<<flip[invert]);
                }
        }

        return error_count;
}
#endif


 







NANDFLASH与PSRAM NANDFLASH与RAM,NORFLASH一些概念 小白第一次发博文,望大佬指正! 符号与缩略语与基本原理解释 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// DDR : DDR就是DD... 阅读详情

相关推荐

【笔记】NandFlash介绍

目录 NandFlash结构 地址访问 如何使用NandFlash芯片? NandFlash结构 页(page) 读写的最小单位,不同厂家的芯片,大小有不同,常见的有256、512、1024、2048字节。 块(block) 擦除的最小单位,不同厂家大小也有所不同。 额外空间() 这块空间是在每一页的后面多出来的存储空间,不算入总的存储空间,大小一般数十个字节,视芯片而定。 地址访问 NandFlash的地址访问大致由列地址行...

mc_li的博客 2893

FatFs文件系统Nandflash驱动函数详解

FatFs文件系统Nandflash驱动函数详解 转载 2015-08-06 14:43:27 标签:nandflash驱动函数详fatfs文件系统nandfla 本文讲解FatFs文件系统 下需要的nandflash驱动函数 1:disk_initialize() 此函数用于nandflash的初始化,包过时钟基本的IO初始化,以及建立LUT表。 ​ 显示...

qq_20312079的博客 3820

常用DDRNandFlash型号

常用DDRNandFlash型号

qq_44884706的博客 2185

pmon下nandflash相关操作

龙芯平台下nandflash相关操作 pmon下 查看nandflash设备(只能通过打印信息查看) NAND device: Manufacturer ID: 0xec, Chip ID: 0xf1 (Samsung NAND 128MiB 3,3V 8-bit) NAND_ECC_NONE selected by board driver. This is not recommended !!...

冷漠的搬砖人的博客 2218

裸机:NandFlashiNand

iNand 是 SanDisk 公司研发的存储芯片,可以看作是 SD 卡或 MMC 卡芯片化的产物。iNand 内部采用 MLC(多层单元)存储颗粒,并提供了复杂的接口电路完善的功能,如 ECC 校验、Cache 机制等。主要特点:1.接口协议:iNand 提供了 eMMC 接口协议,与 SoC(系统级芯片)的 eMMC 控制器进行配对通信,简化了与 SoC 的连接交互。2.性能提升:iNand 内置了 Cache 模块,能够显著提高小容量文件的存储速度,并且具有接近 SLC 的读写速度。

qq_43441284的博客 1774

Nandflash 驱动

1. 基本知识 jz2440 中使用的nandflash的型号是 K9F2G08U0M 图中可以看到这个nandflash结构是: 1页 = (2k + 64) 字节 1块 = 64个页 = ( 2k + 64) x 64 = 128k + 4k 字节 1个设备 = 2048个块 = ... 对于某个字节的访问,地址的组成如上图,是分5个周期发送的,其中 Column是列,R...

老鹏 1804

NandFlash详解

转载自: https://blog.csdn.net/hellomxj1/article/details/18984873 学习结构如目录所示: 一、NAND FLASH概述 二、NAND FLASH的参数及物理结构 三、NAND FLASH的地址访问方法 四、NAND FLASH的操作方法 五、NAND FLASH的其他一些补充 一、Nand Flash的概述 1、Nand Flash...

Golden_Chen的专栏 3万+

stm32 NANDFLASH相关操作

void FSMC_NAND_Init(void) {   GPIO_InitTypeDef GPIO_InitStructure;   FSMC_NANDInitTypeDef FSMC_NANDInitStructure;   FSMC_NAND_PCCARDTimingInitTypeDef  p;   /*使能FSMC总线时钟*/   RCC_AHBPeriphClockCm

1392

外存——NandFlash芯片与S5PV210的NandFlash控制器

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。

主要记录嵌入式学习与开发过程。 2403

NandFlash详述

NandFlash详述 文章目录NandFlash详述1. Nand Flash 是什么1.1 闪存存储单元2. Nand Flash 内部原理2.1 硬件实现机制2.2 数据存储单元的整体架构2.3 物理存储单元的阵列组织结构2.4 引脚(Pin)的说明2.5 特殊硬件结构3. Nand Flash 怎么用3.1 常见操作3.2 读取操作的时序图3.3 计算传入的行地址列地址**4. Nan...

sinat_40754254的博客 1682

ADI的BF561双核DSP怎么做开发,我来说一说(十一)NANDFLASH的读写

BF561这颗ADI公司的双核DSP,应该怎么做底层开发,系列文章简单说一说。

ADI_OP的博客 1160

【篇九】NandFlash iNand存储

本周总结点 NandFlashiNand概念相关接图 NandFlash常见操作流程图分析 Nand控制器(SOc角度) iNand介绍 iNand/SD卡操作 NandFlashiNand概念相关接图 • NandiNand接线图如下 Nand的型号命名:K9F2G08 1:K9F表示厂家是三星公司的,型号是NandFlash...

小石头的幸福—2014 1867

NandFlash基础知识-K9F2G08

S5PV210的NandFlash: 关于Nand的基本知识: 1.NandFlash的型号命名都是有意义的,K9F2G08,K9F表示是samsung系列的NandFlash,2G表示的是2Gbit = 256MByte,08表示的是8位的,也就是数据线有8根。 2.Nand有8bit数据位的,也有16bit位的,说明我们NandFlash是并行接口的,我们Nand 的数据线上传输的不一定都是...

qq_33472414的博客 3236

基于Nandflash的Bootloader的设计与实现

操作系统内核运行之前的一段自举程序,用来初始化硬件设备、改变处理器运行模式重组中断向量,建立内存空间的映射图,将系统的软硬件环境带到一个由用户定制的特定状态,然后加载操作系统内核。()函数的具体实现,但省略了一些具体细节,包括从串口打印的启动、交互、调试信息一些具体函数的实现。实际上也依赖于具体的嵌入式板级设备的配置,也就是说,对于两块不同的嵌入式板而言,即使它们是基于同一种处理器而构建的,要想让运行在一块板子上的。,并理解找出其中的原理规律,就其特定的嵌入式系统,移植或开发属于自己的。

智光工作室 992

norflashnandflash

CPU可以直接访问NOR Flash,并且能够从中执行代码。这使得NOR Flash在嵌入式系统中,特别是在需要高可靠性快速启动的应用场景中,成为一种理想的存储器选择。与NOR Flash不同,NAND Flash 的访问方式特性有所不同。尽管NAND Flash在存储容量成本方面具有优势,但其访问方式与CPU的直接访问存在一些区别。NAND Flash的特点:适合大容量、低成本的数据存储,但不能直接被CPU访问或执行代码。它需要通过控制器管理,并且系统启动时通常需要将代码加载到RAM中运行。

colortztzztzt的博客 848

linux nandflash

1. 前言:1.1 先分析下nandflash的布局、操作结构由图可以看出一片Nand flash为一个设备(device),其数据存储分层为:a.  1个设备(device)=1024个块(Blocks),块也是Nand flash擦除操作的最小单位。b.  1个块(block) = 64页(Pages),页是Nand flash写入的最小单位,对于每一个页,由数据块区域空闲区域。数据区,也容...

chenliang0224的专栏 1951

关于启动代码中NANDFLASH启动相关代码的解释

首先转载一篇文章。 转自:http://blog.csdn.net/canjiangsu/article/details/6584791   [置顶] 原来程序是这样从NandFlash拷贝并跳转到SDRAM的 重新看了一下FL2440的BootLoader,终于把程序是怎样从Nandflash拷贝并跳转到SDRAM的过程弄清楚了,在这边做一下笔记。先上张图:

行者 1050

Nandflash

一般Soc的内部会集成flash控制器,我们只需要操作寄存器即可对Nandflash进行读写等操作Nandflash的寄存器较多,并且每款Soc的寄存器都不一样,因此如果要知道具体操作哪些寄存器,最好的方法就是根据已有代码进行梳理,不要一开始就想根据数据手册完全写出代码。

wiliam_luky的博客 236
上一篇: uart 串口的一些结构体和操作函数
下一篇: 对bootloader 环境变量的一些操作
lamdoc
博客等级 码龄18年 155粉丝 655原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值