⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nandflash.c

📁 启动代码
💻 C
📖 第 1 页 / 共 3 页
字号:
          byte_loc -= 8;  // 减去两个RS占的长度(4B*2)
          if (byte_loc < 518)   // is data error(is not ECC itself error)
          {
            if (byte_loc < 512)
            {
              printf("excute bch %d: 0x%x --> 0x%x\r\n",
                cnt, buf[byte_loc], buf[byte_loc] ^ (1 << bit_loc));          
              
              buf[byte_loc] = buf[byte_loc] ^ (1 << bit_loc); // correct
            }
            else
            {
              // 暂忽略文件系统信息
              //printf("Is file system error, ignore it\r\n");

              printf("excute bch %d: 0x%x --> 0x%x\r\n",
                cnt, fileSysBuf[byte_loc - 512], fileSysBuf[byte_loc - 512] ^ (1 << bit_loc));

              fileSysBuf[byte_loc - 512] = fileSysBuf[byte_loc - 512] ^ (1 << bit_loc); // correct
            }
          }
          else 
          {
            printf("Is BCH %d ECC itself error, ignore it\r\n", cnt);
            printf("byte_loc = %d\r\n", byte_loc);
          }
        } // end if (ecc_loc == 0xFF)
      } // end for (cnt=0; cnt<2; cnt++)
    } //  end if (status & BCH_CANT_CORRECT_BIT)
  } // end if ((status & BCH_NO_ERR_BIT) != BCH_NO_ERR_BIT)
  else
  {
//    printf("BCH no error\r\n");
  }

  return ret;
}

//********************tools funciton********************************//

static T_U16 getShiftNum(T_U32 tot)
{
  T_U16 i=0;
  
  while (tot>1)
  {
    i++;
    tot=(tot>>1);
  }
  return i;
}


/**
* @BRIEF check cmd_done bit
* @AUTHOR lgj
* @DATE 2005-10-18
* @PARAM T_VOID
* @RETURN
* @RETVAL
*/
static T_BOOL check_cmd_done(T_VOID)
{
  volatile T_U32 status;

  HAL_READ_UINT32(FLASH_CTRL_REG22, status);

  //printf("status = 0x%x\r\n", status);

  if (status & 0x80000000)
    return AK_TRUE;
  else
    return AK_FALSE;
}




/**
* @BRIEF read data from FIFO to memory(cpu mode)
* @AUTHOR lgj
  modify dengjian
 * @DATE 2005-10-18
* @PARAM  *dest: destination pointer.
*     fifo_start: fifo start address.
*     count: word count(32BIT);
* @RETURN
* @RETVAL
* @NOTE   大小端(字节顺序)
*/
static T_VOID CPU_FIFO2memory(T_U32 *dest, T_U32 fifo_start, T_U8 count)
{
  T_U32 tmp;
  T_U32 next_reg_addr;
  volatile T_U32 status;

  //T_U32 dest_value = (T_U32)dest;
  //switch(dest_value%4)
  switch(((T_U32)dest)%4)
  {
    case 0://basic condition
      for (next_reg_addr=fifo_start; next_reg_addr<count; next_reg_addr++)
      {
        // CPU mode read: set dump address, CPU request
        HAL_WRITE_UINT32(FLASH_DMA_REG0, (1 << 29) | ((next_reg_addr & 0x7F) << 21));

        // delay?
        do {
          HAL_READ_UINT32(FLASH_DMA_REG0, status);
        } while (status & (1 << 29));

        HAL_READ_UINT32(FLASH_DMA_REG5, tmp);
        *dest++ = tmp;
        //HAL_READ_UINT32(FLASH_DMA_REG5, *dest++);
        //printf("read tmp = 0x%x\r\n", tmp);
      }
      break;


    default:
      {
        //T_U32 temp_value;
        T_U8 *temp_p8;
        temp_p8 = (T_U8 *)dest;
//        printf("\nnand read not T_U32 dest,dest =0x%x",dest);
        for (next_reg_addr=fifo_start; next_reg_addr<count; next_reg_addr++)
        {
          // CPU mode read: set dump address, CPU request
          HAL_WRITE_UINT32(FLASH_DMA_REG0, (1 << 29) | ((next_reg_addr & 0x7F) << 21));

          // delay?
          do {
            HAL_READ_UINT32(FLASH_DMA_REG0, status);
          } while (status & (1 << 29));
          /*
          //this read is wrong,FLASH_DMA_REG5 is not fifo, it is a 32-bit register
          HAL_READ_UINT8(FLASH_DMA_REG5, *temp_p8++);
          HAL_READ_UINT8(FLASH_DMA_REG5, *temp_p8++);
          HAL_READ_UINT8(FLASH_DMA_REG5, *temp_p8++);
          HAL_READ_UINT8(FLASH_DMA_REG5, *temp_p8++);
          */
          /*
          HAL_READ_UINT32(FLASH_DMA_REG5, temp_value);
          *temp_p8++ = temp_value & 0xFF;
          *temp_p8++ = (temp_value>>8) & 0xFF;
          *temp_p8++ = (temp_value>>16) & 0xFF;
          *temp_p8++ = (temp_value>>24) & 0xFF;
          */
          //maybe this is the fastest code,cpu control register to memory
          *temp_p8++ = (*(volatile T_U32*)FLASH_DMA_REG5) & 0xFF;
          *temp_p8++ = ((*(volatile T_U32*)FLASH_DMA_REG5)>>8) & 0xFF;
          *temp_p8++ = ((*(volatile T_U32*)FLASH_DMA_REG5)>>16) & 0xFF;
          *temp_p8++ = ((*(volatile T_U32*)FLASH_DMA_REG5)>>24) & 0xFF;
                    HAL_READ_UINT32(FLASH_DMA_REG5, tmp);
        }
        break;
      }

  }
}

