打印

NAND FLASH 设备ID读取错误

[复制链接]
2846|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xuzi_fan|  楼主 | 2011-7-25 15:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这个问题调了好几天了,实在不知道哪出问题,跪求各位大侠帮小弟看看。

    CPU是AT91RM9200 ,FLASH是三星的K9F1G08U0M,出现的问题是FLASH id老是读不正确,有的时候是0x0,有的时候是一串没规律的数字,ReadStatus()放在ReadID()之前的时候,得到的值是0xe0,放在ReadID()的时候得到的值是0x60。

源码:
#include "cpuRegs.h"
typedef unsigned long DWORD;
typedef unsigned char BYTE;
typedef unsigned char UINT8;
typedef unsigned int UINT32;
  
#define  REG32(addr)   *((volatile unsigned long * const) (addr))
#define  REG08(addr)   *((volatile unsigned char * const) (addr))
  
/* Flash commands:*/
#define SERIAL_DATA_INPUT   0x80
#define READ_MODE           0x00
#define RESET_FLASH         0xff
#define SETUP_WRITE         0x10
#define SETUP_ERASE         0x60
#define CONFIRM_ERASE       0xd0
#define READ_STATUS         0x70
#define READ_ID             (0x90)
#define SUSPEND_ERASE       0xb0
#define REGISTER_READ       0xe0
#define READ_END     0x30


#define NAND_ADDR_DATA      0x40000000
#define NAND_ADDR_COMM      0x40200000
#define NAND_ADDR_ADDR      0x40400000
//#define GET_NAND_R_B  ((AT91_PIOC_PDSR & (1<<5)) ? 1 : 0)
/**
  * @brief  CPU输出管脚控制
  * @param  port 端口编号(参考bsp.h)
  * @param  no 管脚编号
  * @param  value 0,置低; 非0,置高
  * @retval 无
  */
void bspPinOut(char port, BYTE no, BYTE value)
{
DWORD temp = (1<<no);
if(port=='A'){
  if(value)
   REG32(AT91C_PIOA_SODR) = temp;
  else
   REG32(AT91C_PIOA_CODR) = temp;
}
else if(port=='B'){
  if(value)
   REG32(AT91C_PIOB_SODR) = temp;
  else
   REG32(AT91C_PIOB_CODR) = temp;
}
else if(port == 'C'){
  if(value)
   REG32(AT91C_PIOC_SODR) = temp;
  else
   REG32(AT91C_PIOC_CODR) = temp;
}
       else if(port=='D'){
               if(value)
   REG32(AT91C_PIOD_SODR) = temp;
  else
   REG32(AT91C_PIOD_CODR) = temp;
       }
}
/**
  * @brief  CPU输出管脚初始化
  * @param  port 端口编号(参考bsp.h)
  * @param  no 管脚编号
  * @param  value 初始化值; 0,置低; 非0,置高
  * @retval 无
  */
void bspPinOutInit(char port, BYTE no, BYTE value)
{
DWORD temp = (1<<no);
if(port == 'A'){
  REG32(AT91C_PIOA_PER) = temp;
  REG32(AT91C_PIOA_OER) = temp;
}
else if(port == 'B'){
  REG32(AT91C_PIOB_PER) = temp;
  REG32(AT91C_PIOB_OER) = temp;
}
else if(port == 'C'){
  REG32(AT91C_PIOC_PER) = temp;
  REG32(AT91C_PIOC_OER) = temp;
}
        else if(port == 'D'){
  REG32(AT91C_PIOD_PER) = temp;
  REG32(AT91C_PIOD_OER) = temp;
}
bspPinOut(port, no, value);
}
/**
  * @brief  CPU外设管脚初始化
  * @param  port 端口编号(参考bsp.h)
  * @param  no 管脚编号
  * @param  value 初始化值; 0,置低; 非0,置高
  * @param  ab   A:选择A复用,B:选择B复用
  * @retval 无
  */
void bspPinPeriInit(char port,BYTE no,char ab)
{
        DWORD temp=(1<<no);
        if(port == 'A'){
         REG32(AT91C_PIOA_PDR) = temp;
             if(ab=='A')
          REG32(AT91C_PIOA_ASR) = temp;
             else if (ab=='B')
                REG32(AT91C_PIOA_BSR) = temp;
}
else if(port == 'B'){
  REG32(AT91C_PIOB_PDR) = temp;
             if(ab=='A')
          REG32(AT91C_PIOB_ASR) = temp;
             else if (ab=='B')
                REG32(AT91C_PIOB_BSR) = temp;
}
else if(port == 'C'){
  REG32(AT91C_PIOC_PDR) = temp;
             if(ab=='A')
          REG32(AT91C_PIOC_ASR) = temp;
             else if (ab=='B')
                REG32(AT91C_PIOC_BSR) = temp;
}
        else if(port == 'D'){
  REG32(AT91C_PIOD_PDR) = temp;
             if(ab=='A')
          REG32(AT91C_PIOD_ASR) = temp;
             else if (ab=='B')
                REG32(AT91C_PIOD_BSR) = temp;
}
      //  bspPinOut(port, no, value);
}
/**
  * @brief  CPU输入管脚初始化
  * @param  port 端口编号(参考bsp.h)
  * @param  no 管脚编号
  * @retval 无
  */
