返回列表 发新帖

SAM4E-EK开发板代码解读07——NAND_FLASH

[复制链接]

21

主题

31

帖子

1万

积分

允许发帖

积分
10129
发表于 2020-5-13 15:54:47 | 显示全部楼层 | 阅读模式
本帖最后由 Mcuzone_TKN 于 2020-5-15 09:15 编辑

关键词:Microchip Atmel  SAM4E SAM4E-EK  SAM4E16E 芯片 NAND_FLASH

概述:简要运行NAND闪存组件单元测试


NAND Flash的容量较大。整片Flash分为若干个块(Block),每个Block分为若干个(Page)。在每个页中,除了数据区域,也包含若干“多余”的区域,用来进行ECC等操作。在进行擦除操作是,基本单位是“块”;而编程的基本单位是“页”。另外,NAND Flash的物理特性决定了其在编程时,每个bit只能从1变成0,不能从0变成1,所以写之前,必须先对块进行擦除(擦除时把所有位置为1)。
读写时序:因没有地址线,所以读写较为复杂。读写时,需要先发送相应操作命令,然后发送地址,才能进行数据传输。
打开产品光盘SAM4E16E-EK/SAM4E16E-EK中文资料/softpack软件包/Atmel Studio 7,打开08_NAND_FLASH_UNIT_TEST例子。
int main(void)
{
const usart_serial_options_t usart_serial_options = {
  .baudrate   = CONF_TEST_BAUDRATE,
  .charlength = CONF_TEST_CHARLENGTH,
  .paritytype = CONF_TEST_PARITY,
  .stopbits   = CONF_TEST_STOPBITS
};
sysclk_init();
#if SAM
sysclk_enable_peripheral_clock(CONSOLE_UART_ID);
#else
sysclk_enable_hsb_module(SYSCLK_EBI);
sysclk_enable_pbb_module(SYSCLK_SMC_REGS);
sysclk_enable_pbb_module(SYSCLK_HMATRIX);
#endif
board_init();
stdio_serial_init(CONF_TEST_USART, &usart_serial_options);
//定义所有测试用例
DEFINE_TEST_CASE(nand_flash_test_read_id, NULL, run_test_initialization, NULL,
   "NAND Flash initialization and id test");
DEFINE_TEST_CASE(nand_flash_test_raw_read_write, NULL,
   run_test_raw_read_write, NULL,
   "NAND Flash raw data read/write test");
DEFINE_TEST_CASE(nand_flash_test_software_ecc, NULL,
   run_test_software_ecc, NULL,
   "NAND Flash data read/write with software ECC test");
//将测试用例地址放在数组中。
DEFINE_TEST_ARRAY(nand_flash_test_array) = {
  &nand_flash_test_read_id,
  &nand_flash_test_raw_read_write,
  &nand_flash_test_software_ecc,};
//定义测试套件
DEFINE_TEST_SUITE(nand_flash_suite, nand_flash_test_array,
   "NAND Flash component test suite");
//在测试套件中运行所有测试
test_suite_run(&nand_flash_suite);
while (1) {
}
}






回复

使用道具 举报

21

主题

31

帖子

1万

积分

允许发帖

积分
10129
发表于 2020-5-13 16:00:08 | 显示全部楼层
//简要测试NAND FLASH初始化 这个测试调用初始化函数并检查flash id。param测试当前测试用例
static void run_test_initialization(const struct test_case *test)
{
        //Test1:检查initialize函数
        error_code = nand_flash_raw_initialize(&nf_raw, 0, cmd_address,
                        addr_address, data_address);
        test_assert_true(test, error_code == 0,
                        "NAND Flash initialization failed!");

        //获取设备参数
        num_block = nand_flash_model_get_device_size_in_blocks(&nf_raw.model);
        page_size = nand_flash_model_get_page_data_size(&nf_raw.model);

        nf_ecc.raw = nf_raw;

        //检查flash ID
        flash_id = nand_flash_raw_read_id(&nf_raw);
#if (SAM3XA || SAM3S)
        test_assert_true(test, flash_id == 0x9580DA2C,
                "NAND Flash ID error!");
#endif
#if SAM3U
        test_assert_true(test, flash_id == 0xD580CA2C,
                "NAND Flash ID error!");
#endif
#if UC3A3
        test_assert_true(test, flash_id == 0x1580DA2C,
                "NAND Flash ID error!");
#endif

}
回复 支持 反对

