有没有人对 TC58CVG2S0HRAIG 有任何经验?带 SPI 的串行 NAND 闪存

问题描述

嘿伙计们,我真的可以使用你们的帮助!

我正在使用的设备具有 TC58CVG2S0HRAIG 串行 nand 闪存,但我无法使其正常工作!

数据表链接: https://media.digikey.com/pdf/Data%20Sheets/Toshiba%20PDFs/TC58CVG2S0HxAIx_Rev1.1_2016-11-08.pdf

问题: 如果页面编程和读取页面之间存在延迟,则数据读取正确!

示例:

int init_SPI()
{
    // Set pion as the slave select for the digital port
    const int _CS = 19;     // D19 at the variant.cpp
                            // 3,D19 is P0.03 (A5)


#if DEBUG
six_deg__print("Enter Init SPI....\n");
#endif

pinMode(_CS,OUTPUT);

SPI.begin();
SPI.setDataMode(SPI_MODE0);
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV16);
delay(1);

char* myString = "Hello World from the Flash Chip!";

char buf[512];
int ret;

long timer = millis();

char buf1[3] = {0x0F,0xA0,0x87};     // clear prot bits in any case
                                                          // a MUST even if the WP Pin is Attached to the VCC

// Send data to Prot Register
digitalWrite(_CS,LOW);                         
SPI.transfer(buf1,sizeof(buf1));
digitalWrite(_CS,HIGH);


// Put the String into our Flash buffer,// We cant point to the string directly as it is static
// and the buffer will be modified with the received data
memcpy(buf,myString,strlen(myString) + 1);

// Transfer the data we want to program and execute the program command
ret = loadProgData(0,&buf[0],strlen(myString) + 1);
#if DEBUG
Serial.print("Load Program Data: ");
Serial.println(ret);
#endif

ret = ProgramExecute(0);
#if DEBUG
Serial.print("Program Execute: ");
Serial.println(ret);
#endif

ret = pageDataRead(0);    
#if DEBUG
Serial.print("Page Data Read: ");
Serial.println(ret);
#endif

delay(3);                                       
memset(buf,0x55,sizeof(buf));
ret = read(0,buf,sizeof(buf));

#if DEBUG
Serial.print("Read: ");
Serial.println(ret);
Serial.println(buf);
Serial.print("Time: ");
Serial.println(millis() - timer);
#endif

if(memcmp(buf,sizeof(myString)) != 0)      
{
    // Bad Block!
    ret = 1;
    #if DEBUG
    Serial.print("Read str does NOT equal Write str!!\n");
    #endif
}
else
{
    ret = 0;
    #if DEBUG
    Serial.print("Read str EQUALS Write str!\n");
    #endif
}

// Init Flash save Mechanism
block_num = BASE_BLOCK;
page_num = BASE_PAGE;
col_num = BASE_COL;


save_last_block_start = block_num;      // in case for some reason it will not start from base block
save_last_page_start = page_num;        // in case for some reason it will not start from base page
save_last_start_time = millis();        // save current time for reconstruction

return ret;   

}

这个函数会起作用,我会看到打印出“Hello World from the Flash Chip!” 和“读str等于写str!”这是我想要的输出

无论如何

