[活动专区] 【AT-START-F437测评】QPI-FLASH测试

[复制链接]
1012|0
 楼主| aple0807 发表于 2022-12-28 15:38 | 显示全部楼层 |阅读模式
本帖最后由 aple0807 于 2022-12-28 17:42 编辑

QPI是很多高性能MCU的标配,AT32F437也不例外,今天来测试一下板载QPI-FLASH的读写性能如何。

QPI初始化代码如下:
  1. void bsp_qpi_init(void)
  2. {
  3.         intx_alloc();

  4.         intx_disable();

  5.         /* enable the qspi clock */
  6.         crm_periph_clock_enable(CRM_QSPI1_PERIPH_CLOCK, TRUE);
  7.         crm_periph_reset(CRM_QSPI1_PERIPH_RESET, TRUE);
  8.         crm_periph_reset(CRM_QSPI1_PERIPH_RESET, FALSE);

  9.         intx_enable();

  10.         /* switch to cmd port */
  11.         qspi_xip_enable(QPIX, FALSE);

  12.         /* set sclk , AHB / 4*/
  13.         qspi_clk_division_set(QPIX, QSPI_CLK_DIV_4);

  14.         /* set sck idle mode 0 */
  15.         qspi_sck_mode_set(QPIX, QSPI_SCK_MODE_0);

  16.         /* set wip in bit 0 */
  17.         qspi_busy_config(QPIX, QSPI_BUSY_OFFSET_0);

  18.         cmd_cfg.pe_mode_enable = FALSE;
  19.         cmd_cfg.pe_mode_operate_code = 0;
  20.         cmd_cfg.instruction_length = QSPI_CMD_INSLEN_1_BYTE;
  21.         cmd_cfg.read_status_config = QSPI_RSTSC_HW_AUTO;
  22.         cmd_cfg.read_status_enable = FALSE;
  23. }
该接口为AHB外设,时钟设定4分频,即72MHz。
AT32的QPI接口是基于命令处理的,用户配置好命令、时序等内容启动后,硬件自动按照指定的位宽发送/接收数据。
本测试读写均采用DMA方式,这样可以最大限度的发挥QPI的执行速度,特别是读操作。
  1. void qspi_dma_set(dma_dir_type dir, uint8_t *buf, uint32_t length)
  2. {
  3.         dma_init_type dma_init_struct;
  4.         dma_reset(DMA2_CHANNEL1);
  5.         dma_default_para_init(&dma_init_struct);
  6.         dma_init_struct.buffer_size = (length + 3) >> 2; /* using word unit */
  7.         dma_init_struct.loop_mode_enable = FALSE;
  8.         dma_init_struct.direction = dir;
  9.         dma_init_struct.memory_base_addr = (uint32_t)buf;
  10.         dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_WORD;
  11.         dma_init_struct.memory_inc_enable = TRUE;
  12.         dma_init_struct.peripheral_base_addr = (uint32_t)(&(QPIX->dt));
  13.         dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_WORD;
  14.         dma_init_struct.peripheral_inc_enable = FALSE;
  15.         dma_init_struct.priority = DMA_PRIORITY_HIGH;

  16.         dma_init(DMA2_CHANNEL1, &dma_init_struct);

  17.         dmamux_init(DMA2MUX_CHANNEL1, DMAMUX_DMAREQ_ID_QSPI1);
  18.         dmamux_enable(DMA2, TRUE);

  19.         dma_channel_enable(DMA2_CHANNEL1, TRUE);
  20. }
应用层测试代码如下:
  1. if (1 == nortst.check_req || nortst.chk_keep)

  2.         {

  3.                 uint32_t amount = nortst.amount;

  4.                 uint32_t ticks;



  5.                 // 写入数据

  6.                 uint32_t dats = nortst.dat = nortst.dat_first;



  7.                 flash_dbg_print("fix spi mode check : start : R/W : %dMB\n", amount / (1024 * 1024));

  8.                 ticks = app_tick_get();

  9.                 for (nortst.addr = nortst.addr_start; nortst.addr < amount + nortst.addr_start; nortst.addr += SPI_NOR_PAGE_SIZE)

  10.                 {

  11.                         if (nortst.addr % SPI_NOR_SECTOR_SIZE == 0)

  12.                         {

  13.                                 bsp_snor_sector_erase(nortst.addr);

  14.                         }



  15.                         for (int index = 0; index < SPI_NOR_PAGE_SIZE / 4; index++)

  16.                         {

  17.                                 nortst.buff[index].uVal = nortst.dat++;

  18.                         }



  19.                         // 写入一页数据

  20.                         bsp_snor_write(nortst.addr, SPI_NOR_PAGE_SIZE, nortst.buff[0].v);



  21.                         if (0 == (nortst.addr & 0x03FFFF))

  22.                         {

  23.                                 flash_dbg_print("fix spi mode check write data: %d %% \n", (nortst.addr - nortst.addr_start) * 100 / amount);

  24.                         }

  25.                 }

  26.                 flash_dbg_print("fix spi write end: time : %d ms \n", app_tick_get() - ticks);



  27.                 // 读回校验

  28.                 ticks = app_tick_get();

  29.                 nortst.dat = dats;

  30.                 for (nortst.addr = nortst.addr_start; nortst.addr < amount + nortst.addr_start; nortst.addr += SPI_NOR_PAGE_SIZE)

  31.                 {

  32.                         if (nortst.addr % SPI_NOR_SECTOR_SIZE == 0)

  33.                         {

  34.                                 // 读取一扇区数据

  35.                                 bsp_snor_read(nortst.addr, SPI_NOR_SECTOR_SIZE, nortst.buff[0].v);



  36.                                 for (int index = 0; index < SPI_NOR_SECTOR_SIZE / 4; index++)

  37.                                 {

  38.                                         if (nortst.buff[index].uVal != nortst.dat)

  39.                                         {

  40.                                                 nortst.err++;

  41.                                         }

  42.                                         nortst.dat++;

  43.                                 }



  44.                                 if (nortst.err)

  45.                                 {

  46.                                         flash_dbg_print("fix spi mode check err: %d [url=home.php?mod=space&uid=72445]@[/url] %x \n", nortst.err, nortst.addr);

  47.                                         nortst.err = 0;

  48.                                 }

  49.                         }

  50.                 }



  51.                 nortst.check_req = 0;

  52.                 flash_dbg_print("fix qpi mode read and check end : time : %d ms\n", app_tick_get() - ticks);



  53.                 set_u32(nortst.buff, 0, 4096 / 4);



  54.                 nortst.chk_cnt++;

  55.                 if (nortst.err)

  56.                         nortst.chk_err_cnt++;

  57.         }





先写入FLASH一定量的数据,然后读回验证。
在串口终端 输入 : nor check 4 启动测试,测试FLASH容量4MB,测试结果如下图所示:
QPI-FLASH.png
4MB,写46s,读156ms。可以算得Flash写入速度大约87KB/s,读取并验证速度大约25.6MB/s。 写速度受FLASH擦写特性影响等待操作比较耗时。而读操作是无延时的,速度十分感人,这样读取16MB数据也只需要0.7s,比访问内置FLASH也差不了多少了。
QPI暂时测到这里,后面就可以给它加文件系统存储数据了。

代码托管在GITEE,后面评测会一直用这个仓库更新。
https://gitee.com/aple_sun/atf437-start


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

本版积分规则

77

主题

326

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部