使用道具 举报

21

主题

31

帖子

1万

积分

允许发帖

积分
10129
发表于 2020-5-13 16:07:17 | 显示全部楼层
本帖最后由 Mcuzone_TKN 于 2020-5-13 16:09 编辑

//简单测试原始的读写函数,这个测试调用原话的读写并检查数据值。param测试当前测试用例
static void run_test_raw_read_write(const struct test_case *test)
{
        uint32_t i;

        //擦除块,并使用第一个良好的块读写测试
        for (block = (num_block - 1); block > 0; block--) {
                error_code = nand_flash_raw_erase_block(&nf_raw, block);
                if (!error_code) {
                        break;
                }
        }
        //检查擦除结果
        test_assert_true(test, block != 0,
                        "All block erase failed!");

        //重置读缓冲区。
        memset(read_buffer, 0, sizeof(read_buffer));

        //从已擦除的NAND闪存块中读取第一页
        nand_flash_raw_read_page(&nf_raw, block, 0, read_buffer, 0);
        //检查删除结果的数据内容
        for (i = 0; i < page_size; i++) {
                if (read_buffer != 0xFF) {
                        error_code = 1;
                        break;
                }
        }
        test_assert_true(test, error_code == 0,
                        "The content of the block erase result error!");

        //在SRAM中准备一个页面大小的缓冲区
        for (i = 0; i < page_size; i++) {
                write_buffer = i & 0xFF;
        }

        //重置缓冲区
        memset(read_buffer, 0, sizeof(read_buffer));

        //给NAND FLASH写页
        error_code = nand_flash_raw_write_page(&nf_raw, block, 0, write_buffer,
                        0);
        //从NAND Flash里面读页/
        nand_flash_raw_read_page(&nf_raw, block, 0, read_buffer, 0);

        //测试读缓冲区是否与SRAM缓冲区相同
        error_code = memcmp(read_buffer, write_buffer, sizeof(write_buffer));

        //检查擦除结果
        test_assert_true(test, error_code == 0,
                        "The raw read/write functions test failed!");

}
回复 支持 反对

使用道具 举报

21

主题

31

帖子

1万

积分

允许发帖

积分
10129
发表于 2020-5-13 16:17:36 | 显示全部楼层
//简要测试软件ECC的读写功能
本测试调用软件ECC的读写功能,并检查数据值。
static void run_test_software_ecc(const struct test_case *test)
{
        uint32_t i;

        //擦除块,并使用第一个良好的块读写测试
        for (block = (num_block - 1); block > 0; block--) {
                error_code = nand_flash_raw_erase_block(&nf_raw, block);
                if (!error_code) {
                        break;
                }
        }
        //检查擦除结果
        test_assert_true(test, block != 0,
                        "All block erase failed!");

        //重置读缓冲区
        memset(read_buffer, 0, sizeof(read_buffer));

        //从已擦除的NANDFLASH中读取第一页
        nand_flash_raw_read_page(&nf_raw, block, 0, read_buffer, 0);
        //检查删除结果的数据内容
        for (i = 0; i < page_size; i++) {
                if (read_buffer[i] != 0xFF) {
                        error_code = 1;
                        break;
                }
        }
        test_assert_true(test, error_code == 0,
                        "The content of the block erase result error!");

        //在SRAM中准备一个页面大小的缓冲区
        for (i = 0; i < page_size; i++) {
                write_buffer[i] = i & 0xFF;
        }

        //重置读缓冲区
        memset(read_buffer, 0, sizeof(read_buffer));

        //往NANDFLASH里面写页
        error_code = nand_flash_ecc_write_page(&nf_ecc, block, 0, write_buffer,
                                spare_buffer);
        //从NANDFLASH里面读页
        nand_flash_ecc_read_page(&nf_ecc, block, 0, read_buffer, spare_buffer);

        //测试读缓冲区是否与SRAM缓冲区相同
        error_code = memcmp(read_buffer, write_buffer, sizeof(write_buffer));

        //检查擦除结果
        test_assert_true(test, error_code == 0,
                        "The software ECC read/write functions test failed!");

        //清除所有块以清除NANDFLASH
        for (i = 0; i < num_block; i++) {
                nand_flash_raw_erase_block(&nf_raw, i);
        }
}

回复 支持 反对

使用道具 举报

发表回复

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

本版积分规则

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