//******************************************read chipstatus control(not sure) *******************************//



/**
* @BRIEF read one physical page from nandflash directly.
* @AUTHOR Junhua Zhao
* @DATE 2006-3-30
* @PARAM PhyPage:physical page no.
*  *data:pointer of data buffer
* @RETURN
* @RETVAL
*/
//***********************************************************************************
//tip:chip select by mtd manager, this driver just read current chip page data
//***********************************************************************************
static T_S16 nf_read_page(T_U8 chip,T_U32 page, T_U32 offset, T_U8 *data, T_S32 len,T_BOOL bECC)
{
  T_U32 status;
  T_U16 j;
  T_U32 columnAddr, rowAddr;

  if(data == AK_NULL)
  {
    printf("\r\nnand dirver read:all of fs_info and data is AK_NULL\r\n");
    return NF_SUCCESS;//because mtd would handle error block,just alert,only write faile return falsereturn AK_FALSE;
    }

  //calculate column address and row address
  rowAddr = page;
    columnAddr = offset;
    
   
#ifdef CHK_STA_BEFORE
    if (NF_SUCCESS != nf_check_status(chip))
        return NF_ERR_LAST;
#endif

  //read data and do ecc check
  if( data != AK_NULL )
  {
    #ifdef STORE_ALL_INT
    store_all_int();//need or not?
    #endif

        if(bECC)
        {
            //enable ECC encode
            HAL_WRITE_UINT32(FLASH_ECC_REG4, ECC_DECODE_CONFIG);
        }
        else
        {
            //disable ECC encode
            HAL_WRITE_UINT32(FLASH_ECC_REG4, ECC_DECODE_DISCFG | ((len-1) << 17));
        }

    //***************************push nandflash command,if need,make next code be a function*************************//
    {
      T_U32 *reg_addr = (T_U32 *) FLASH_CTRL_REG0;

      // sta_clr = 0,
      HAL_WRITE_UINT32(FLASH_CTRL_REG22, 0x00);

      //nandflash read1 command
      HAL_WRITE_UINT32(reg_addr++, (NFLASH_READ1 << 11) | COMMAND_CYCLES_CONF);

      //nandflash byte offset in physic page
      HAL_WRITE_UINT32(reg_addr++, ((columnAddr & 0xff) << 11) | ADDRESS_CYCLES_CONF);
      HAL_WRITE_UINT32(reg_addr++, (((columnAddr & 0xff00)>>8) << 11) | ADDRESS_CYCLES_CONF);

      //nandflash physic page address
      HAL_WRITE_UINT32(reg_addr++, ((rowAddr & 0xff) << 11) | ADDRESS_CYCLES_CONF);
      HAL_WRITE_UINT32(reg_addr++, (((rowAddr & 0xff00)>>8) << 11) | ADDRESS_CYCLES_CONF);

      //*******if nand flash >= 256M, this address seek would send******//
      if(3==chipInfo.row_cycle)
      {
        HAL_WRITE_UINT32(reg_addr++, (((rowAddr & 0xff0000)>>16) << 11) | ADDRESS_CYCLES_CONF);
      }


      //nandflash read2 command,this is a wait command
      HAL_WRITE_UINT32(reg_addr++, (NFLASH_READ2 << 11) | COMMAND_CYCLES_CONF|(1 << 10));

      HAL_WRITE_UINT32(reg_addr++, WAIT_JUMP_CONF);// wait R/B rising edge
      //HAL_WRITE_UINT32(reg_addr++, (BASIC_DLYCNT << 11) | DELAY_CNT_CONF);

      //******************read one times***********//
      HAL_WRITE_UINT32(reg_addr, ((len-1) << 11) | READ_DATA_CONF | LAST_CMD_FLAG);

    }
    // excute operation, CE1, enable power saving, CE# keep LOW wait R/B
    //HAL_WRITE_UINT32(FLASH_CTRL_REG22, NCHIP_SELECT(rowAddr%NFLASH_PAGE_SIZE)|DEFAULT_GO|SAVE_MODE_FLAG);
    //HAL_WRITE_UINT32(FLASH_CTRL_REG22, NCHIP_SELECT(0)|DEFAULT_GO|SAVE_MODE_FLAG);
    HAL_WRITE_UINT32(FLASH_CTRL_REG22, NCHIP_SELECT(chip)|DEFAULT_GO);

    // wait reg22 fifo command send done
    //printf("before check cmd ");
    while(!check_cmd_done());
    

    // 从FIFO中读出数据(data部分), 存到memory中
    //DMA_FIFO2memory((T_U32*) data, 0, (T_U8) (NFC_FIFO_SIZE/sizeof(T_U32)));
    //CPU_FIFO2memory((T_U32*) data, 0, (T_U8) (NFC_FIFO_SIZE/sizeof(T_U32)));

    switch(((T_U32)data) & 0x01)
    {
      case 0:
/*                if (bECC)
                    DMA_FIFO2memory((T_U32*)data,0,NFC_FIFO_SIZE/4);
                else
				    DMA_FIFO2memory((T_U32*)data,0,len/4);
				break;
*/				
      case 1:
                if (bECC)
                    CPU_FIFO2memory((T_U32*)data,0,NFC_FIFO_SIZE/4);
                else
            CPU_FIFO2memory((T_U32*)data,0,len/4);
        break;
      default:
        printf("\r\nimpoisble read \r\n");
        break;
    }

    #ifdef STORE_ALL_INT
        restore_all_int(); //need or not??
    #endif// need or not??
  }

    return NF_SUCCESS;
}