void bspPinInInit(BYTE port, BYTE no)
{
DWORD temp = (1<<no);
if(port == 1){
  REG32(AT91C_PIOA_PER) = temp;
  REG32(AT91C_PIOA_ODR) = temp;
}
else if(port == 2){
  REG32(AT91C_PIOB_PER) = temp;
  REG32(AT91C_PIOB_ODR) = temp;
}
else if(port == 3){
  REG32(AT91C_PIOC_PER) = temp;
  REG32(AT91C_PIOC_ODR) = temp;
}
}

/**
  * @brief  CPU输入管脚状态
  * @param  port 端口编号(参考bsp.h)
  * @param  no 管脚编号
  * @retval 管脚状态: 0,低; 1,高
  */
BYTE bspPinInState(BYTE port, BYTE no)
{
DWORD temp = (1<<no);
if(port == 1){
  if(REG32(AT91C_PIOA_PDSR) & temp) return 1;
}
else if(port == 2){
  if(REG32(AT91C_PIOB_PDSR) & temp) return 1;
}
else if(port == 3){
  if(REG32(AT91C_PIOC_PDSR) & temp) return 1;
}
return 0;
}
void EnableCE()
{
  bspPinOut('C',4, 0);
}
void DisableCE()
{
bspPinOut('C',4, 1);  
}
void Reset(void)
{
    int i;
    EnableCE();
    REG08(NAND_ADDR_COMM) = RESET_FLASH;
//  taskDelay(10);
    for(i=0; i<100000; i++)
     if(bspPinInState(3,5)) break; // If Flash is ready
    DisableCE();
}
unsigned char ReadStatus(void)
{
  unsigned char chipStatus;
  EnableCE();
  REG08(NAND_ADDR_COMM) = READ_STATUS;
  chipStatus = REG08(NAND_ADDR_DATA);
  DisableCE();
  return chipStatus;
}
DWORD ReadID(void)
{
    BYTE v[4];   
    DWORD ret; int i,j;
    EnableCE();
//
    REG08(NAND_ADDR_COMM) = (UINT8)READ_ID;
    REG08(NAND_ADDR_ADDR) = (UINT8)0x00;
   
    ret = ReadStatus();
    printf("i=0x%x\n", ret);
     
   
     taskDelay(10);
    v[0] = REG08(NAND_ADDR_DATA);
    v[1] = REG08(NAND_ADDR_DATA);
    v[2] = REG08(NAND_ADDR_DATA);
    v[3] = REG08(NAND_ADDR_DATA);

    DisableCE();
   ret = (v[3]<<24)|(v[2]<<16)|(v[1]<<8)|v[0];
  //    ret = ((v[0]<<24)|(v[1]<<16)|(v[2]<<8)|v[3]);
    //ret = v[0];
    return ret;
}
/* set the bus interface characteristics based on
    tDS Data Set up Time 30 - ns
    tDH Data Hold Time 20 - ns
    tALS ALE Set up Time 20 - ns
    16ns at 60 MHz ~= 3  */
/*memory mapping structures */
#define SM_ID_RWH (5 << 28)
#define SM_RWH  (1 << 28)
#define SM_RWS  (0 << 24)
#define SM_TDF  (1 << 8)
#define SM_NWS  (3)
#define AT91C_SMC2_ACSS_STANDARD  0
#define AT91C_SMC2_DBW_8      ((unsigned int) 0x2 << 13)
#define AT91C_SMC2_WSEN       ((unsigned int) 0x1 <<  7)
void test(void)
{
     DWORD ret;
     int i;
     bspPinOutInit('C', 4, 1);//set the pc4 in I/O state
     bspPinPeriInit('C',1,'A');
     bspPinPeriInit('C',3,'A');
     bspPinInInit(3, 5);
     /*PC4,PC5*/
  //  REG32(AT91C_PIOC_PPUER) = (1<<5)|(1<<4);

     REG32(AT91C_EBI_CSA)  = 0x0000000A;
     REG32(AT91C_SMC_CSR3) = 0x11005281;
     
     /*REG32(AT91C_SMC_CSR3) = (SM_RWH | SM_RWS |
  AT91C_SMC2_ACSS_STANDARD | AT91C_SMC2_DBW_8 |
  SM_TDF | AT91C_SMC2_WSEN | SM_NWS);*/

     Reset();
      for(i=0; i<100000; i++)
       if(bspPinInState(3,5)) break; // If Flash is ready
       ret = ReadStatus();
    printf("ReadStatus=0x%x\n",ret);
     ret = ReadID();
     printf("ReadID=0x%x\n",ret);
}

相关帖子

沙发
xuzi_fan|  楼主 | 2011-7-25 15:54 | 只看该作者
放在ReadID()之后的时候得到的值是0x60,上面写漏了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

3

帖子

1

粉丝