【Follow me第二季第3期】基础任务:quad-spi flash和octo-spi flash配置及读写速...
<p>在e2 studio中把工程建立起来,选择好芯片型号。</p><div style="text-align: center;"></div>
<p>逐步生成工程文件:</p>
<div style="text-align: center;"></div>
<p><strong><span style="font-size:18px;">quad-spi flash配置</span></strong></p>
<p> </p>
<div style="text-align: center;"></div>
<p>很方便的在e2 studio中配置好QSPI FLASH,CLK也配置好</p>
<div style="text-align: center;"></div>
<p><strong><span style="font-size:18px;">octo-spi flash配置</span></strong></p>
<div style="text-align: center;"></div>
<p>配置完成后点击生成配置和驱动,ospi_performance_test的源码如下,分别提供OSPI flash的读写测试结果:</p>
<pre>
<code>
/**********************************************************************************************************************
* Function Name: ospi_performance_test
* Description: .
* Arguments : data_size
* : ospi_performance_write_result
* : ospi_performance_read_result
* Return Value : .
*********************************************************************************************************************/
void ospi_performance_test(uint32_t data_size,
uint32_t *ospi_performance_write_result,
uint32_t *ospi_performance_read_result)
{
fsp_err_t err;
uint32_t i =1;
if (R_CGC_Open (g_cgc.p_ctrl, g_cgc.p_cfg) != FSP_SUCCESS)
{
__asm("bkpt");
}
while (i)
{
err = R_OSPI_Open(g_ospi.p_ctrl, g_ospi.p_cfg);
if (FSP_SUCCESS != err)
{
__asm("bkpt");
}
#if HIGH_SPEED_MODE
configure_dopi_ospi();
ospi_test_wait_until_wip();
#endif
*ospi_performance_write_result = write_dopi_ospi(data_size);
ospi_test_wait_until_wip();
*ospi_performance_read_result = read_dopi_ospi(data_size);
ospi_test_wait_until_wip();
erase_dopi_ospi();
ospi_test_wait_until_wip();
#if HIGH_SPEED_MODE
configure_spi_ospi();
ospi_test_wait_until_wip();
#endif
err = R_OSPI_Close(g_ospi.p_ctrl);
if (FSP_SUCCESS != err)
{
__asm("bkpt");
}
i--;
}
}
</code></pre>
<p>QSPI flash的写测试实现如下:</p>
<pre>
<code>* Function Name: qspi_write_test
* Description: .
* Argument : block_size
* Return Value : .
*********************************************************************************************************************/
static uint32_t qspi_write_test(uint32_t block_size)
{
fsp_err_t fsp_err;
uint32_t qspi_write_result = 0;
timer_status_t status = {};
fsp_err_t err = FSP_SUCCESS;
spi_flash_protocol_t current_spi_mode;
/* Convert from kB */
block_size *= 1024;
/* The comms mode is EXTENDED_SPI by default */
current_spi_mode = SPI_FLASH_PROTOCOL_EXTENDED_SPI;
/* initialise the QSPI, and change mode to that set in FSP */
err = qpi_init();
if (FSP_SUCCESS == err)
{
/* The comms mode has changed. So if recovering, this new mode required */
current_spi_mode = g_qspi_cfg.spi_protocol;
}
uint32_t page_write_count = 0;
uint8_t* p_mem_addr;
/* Cast to req type */
p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;
while (((page_write_count * SECTOR_SIZE) < block_size)
&& ( FSP_SUCCESS == err ) )
{
/* Erase Flash for one sector */
err = R_QSPI_Erase(&g_qspi_ctrl, p_mem_addr, SECTOR_SIZE);
if (FSP_SUCCESS != err)
{
sprintf(s_print_buffer, "R_QSPI_Erase Failed\r\n");
}
else
{
err = get_flash_status();
if (FSP_SUCCESS != err)
{
sprintf(s_print_buffer, "Failed to get status for QSPI operation\r\n");
}
/* Verify the erased block data */
uint32_t count;
for (count = 0; count < SECTOR_SIZE; count++ )
{
if (DEFAULT_MEM_VAL != p_mem_addr)
{
/* Verification failed, perhaps the ERASE failed */
err = FSP_ERR_NOT_ERASED;
}
}
}
p_mem_addr += SECTOR_SIZE;
page_write_count++;
}
/* Start the test timer */
fsp_err = R_GPT_Start(g_memory_performance.p_ctrl);
/* Handle error */
if (FSP_SUCCESS != fsp_err)
{
/* Fatal error */
SYSTEM_ERROR
}
/* Cast to req type */
p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;
page_write_count = 0;
while (((page_write_count * PAGE_WRITE_SIZE) < block_size)
&& (FSP_SUCCESS == err))
{
if (FSP_SUCCESS == err)
{
/* Write data to QSPI Flash */
/* Each block begins one character shifted along the source text. To avoid regular striping in memory */
err = R_QSPI_Write(&g_qspi_ctrl, &(sp_source), p_mem_addr, PAGE_WRITE_SIZE);
if (FSP_SUCCESS != err)
{
sprintf(s_print_buffer, "R_QSPI_Write Failed\r\n");
}
else
{
err = get_flash_status();
if (FSP_SUCCESS != err)
{
sprintf(s_print_buffer, "Failed to get status for QSPI operation\r\n");
}
}
}
p_mem_addr += PAGE_WRITE_SIZE;
page_write_count++;
}
/* close QSPI module */
deinit_qspi(current_spi_mode);
fsp_err = R_GPT_Stop(g_memory_performance.p_ctrl);
/* Handle error */
if (FSP_SUCCESS != fsp_err)
{
/* Fatal error */
SYSTEM_ERROR
}
fsp_err = R_GPT_StatusGet(g_memory_performance.p_ctrl, &status);
/* Handle error */
if (FSP_SUCCESS != fsp_err)
{
/* Fatal error */
SYSTEM_ERROR
}
fsp_err = R_GPT_Reset(g_memory_performance.p_ctrl);
/* Handle error */
if (FSP_SUCCESS != fsp_err)
{
/* Fatal error */
SYSTEM_ERROR
}
qspi_write_result = status.counter;
return (qspi_write_result);
}</code></pre>
<p>QSPI flash的读测试代码如下:</p>
<pre>
<code>/**********************************************************************************************************************
* Function Name: qspi_read_test
* Description: .
* Argument : block_size
* Return Value : .
*********************************************************************************************************************/
static uint32_t qspi_read_test(uint32_t block_size)
{
fsp_err_t fsp_err;
fsp_err_t err = FSP_SUCCESS;
uint32_t qspi_read_result = 0;
timer_status_t status = {};
spi_flash_protocol_t current_spi_mode;
uint8_t* p_dma_read_buffer;
uint32_t page_read_count;
uint8_t* p_mem_addr;
/* Convert from kB */
block_size *= 1024;
p_dma_read_buffer = pvPortMalloc(block_size);
if (NULL == p_dma_read_buffer)
{
HeapStats_t pxHeapStats;
vPortGetHeapStats(&pxHeapStats);
sprintf(s_print_buffer, "\r\nQSPI malloc operation Failed - Max free mem: %dbytes\r\n",
pxHeapStats.xSizeOfLargestFreeBlockInBytes);
/* Verification failed, perhaps the ERASE failed */
err = FSP_ERR_NOT_ERASED;
}
/* The comms mode of the FLASH device is EXTENDED_SPI by default */
current_spi_mode = SPI_FLASH_PROTOCOL_EXTENDED_SPI;
/* initialise the QSPI, and change mode to that set in FSP */
err = qpi_init();
if (FSP_SUCCESS == err)
{
/* The comms mode has changed. So if recovering, this new mode required */
current_spi_mode = g_qspi_cfg.spi_protocol;
}
/* Start the test timer */
fsp_err = R_GPT_Start(g_memory_performance.p_ctrl);
/* Handle error */
if (FSP_SUCCESS != fsp_err)
{
/* Fatal error */
SYSTEM_ERROR
}
page_read_count = 0;
/* cast to req type */
p_mem_addr = (uint8_t *)QSPI_DEVICE_START_ADDRESS;
while (((page_read_count * PAGE_WRITE_SIZE) < block_size)
&& (FSP_SUCCESS == err))
{
/* Verify the written data */
/* Each block begins one character shifted along the source text. To avoid regular striping in memory */
if ((fsp_err_t) (memcmp (p_mem_addr, &(sp_source), PAGE_WRITE_SIZE)) != FSP_SUCCESS)
{
err = FSP_ERR_NOT_ERASED;
sprintf(s_print_buffer, "\r\nQSPI operation Failed -> Data read does not match with written data\r\n");
}
p_mem_addr += PAGE_WRITE_SIZE;
page_read_count++;
}
fsp_err = R_GPT_Stop(g_memory_performance.p_ctrl);
/* close QSPI module */
deinit_qspi(current_spi_mode);
/* Handle error */
if (FSP_SUCCESS != fsp_err)
{
/* Fatal error */
SYSTEM_ERROR
}
fsp_err = R_GPT_StatusGet(g_memory_performance.p_ctrl, &status);
/* Handle error */
if (FSP_SUCCESS != fsp_err)
{
/* Fatal error */
SYSTEM_ERROR
}
fsp_err = R_GPT_Reset(g_memory_performance.p_ctrl);
/* Handle error */
if (FSP_SUCCESS != fsp_err)
{
/* Fatal error */
SYSTEM_ERROR
}
qspi_read_result = status.counter;
vPortFree(p_dma_read_buffer);
return (qspi_read_result);
}</code></pre>
<p>测试效果如下</p>
<div style="text-align: center;"></div>
<p> </p>
<p>##完成!</p>
<p> </p>
<p>OSPI SPI比Quad SPI快的居然不止两倍?</p>
页:
[1]