//******************************check ecc*****************************************//
/*
* @BRIEF ECC check and correct error for a page.
* @AUTHOR Junhua Zhao
   MODIFY Dengjian
* @DATE 2006-01-07
* @PARAM UINT8 *pData: the main area data(must be 512 byte)
*   UINT8 *pSpare: the spare area data (file system information,must be 6 byte)
* @RETURN if no error or correct error successfully return AK_TRUE,otherwise return AK_FALSE
* @NOTE
*/
T_BOOL ECC_Check(T_U8 *data, T_U8 *fs, T_U16 CRC_FS)
{
  T_S32 ret;
  ret = do_ECC_coerr(data, fs);

  if (ret < ECC_NEED_CRC_CHECK)
  {
    return AK_TRUE;
  }   
  else  if (ret >= ECC_CANT_CORRECT)
  {
    printf("Too much error, ECC can't correct\r\n");
    return AK_FALSE;    
  }
  else
  {
    T_U16 CRC;
    // check CRC
    printf("More than 2 error, need check CRC\r\n");

    // get CRC
    CRC = (T_U16)MakeCRC(CRC_TYPE_CRC16, data, NFC_FIFO_SIZE);
//      printf("org CRT = 0x%x, calculate CRC = 0x%x\r\n", tmp, CRC);
    if (CRC != CRC_FS)
    {
      printf("CRC check error, ECC fail\r\n");
      return AK_FALSE;
    }
  }
}
//******************************check ecc done*****************************************


//******************************************init,read chipID and set information(not sure)*******************************//

/**
* @BRIEF 配置并口为NAND FLASH, 配置AC参数
* @AUTHOR lgj
* @DATE 2005-10-13
* @PARAM T_VOID
* @RETURN
* @RETVAL
*/
T_VOID pp_nandf_init(T_VOID)
{
  T_U32 tmp;

  // 配置并口为NAND FLASH, 在FPGA上如何验证?
  HAL_READ_UINT32(0x20090020, tmp);
  tmp |= (1 << 16);
  HAL_WRITE_UINT32(0x20090020, tmp);
  // close host interface pull up control
  HAL_READ_UINT32(0x20090060, tmp);
  tmp |= (1 << 24);
  HAL_WRITE_UINT32(0x20090060, tmp);
  HAL_READ_UINT32(0x20090064, tmp);
  tmp |= 0x1FFFF;
  HAL_WRITE_UINT32(0x20090064, tmp);

  /*
  HAL_READ_UINT32(ANALOG_CONTROL1, tmp);
  tmp |= (1 << 16);
  HAL_WRITE_UINT32(ANALOG_CONTROL1, tmp);
  // close host interface pull up control
  HAL_READ_UINT32(PULL_UP_REG1, tmp);
  tmp |= (1 << 24);
  HAL_WRITE_UINT32(PULL_UP_REG1, tmp);
  HAL_READ_UINT32(PULL_UP_REG2, tmp);
  tmp |= 0x1FFFF;
  HAL_WRITE_UINT32(PULL_UP_REG2, tmp);
  */

  //	HAL_WRITE_UINT32(FLASH_CTRL_REG23, 0xC3671);
  //	HAL_WRITE_UINT32(FLASH_CTRL_REG24, 0xF3637);


  // bypass ECC, length is 528Byte
  HAL_WRITE_UINT16(FLASH_ECC_REG0 + 0x02, (1 << 12) | 0x210);
}

/**
* @BRIEF init current nandchip
* @AUTHOR dengjian
* @DATE 2006-01-05
* @PARAM
* @RETURN chip id
* @RETVAL
*/
T_S16 nf_init()
{
  T_U32 i;
  T_S16 ret;

//  if (bNandInit)
//    return NF_SUCCESS;

  pp_nandf_init();
  ret = read_chipinfo();
  if (ret != NF_SUCCESS)
  {
    printf("error read chipInfo\r\n");
    return ret;
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -