OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4059|回复: 1

fmc控制nand flash無法讀寫?

[复制链接]

3

主题

6

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2015-5-21
在线时间
0 小时
发表于 2015-8-24 18:10:21 | 显示全部楼层 |阅读模式
5金钱
我是使用stm32f427透過fmc控制MT29F1G08ABAEAWP
目前可以讀到ID與ParameterID
但是我想要做讀寫的測試
要對某個page做抹寫再寫入再讀出
來判斷是否有問題

但是
無論我寫任何值
總是讀出0的值
不知道大俠是否有經驗

讀function
HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, unsigned char *pBuffer, unsigned int NumPageToRead)
{
  unsigned int index  = 0;
  unsigned int deviceaddress = 0, size = 0, numpagesread = 0, addressstatus = NAND_VALID_ADDRESS;                                                                                                                   
  NAND_AddressTypeDef nandaddress;
  unsigned int addressoffset = 0;                                                                                                                                                                                   

  /* Process Locked */
  __HAL_LOCK(hnand);

  /* Check the NAND controller state */
  if(hnand->State == HAL_NAND_STATE_BUSY)                                                                                                                                                                           
  {                           
     return HAL_BUSY;
  }  

  /* Identify the device address */
  if(hnand->Init.NandBank == FMC_NAND_BANK2)                                                                                                                                                                        
  {    
    deviceaddress = NAND_DEVICE1;
  }    
  else
  {    
    deviceaddress = NAND_DEVICE2;
  }    

  /* Update the NAND controller state */
  hnand->State = HAL_NAND_STATE_BUSY;                                                                                                                                                                               

  /* Save the content of pAddress as it will be modified */
  nandaddress.Block     = pAddress->Block;
  nandaddress.Page      = pAddress->age;
  nandaddress.Zone      = pAddress->Zone;
/* Page(s) read loop */
  while((NumPageToRead != 0) && (addressstatus == NAND_VALID_ADDRESS))
  {
    /* update the buffer size */
    size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpagesread);

    /* Get the address offset */
    addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);

    /* Send read page command sequence */
    *(unsigned char *)((unsigned int)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;

    *(unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA)) = 0x00;
    *(unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA)) = 0x00;
    *(unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA)) = 0x09;
    *(unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA)) = 0x11;

 *(unsigned char *)((unsigned int)(deviceaddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;

#if 1
    /* Read status until NAND is ready */
    unsigned int i = 0;
    printk("!!!!!!!!!!!!!!!!\n");
    while(HAL_NAND_Read_Status(hnand) != NAND_READY)
    {
    //  if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
      if(i>NAND_WRITE_TIMEOUT)
      {
        return HAL_TIMEOUT;
      }
      i++;
    }
    printk("!!!!!!!!!!!!!!!!\n");
#endif
    *(unsigned char *)((unsigned int)(deviceaddress | CMD_AREA)) = 0x00;

    //unsigned char data = 0;
    /* Get Data into Buffer */
    for(index = size; index != 0; index--)
    {
      *pBuffer++ = *(unsigned char *)deviceaddress;
      //pBuffer[index] = *(unsigned char *)deviceaddress;
      //data = *(unsigned char *)deviceaddress;
    //printk("!!!data = 0x%x\n",data);
    }

 numpagesread++;

    /* Decrement pages to read */
    NumPageToRead--;

    /* Increment the NAND address */
    addressstatus = HAL_NAND_Address_Inc(hnand, &nandaddress);
  }

  /* Update the NAND controller state */
  hnand->State = HAL_NAND_STATE_READY;

  /* Process unlocked */
  __HAL_UNLOCK(hnand);

  return HAL_OK;

}

寫function
HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, unsigned char *pBuffer, unsigned int NumPageToWrite)
{
  unsigned int index   = 0;
  unsigned int tickstart = 0;
  unsigned int deviceaddress = 0 , size = 0, numpageswritten = 0, addressstatus = NAND_VALID_ADDRESS;
  NAND_AddressTypeDef nandaddress;
  unsigned int addressoffset = 0;

  /* Process Locked */
  __HAL_LOCK(hnand);

  /* Check the NAND controller state */
  if(hnand->State == HAL_NAND_STATE_BUSY)
  {
     return HAL_BUSY;
  }

  /* Identify the device address */
  if(hnand->Init.NandBank == FMC_NAND_BANK2)
  {
    deviceaddress = NAND_DEVICE1;
  }
  else
  {
    deviceaddress = NAND_DEVICE2;
  }

  /* Update the NAND controller state */
  hnand->State = HAL_NAND_STATE_BUSY;

  /* Save the content of pAddress as it will be modified */
  nandaddress.Block     = pAddress->Block;
  nandaddress.Page      = pAddress->age;
  nandaddress.Zone      = pAddress->Zone;
/* Page(s) write loop */
  while((NumPageToWrite != 0) && (addressstatus == NAND_VALID_ADDRESS))
  {
    /* update the buffer size */
    size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpageswritten);

    /* Get the address offset */
    addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
    printk("addressoffset = 0x%x\n",addressoffset);

    /* Send write page command sequence */
    //*(unsigned char *)((unsigned int)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
    *(unsigned char *)((unsigned int)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;

*(unsigned char *)((unsigned int)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;

    *(unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA)) = 0x00;
    *(unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA)) = 0x00;
    *(unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA)) = 0x09;
    *(unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA)) = 0x11;
    //*(unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA+2)) = ADDR_1ST_CYCLE(addressoffset);
    //*(unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA+3)) = ADDR_2ND_CYCLE(addressoffset);
    //*(unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset);

    /* for 512 and 1 GB devices, 4th cycle is required */
    if(hnand->Info.BlockNbr >= 1024)
    {
      //*(unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset);
    }

    /* Write data to memory */
    for(index = size; index != 0; index--)
    {
      *(unsigned char *)deviceaddress = *(unsigned char *)pBuffer++;
     //*(unsigned char *)deviceaddress = 0x25;
    }

    *(unsigned char *)((unsigned int)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;

    /* Get tick */
    //tickstart = HAL_GetTick();

#if 1
    /* Read status until NAND is ready */
    printk("@@@@@@@@@@@@@@@\n");
    unsigned int i = 0;
    while(HAL_NAND_Read_Status(hnand) != NAND_READY)
    {
    //  if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
      if(i>NAND_WRITE_TIMEOUT)
      {
        return HAL_TIMEOUT;
      }
      i++;
    }
    printk("@@@@@@@@@@@@@@@\n");

#endif
/* Increment written pages number */
    numpageswritten++;

    /* Decrement pages to write */
    NumPageToWrite--;

 /* Increment the NAND address */
    addressstatus = HAL_NAND_Address_Inc(hnand, &nandaddress);
  }

  /* Update the NAND controller state */
  hnand->State = HAL_NAND_STATE_READY;

  /* Process unlocked */
  __HAL_UNLOCK(hnand);

  return HAL_OK;
}

erase function
HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, short block)
{
  unsigned int deviceaddress = 0;
  unsigned int tickstart = 0;

  /* Process Locked */
  __HAL_LOCK(hnand);

  /* Check the NAND controller state */
  if(hnand->State == HAL_NAND_STATE_BUSY)
  {
     return HAL_BUSY;
  }

  /* Identify the device address */
  if(hnand->Init.NandBank == FMC_NAND_BANK2)
  {
    deviceaddress = NAND_DEVICE1;
  }
  else
  {
    deviceaddress = NAND_DEVICE2;
  }

  /* Update the NAND controller state */
  hnand->State = HAL_NAND_STATE_BUSY;

  unsigned char block1 = ((block&0x3)<<6);
  unsigned char block2 = (block>>2);
  printk("block1 = 0x%x, block2 = 0x%x\n", block1, block2);
  /* Send Erase block command sequence */
  *( unsigned char *)((unsigned int)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;

//  *( unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA)) = 0x09;
//  *( unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA)) = 0x11;
  *( unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA)) = block1;
  *( unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA)) = block2;

if(hnand->Info.BlockNbr >= 1024)
  {
    //*( unsigned char *)((unsigned int)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  }

  *( unsigned char *)((unsigned int)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;

  /* Update the NAND controller state */
  hnand->State = HAL_NAND_STATE_READY;

  /* Get tick */
  //tickstart = HAL_GetTick();
  unsigned int i = 0;

  /* Read status until NAND is ready */
  printk("##############\n");
  while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  {
    //if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
    if(i>NAND_WRITE_TIMEOUT)
    {
      /* Process unlocked */
      __HAL_UNLOCK(hnand);

      return HAL_TIMEOUT;
    }
    i++;
  }

  printk("##############\n");
  /* Process unlocked */
  __HAL_UNLOCK(hnand);

  return HAL_OK;

}





正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2015-8-25 23:20:28 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-25 07:48

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表