此函数将输出 - 读取 str 不等于写入 str:

    int init_SPI()
    {
        // Set pion as the slave select for the digital port
        const int _CS = 19;     // D19 at the variant.cpp
                                // 3,D19 is P0.03 (A5)
    

    #if DEBUG
    six_deg__print("Enter Init SPI....\n");
    #endif

    pinMode(_CS,OUTPUT);

    SPI.begin();
    SPI.setDataMode(SPI_MODE0);
    SPI.setBitOrder(MSBFIRST);
    SPI.setClockDivider(SPI_CLOCK_DIV16);
    delay(1);

    char* myString = "Hello World from the Flash Chip!";
    
    char buf[512];
    int ret;

    long timer = millis();

    char buf1[3] = {0x0F,0x87};     // clear prot bits in any case
                                                              // a MUST even if the WP Pin is Attached to the VCC

    // Send data to Prot Register
    digitalWrite(_CS,LOW);                         
    SPI.transfer(buf1,sizeof(buf1));
    digitalWrite(_CS,HIGH);


    // Put the String into our Flash buffer,// We cant point to the string directly as it is static
    // and the buffer will be modified with the received data
    memcpy(buf,strlen(myString) + 1);

    // Transfer the data we want to program and execute the program command
    ret = loadProgData(0,strlen(myString) + 1);
    #if DEBUG
    Serial.print("Load Program Data: ");
    Serial.println(ret);
    #endif

    ret = ProgramExecute(0);
    #if DEBUG
    Serial.print("Program Execute: ");
    Serial.println(ret);
    #endif
    delay(500);
    ret = pageDataRead(0);    
    #if DEBUG
    Serial.print("Page Data Read: ");
    Serial.println(ret);
    #endif

    delay(3);                                       
    memset(buf,sizeof(buf));
    ret = read(0,sizeof(buf));

    #if DEBUG
    Serial.print("Read: ");
    Serial.println(ret);
    Serial.println(buf);
    Serial.print("Time: ");
    Serial.println(millis() - timer);
    #endif

    if(memcmp(buf,sizeof(myString)) != 0)      
    {
        // Bad Block!
        ret = 1;
        #if DEBUG
        Serial.print("Read str does NOT equal Write str!!\n");
        #endif
    }
    else
    {
        ret = 0;
        #if DEBUG
        Serial.print("Read str EQUALS Write str!\n");
        #endif
    }
   
    // Init Flash save Mechanism
    block_num = BASE_BLOCK;
    page_num = BASE_PAGE;
    col_num = BASE_COL;
    

    save_last_block_start = block_num;      // in case for some reason it will not start from base block
    save_last_page_start = page_num;        // in case for some reason it will not start from base page
    save_last_start_time = millis();        // save current time for reconstruction
    
    return ret;   
} 

注意 programExectue 和 pageDataRead 函数之间的延迟(500)。 出于某种原因,两个函数之间的任何延迟(在现实生活中必须有这种延迟,因为我只想在几个小时后读取数据)导致无法正确读取内存。

附上辅助函数:

void writeEnable()
{
    char buf[] = {W25N_WRITE_ENABLE};
    sendData(buf,sizeof(buf));
}

int loadProgData(uint16_t columnAdd,char* buf,uint32_t dataLen)
{
    if(columnAdd > (uint32_t)MAX_COLUMN)                return 1;
    if(dataLen > (uint32_t)MAX_COLUMN - columnAdd)      return 1;

    char columnHigh = (columnAdd & 0xFF00) >> 8;
    char columnLow = columnAdd & 0xFF;
    char cmdbuf[3] = {0x02,columnHigh,columnLow};

    writeEnable();
    SPI.beginTransaction(SPISettings(8000000,MSBFIRST,SPI_MODE0));
    digitalWrite(_CS,LOW);
    SPI.transfer(cmdbuf,sizeof(cmdbuf));
    SPI.transfer(buf,dataLen);
    digitalWrite(_CS,HIGH);
    SPI.endTransaction();
    return 0;
}

int ProgramExecute(uint32_t pageAdd)
{
    //if(pageAdd > getMaxPage())      return 1;
    if(pageAdd > 131071)   return 1;

    char pageHigh = (char)((pageAdd & 0xFF00) >> 8);
    char pageLow = (char)pageAdd;

    char buf[4] = {0x10,0x00,pageHigh,pageLow};
    sendData(buf,sizeof(buf));
    return 0;
}

int pageDataRead(uint32_t pageAdd)
{
    //if(pageAdd > getMaxPage())      return 1;                 // getMaxPage returns 63,it is the max page with a BLOCK!
    if(pageAdd > 131071)   return 1;

    char pageHigh = (char)((pageAdd & 0xFF00) >> 8);
    char pageLow = (char)(pageAdd);
    
    char buf[4] = {0x13,sizeof(buf));
    return 0;
}

int read(uint16_t columnAdd,uint32_t dataLen)
{
    if(columnAdd > (uint32_t)MAX_COLUMN)            return 1;
    if(dataLen > (uint32_t)MAX_COLUMN - columnAdd)  return 1;  

    char columnHigh = (columnAdd & 0xFF00) >> 8;
    char columnLow = columnAdd & 0xFF;
    char cmdbuf[4] = {0x03,columnLow,0x00};
    SPI.beginTransaction(SPISettings(8000000,HIGH);
    SPI.endTransaction();
    return 0;
}

非常感谢任何和所有帮助!

谢谢!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)