1282 lines
46 KiB
C
1282 lines
46 KiB
C
|
/****************************************************************************
|
|||
|
|
|||
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|||
|
|
|||
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|||
|
be copied by any method or incorporated into another program without
|
|||
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|||
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|||
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|||
|
liability for its use in any way and conveys no license or title under
|
|||
|
any patent or copyright and makes no representation or warranty that this
|
|||
|
Information is free from patent or copyright infringement.
|
|||
|
|
|||
|
****************************************************************************/
|
|||
|
#include "chip_reg_base.h"
|
|||
|
#include "hw_reg_api.h"
|
|||
|
#include "sfc_rf.h"
|
|||
|
#include "apb_cache_reg.h"
|
|||
|
#include "pin_rf.h"
|
|||
|
#include "gpio_reg.h"
|
|||
|
#include "gpio_mtx_reg.h"
|
|||
|
|
|||
|
#include "sfc.h"
|
|||
|
#include "ahb_hw.h"
|
|||
|
#include "flash.h"
|
|||
|
#include "ahb.h"
|
|||
|
#include "cpu.h"
|
|||
|
#include "gp_timer.h"
|
|||
|
#include "gpio_mtx.h"
|
|||
|
#include "apb.h"
|
|||
|
#include "clk_hw.h"
|
|||
|
|
|||
|
#include "iot_clock.h"
|
|||
|
#include "iot_config.h"
|
|||
|
#include "dbg_io.h"
|
|||
|
#include "iot_io.h"
|
|||
|
#include "iot_bitops.h"
|
|||
|
|
|||
|
#include "os_utils_api.h"
|
|||
|
#include "iot_errno_api.h"
|
|||
|
#include "os_mem_api.h"
|
|||
|
|
|||
|
#include "dtest_printf.h"
|
|||
|
|
|||
|
#define DTEST_SFC_OFFSET (0x00)
|
|||
|
#define DTEST_SFC_CACHE_FOR_READ 0
|
|||
|
#define DTEST_SFC_CORE12_RW_CNT 100
|
|||
|
#define DTEST_SFC_CORE12_CACHE_READ_CNT 1000
|
|||
|
#define DTEST_SFC_CORE12_SCRATCH_ADDR (AHB_REG_LITE_BASEADDR + CFG_SCRATCH5_ADDR)
|
|||
|
|
|||
|
#define DTEST_SFC_CASE_GET_ID (1 << 0)
|
|||
|
#define DTEST_SFC_CASE_STS_REG (1 << 1)
|
|||
|
#define DTEST_SFC_CASE_ERASE (1 << 2)
|
|||
|
#define DTEST_SFC_CASE_WRITE (1 << 3)
|
|||
|
#define DTEST_SFC_CASE_READ (1 << 4)
|
|||
|
#define DTEST_SFC_CASE_FULL_WR (1 << 5)
|
|||
|
#define DTEST_SFC_CASE_PUYA_FACTORY (1 << 6)
|
|||
|
#define DTEST_SFC_CASE_MULTICORE (1 << 7)
|
|||
|
#define DTEST_SFC_CASE_TWO_CS (1 << 8)
|
|||
|
#define DTEST_SFC_CASE_REMAP (1 << 9)
|
|||
|
#define DTEST_SFC_CASE_MONITOR_SIG (1 << 10)
|
|||
|
|
|||
|
/* the flash chip of GD\puya is on the FPGA development board, with a size of 4m */
|
|||
|
#define DTEST_SFC_ID_CHECK(id_mf, id_mem) do {\
|
|||
|
if ((id_mf != FLASH_VENDOR_ID_GD && id_mf != FLASH_VENDOR_ID_PUYA) || id_mem != FLASH_SIZE_4MB) \
|
|||
|
goto failed; \
|
|||
|
} while (0)
|
|||
|
|
|||
|
uint8_t g_flash_mid = 0x0; //Manufacturer ID, FLASH_VENDOR_ID_GD or FLASH_VENDOR_ID_PUYA
|
|||
|
|
|||
|
uint8_t rdata[0x100] = {0};
|
|||
|
uint8_t wdata[0x100] = {1,2,3,4,5,6,7,8,9,0,255,254,253,252,251,250};
|
|||
|
|
|||
|
static uint32_t dtest_sfc_get_id_test()
|
|||
|
{
|
|||
|
uint8_t param[0x100] = {0};
|
|||
|
|
|||
|
dcase_start("get flash chip id test\n");
|
|||
|
|
|||
|
sfc_read_sfdp(param, 0x0, 0x4);
|
|||
|
dprintf("SFDP data(0x0): %x %x %x %x\n", param[0], param[1], param[2], param[3]);
|
|||
|
sfc_read_sfdp(param, 0x10, 0x4);
|
|||
|
dprintf("SFDP data(0x10): %x %x %x %x\n", param[0], param[1], param[2], param[3]);
|
|||
|
|
|||
|
dprintf("start get flash id test, the correct manufacturer id is 0x85, device id is 0x15\n");
|
|||
|
|
|||
|
/* RDID command read manufacturer id(1byte),memory type(1byte), memory density(1byte) */
|
|||
|
g_sfc_ctrl->get_dev_id(rdata);
|
|||
|
dprintf("Manufacturer ID(api):0x%x, memory type:0x%x\n",rdata[0], rdata[1]);
|
|||
|
if (rdata[0] != FLASH_VENDOR_ID_GD && rdata[0] != FLASH_VENDOR_ID_PUYA) {
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
|
|||
|
/* REMS command read manufacturer id(1byte), device id(1byte) */
|
|||
|
sfc_qspi_get_id_mult(rdata, MOD_SFC_SERIAL);
|
|||
|
dprintf("Manufacturer ID(serial):0x%x, device id:0x%x\n",rdata[0], rdata[1]);
|
|||
|
DTEST_SFC_ID_CHECK(rdata[0], rdata[1]);
|
|||
|
|
|||
|
sfc_qspi_get_id_mult(rdata, MOD_SFC_DUAL);
|
|||
|
dprintf("Manufacturer ID(qual):0x%x, device id:0x%x\n",rdata[0], rdata[1]);
|
|||
|
DTEST_SFC_ID_CHECK(rdata[0], rdata[1]);
|
|||
|
|
|||
|
sfc_qspi_get_id_mult(rdata, MOD_SFC_QUAD);
|
|||
|
dprintf("Manufacturer ID(quad):0x%x, device id:0x%x\n",rdata[0], rdata[1]);
|
|||
|
DTEST_SFC_ID_CHECK(rdata[0], rdata[1]);
|
|||
|
|
|||
|
g_flash_mid = rdata[0];
|
|||
|
|
|||
|
dcase_success();
|
|||
|
return ERR_OK;
|
|||
|
failed:
|
|||
|
dcase_failed();
|
|||
|
return ERR_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
static uint32_t dtest_sfc_get_sts_reg_test()
|
|||
|
{
|
|||
|
uint8_t data, reg;
|
|||
|
|
|||
|
dcase_start("get flash chip status register test\n");
|
|||
|
|
|||
|
/* reg0(cmd 0x05): status register s0 ~ s7 */
|
|||
|
reg = 0;
|
|||
|
g_sfc_ctrl->get_sts_reg(&data, reg);
|
|||
|
dprintf("get reg[%d]: %08x\n", reg, data);
|
|||
|
|
|||
|
/* reg1(cmd 0x35): status register s8 ~ s15 */
|
|||
|
reg = 1;
|
|||
|
g_sfc_ctrl->get_sts_reg(&data, reg);
|
|||
|
dprintf("get reg[%d]: %08x, quad flag:%d\n", reg, data, g_sfc_ctrl->is_quad);
|
|||
|
|
|||
|
/* check whether the QUAD mode is enabled */
|
|||
|
if (((g_sfc_ctrl->is_quad << 1) ^ data) & QUAD_ENA_BIT_S9) {
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
|
|||
|
dcase_success();
|
|||
|
return ERR_OK;
|
|||
|
failed:
|
|||
|
dcase_failed();
|
|||
|
return ERR_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
static uint32_t dtest_sfc_erase_test()
|
|||
|
{
|
|||
|
uint32_t i;
|
|||
|
uint32_t flash_base_addr = ICACHE0_SFC_RAM_BASEADDR, flash_size_total;
|
|||
|
uint8_t data_test = 0x55, data_erase = 0xff, data_read1, data_read2;
|
|||
|
|
|||
|
dcase_start("flash chip erase test\n");
|
|||
|
|
|||
|
/* init wdata */
|
|||
|
os_mem_set(wdata, data_test, sizeof(wdata));
|
|||
|
|
|||
|
/* page erase test */
|
|||
|
/* GD flash chip page erase will now fail */
|
|||
|
if (g_flash_mid == FLASH_VENDOR_ID_PUYA) {
|
|||
|
g_sfc_ctrl->erase_page(DTEST_SFC_OFFSET, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write(wdata, DTEST_SFC_OFFSET, sizeof(wdata), MOD_SFC_PROG_QUAD, MOD_SW_MODE_DIS);
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
data_read1 = *(volatile uint8_t*)(flash_base_addr + DTEST_SFC_OFFSET);
|
|||
|
|
|||
|
g_sfc_ctrl->erase_page(DTEST_SFC_OFFSET, MOD_SW_MODE_DIS);
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
data_read2 = data_erase;
|
|||
|
for (i = 0; i < PAGE_PROGRAM_SIZE; i++) {
|
|||
|
data_read2 &= *(volatile uint8_t*)(flash_base_addr + DTEST_SFC_OFFSET + i);
|
|||
|
}
|
|||
|
if (data_read1 != data_test || data_read2 != data_erase) {
|
|||
|
dprintf("erese page failed, before:0x%x, after:0x%x\n", data_read1, data_read2);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* sector erase test */
|
|||
|
g_sfc_ctrl->erase_sector(DTEST_SFC_OFFSET, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write(wdata, DTEST_SFC_OFFSET, sizeof(wdata), MOD_SFC_PROG_QUAD, MOD_SW_MODE_DIS);
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
data_read1 = *(volatile uint8_t *)(flash_base_addr + DTEST_SFC_OFFSET);
|
|||
|
|
|||
|
g_sfc_ctrl->erase_sector(DTEST_SFC_OFFSET, MOD_SW_MODE_DIS);
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
data_read2 = data_erase;
|
|||
|
for (i = 0; i < SECTOR_ERASE_SIZE; i++) {
|
|||
|
data_read2 &= *(volatile uint8_t*)(flash_base_addr + DTEST_SFC_OFFSET + i);
|
|||
|
}
|
|||
|
if (data_read1 != data_test || data_read2 != data_erase) {
|
|||
|
dprintf("erese sector failed, before:0x%x, after:0x%x\n", data_read1, data_read2);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
|
|||
|
/* block erase test */
|
|||
|
g_sfc_ctrl->erase_block(DTEST_SFC_OFFSET, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write(wdata, DTEST_SFC_OFFSET, sizeof(wdata), MOD_SFC_PROG_QUAD, MOD_SW_MODE_DIS);
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
data_read1 = *(volatile uint8_t*)(flash_base_addr + DTEST_SFC_OFFSET);
|
|||
|
|
|||
|
g_sfc_ctrl->erase_block(DTEST_SFC_OFFSET, MOD_SW_MODE_DIS);
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
data_read2 = data_erase;
|
|||
|
for (i = 0; i < BLOCK_ERASE_64K_SIZE; i++) {
|
|||
|
data_read2 &= *(volatile uint8_t*)(flash_base_addr + DTEST_SFC_OFFSET + i);
|
|||
|
}
|
|||
|
if (data_read1 != data_test || data_read2 != data_erase) {
|
|||
|
dprintf("erese block failed, before:0x%x, after:0x%x\n", data_read1, data_read2);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
|
|||
|
/* chip erase test */
|
|||
|
g_sfc_ctrl->erase_chip();
|
|||
|
g_sfc_ctrl->write(wdata, DTEST_SFC_OFFSET, sizeof(wdata), MOD_SFC_PROG_QUAD, MOD_SW_MODE_DIS);
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
data_read1 = *(volatile uint8_t*)(flash_base_addr + DTEST_SFC_OFFSET);
|
|||
|
|
|||
|
g_sfc_ctrl->erase_chip();
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
data_read2 = data_erase;
|
|||
|
flash_size_total = (1 << (flash_get_dev_size() - FLASH_1M)) * 0x100000;
|
|||
|
for (i = 0; i < flash_size_total; i++) { //4m flash
|
|||
|
data_read2 &= *(volatile uint8_t*)(flash_base_addr + i);
|
|||
|
}
|
|||
|
if (data_read1 != data_test || data_read2 != data_erase) {
|
|||
|
dprintf("erese chip failed, before:0x%x, after:0x%x\n", data_read1, data_read2);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
|
|||
|
dcase_success();
|
|||
|
return ERR_OK;
|
|||
|
failed:
|
|||
|
dcase_failed();
|
|||
|
return ERR_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
static uint32_t dtest_sfc_write_test()
|
|||
|
{
|
|||
|
uint32_t i;
|
|||
|
uint32_t flash_base_addr = ICACHE0_SFC_RAM_BASEADDR;
|
|||
|
uint8_t data_test = 0x55, data_read;
|
|||
|
|
|||
|
dcase_start("flash chip write test\n");
|
|||
|
|
|||
|
/* init wdata */
|
|||
|
os_mem_set(wdata, data_test, sizeof(wdata));
|
|||
|
|
|||
|
/* wirte flash by stand program mode */
|
|||
|
g_sfc_ctrl->erase_sector(DTEST_SFC_OFFSET, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write(wdata, DTEST_SFC_OFFSET, sizeof(wdata), MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS);
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
for (i = 0; i < sizeof(rdata); i++) {
|
|||
|
data_read = *(volatile uint8_t*)(flash_base_addr + DTEST_SFC_OFFSET + i);
|
|||
|
if (data_read != data_test) {
|
|||
|
dprintf("stand write failed, index:%d, wdata:0x%x, rdata:0x%x\n", i, data_test, data_read);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* wirte flash by quad program mode */
|
|||
|
data_test = 0xaa;
|
|||
|
os_mem_set(wdata, data_test, sizeof(wdata));
|
|||
|
g_sfc_ctrl->erase_sector(DTEST_SFC_OFFSET, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write(wdata, DTEST_SFC_OFFSET, sizeof(wdata), MOD_SFC_PROG_QUAD, MOD_SW_MODE_DIS);
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
for (i = 0; i < sizeof(rdata); i++) {
|
|||
|
data_read = *(volatile uint8_t*)(flash_base_addr + DTEST_SFC_OFFSET + i);
|
|||
|
if (data_read != data_test) {
|
|||
|
dprintf("quad write failed, index:%d, wdata:0x%x, rdata:0x%x\n", i, data_test, data_read);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
dcase_success();
|
|||
|
return ERR_OK;
|
|||
|
failed:
|
|||
|
dcase_failed();
|
|||
|
return ERR_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
static uint32_t dtest_sfc_read_test()
|
|||
|
{
|
|||
|
uint8_t d_sig, d_high, d_dual, d_quad, d_dual_io, d_quad_io, d_quad_io_word;
|
|||
|
|
|||
|
dcase_start("flash chip read test\n");
|
|||
|
|
|||
|
g_sfc_ctrl->erase_sector(DTEST_SFC_OFFSET, MOD_SW_MODE_DIS);
|
|||
|
wdata[0] = 0xbb;
|
|||
|
g_sfc_ctrl->write(wdata, DTEST_SFC_OFFSET,sizeof(wdata), MOD_SFC_PROG_QUAD, MOD_SW_MODE_DIS);
|
|||
|
|
|||
|
g_sfc_ctrl->read(&d_sig, DTEST_SFC_OFFSET, sizeof(d_sig), MOD_SFC_READ_SIG);
|
|||
|
g_sfc_ctrl->read(&d_high, DTEST_SFC_OFFSET, sizeof(d_high), MOD_SFC_READ_HIGH_SPD);
|
|||
|
g_sfc_ctrl->read(&d_dual, DTEST_SFC_OFFSET, sizeof(d_dual), MOD_SFC_READ_DUAL_FAST);
|
|||
|
g_sfc_ctrl->read(&d_quad, DTEST_SFC_OFFSET, sizeof(d_quad), MOD_SFC_READ_QUAD_FAST);
|
|||
|
g_sfc_ctrl->read(&d_dual_io, DTEST_SFC_OFFSET, sizeof(d_dual_io), MOD_SFC_READ_DUAL_IO_FAST);
|
|||
|
g_sfc_ctrl->read(&d_quad_io, DTEST_SFC_OFFSET, sizeof(d_quad_io), MOD_SFC_READ_QUAD_IO_FAST);
|
|||
|
g_sfc_ctrl->read(&d_quad_io_word, DTEST_SFC_OFFSET, sizeof(d_quad_io_word), MOD_SFC_READ_QUAD_IO_WORD_FAST);
|
|||
|
|
|||
|
if (d_sig != wdata[0] || d_high != wdata[0] || d_dual != wdata[0] ||
|
|||
|
d_quad != wdata[0] || d_dual_io != wdata[0] || d_quad_io != wdata[0] ||
|
|||
|
d_quad_io_word != wdata[0]) {
|
|||
|
dprintf("flash read failed, sig:%02x, high:%02x, dual:%02x, quad: %02x,"
|
|||
|
"dual_io: %02x, quad_io: %02x, quad_io_word: %02x\n", d_sig, d_high,
|
|||
|
d_dual, d_quad, d_dual_io, d_quad_io, d_quad_io_word);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
|
|||
|
dcase_success();
|
|||
|
return ERR_OK;
|
|||
|
failed:
|
|||
|
dcase_failed();
|
|||
|
return ERR_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
static uint32_t dtest_sfc_flash_full_wr_test()
|
|||
|
{
|
|||
|
uint32_t i;
|
|||
|
uint32_t flash_base_addr = ICACHE0_SFC_RAM_BASEADDR, flash_size_total;
|
|||
|
uint8_t data_test = 0x55, data_read;
|
|||
|
|
|||
|
dcase_start("flash chip full write/read test\n");
|
|||
|
|
|||
|
flash_size_total = (1 << (flash_get_dev_size() - FLASH_1M)) * 0x100000;
|
|||
|
|
|||
|
dprintf("full chip write data 0x55\n");
|
|||
|
os_mem_set(wdata, data_test, sizeof(wdata));
|
|||
|
|
|||
|
/* flash chip full write\read test */
|
|||
|
g_sfc_ctrl->erase_chip();
|
|||
|
for (i = 0; i < flash_size_total; i += sizeof(wdata)) {
|
|||
|
g_sfc_ctrl->write(wdata, i, sizeof(wdata), MOD_SFC_PROG_QUAD, MOD_SW_MODE_DIS);
|
|||
|
}
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
for (i = 0; i < flash_size_total; i++) {
|
|||
|
data_read = *(volatile uint8_t*)(flash_base_addr + i);
|
|||
|
if (data_read != data_test) {
|
|||
|
dprintf("full test failed, index:%d, data:0x%x\n", i, data_read);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
dprintf("full chip write data 0xaa\n");
|
|||
|
data_test = 0xaa;
|
|||
|
os_mem_set(wdata, data_test, sizeof(wdata));
|
|||
|
|
|||
|
/* flash chip full write\read test */
|
|||
|
g_sfc_ctrl->erase_chip();
|
|||
|
for (i = 0; i < flash_size_total; i += sizeof(wdata)) {
|
|||
|
g_sfc_ctrl->write(wdata, i, sizeof(wdata), MOD_SFC_PROG_QUAD, MOD_SW_MODE_DIS);
|
|||
|
}
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
for (i = 0; i < flash_size_total; i++) {
|
|||
|
data_read = *(volatile uint8_t*)(flash_base_addr + i);
|
|||
|
if (data_read != data_test) {
|
|||
|
dprintf("full test failed, index:%d, data:0x%x\n", i, data_read);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
dcase_success();
|
|||
|
return ERR_OK;
|
|||
|
failed:
|
|||
|
dcase_failed();
|
|||
|
return ERR_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
static uint32_t dtest_sfc_puya_factory_test()
|
|||
|
{
|
|||
|
#if 0
|
|||
|
uint32_t bad_cnt = 0;
|
|||
|
uint8_t chip_size;
|
|||
|
uint8_t w_even_page_buf[PAGE_PROGRAM_SIZE];
|
|||
|
uint8_t w_odd_page_buf[PAGE_PROGRAM_SIZE];
|
|||
|
uint32_t read_offset = 0;
|
|||
|
uint32_t base = ICACHE0_SFC_RAM_BASEADDR;
|
|||
|
uint32_t io_map_bak, io_map;
|
|||
|
(void)base;
|
|||
|
|
|||
|
dcase_start("puya flash full scan test\n");
|
|||
|
g_sfc_ctrl->read(rdata, 0, sizeof(rdata), MOD_SFC_READ_QUAD_IO_FAST);
|
|||
|
dprintf("power on, get falsh data:");
|
|||
|
for (uint32_t i = 0; i < sizeof(rdata); i++) {
|
|||
|
iot_printf("%x ", rdata[i]);
|
|||
|
}
|
|||
|
iot_printf("\n");
|
|||
|
|
|||
|
chip_size = 1 << (flash_get_dev_size() - FLASH_1M);
|
|||
|
/* init test data */
|
|||
|
for (uint32_t i = 0; i < PAGE_PROGRAM_SIZE; i += 8) {
|
|||
|
w_even_page_buf[i + 0] = 0xAA;
|
|||
|
w_even_page_buf[i + 1] = 0xAA;
|
|||
|
w_even_page_buf[i + 2] = 0xAA;
|
|||
|
w_even_page_buf[i + 3] = 0xAA;
|
|||
|
w_even_page_buf[i + 4] = 0x55;
|
|||
|
w_even_page_buf[i + 5] = 0x55;
|
|||
|
w_even_page_buf[i + 6] = 0x55;
|
|||
|
w_even_page_buf[i + 7] = 0x55;
|
|||
|
|
|||
|
w_odd_page_buf[i + 0] = 0x55;
|
|||
|
w_odd_page_buf[i + 1] = 0x55;
|
|||
|
w_odd_page_buf[i + 2] = 0x55;
|
|||
|
w_odd_page_buf[i + 3] = 0x55;
|
|||
|
w_odd_page_buf[i + 4] = 0xAA;
|
|||
|
w_odd_page_buf[i + 5] = 0xAA;
|
|||
|
w_odd_page_buf[i + 6] = 0xAA;
|
|||
|
w_odd_page_buf[i + 7] = 0xAA;
|
|||
|
}
|
|||
|
|
|||
|
/* step 1: QE mode */
|
|||
|
g_sfc_ctrl->set_quad_mode(QE_CFG_REG_31H);
|
|||
|
|
|||
|
/* step 2: WREN(06H)+CE(60H)+wait for 12ms */
|
|||
|
g_sfc_ctrl->erase_chip();
|
|||
|
iot_delay_us(12000);
|
|||
|
|
|||
|
/* step 3:Enter test mode */
|
|||
|
sfc_enter_test_mode();
|
|||
|
|
|||
|
/* switch cs and wp pin to enter flash full test mode */
|
|||
|
// flash_full_test_enter_sfc_mtx();
|
|||
|
io_map_bak = *((volatile uint32_t *)(SFC_REG_BASEADDR + CFG_SPI_IO_MAP0_ADDR));
|
|||
|
uint8_t io_map_cs = (io_map_bak >> SFC_CS0_MAP_SEL_OFFSET) & 0x0F;
|
|||
|
uint8_t io_map_wp = (io_map_bak >> SFC_WP_MAP_SEL_OFFSET) & 0x0F;
|
|||
|
io_map = (io_map_bak & (~SFC_CS0_MAP_SEL_MASK) & (~SFC_WP_MAP_SEL_MASK)) |
|
|||
|
(io_map_cs << SFC_WP_MAP_SEL_OFFSET) | (io_map_wp << SFC_CS0_MAP_SEL_OFFSET);
|
|||
|
dprintf("sfc current sfc io map: 0x%08X, set map:0x%08X\n", io_map_bak, io_map);
|
|||
|
sfc_set_io_map(io_map);
|
|||
|
|
|||
|
iot_delay_us(5000);
|
|||
|
|
|||
|
if (chip_size == 2) { /* 2MB flash */
|
|||
|
/* step 4:D4H program 256bytes(AA,AA,AA,AA,55,55,55,55…) to 0x000000 address */
|
|||
|
sfc_test_mode_write(w_even_page_buf, 0x0, PAGE_PROGRAM_SIZE);
|
|||
|
iot_delay_us(10000);
|
|||
|
/* step 5:D4H program 256bytes(AA,AA,AA,AA,55,55,55,55…) to 0x000100 address */
|
|||
|
sfc_test_mode_write(w_even_page_buf, 0x100, PAGE_PROGRAM_SIZE);
|
|||
|
iot_delay_us(10000);
|
|||
|
/* step 6:D4H program 256bytes(55,55,55,55,AA,AA,AA,AA…) to 0x000200 address */
|
|||
|
sfc_test_mode_write(w_odd_page_buf, 0x200, PAGE_PROGRAM_SIZE);
|
|||
|
iot_delay_us(10000);
|
|||
|
/* step 7:D4H program 256bytes(55,55,55,55,AA,AA,AA,AA…) to 0x000300 address */
|
|||
|
sfc_test_mode_write(w_odd_page_buf, 0x300, PAGE_PROGRAM_SIZE);
|
|||
|
iot_delay_us(10000);
|
|||
|
} else if (chip_size == 4) { /* 4MB flash */
|
|||
|
/* step 4:D4H program 256bytes(AA,AA,AA,AA,55,55,55,55…) to 0x000000 address */
|
|||
|
sfc_test_mode_write(w_even_page_buf, 0x0, PAGE_PROGRAM_SIZE);
|
|||
|
iot_delay_us(10000);
|
|||
|
/* step 5:D4H program 256bytes(AA,AA,AA,AA,55,55,55,55…) to 0x000100 address */
|
|||
|
sfc_test_mode_write(w_even_page_buf, 0x100, PAGE_PROGRAM_SIZE);
|
|||
|
iot_delay_us(10000);
|
|||
|
/* step 6:D4H program 256bytes(AA,AA,AA,AA,55,55,55,55…) to 0x000200 address */
|
|||
|
sfc_test_mode_write(w_even_page_buf, 0x200, PAGE_PROGRAM_SIZE);
|
|||
|
iot_delay_us(10000);
|
|||
|
/* step 7:D4H program 256bytes(AA,AA,AA,AA,55,55,55,55…) to 0x000300 address */
|
|||
|
sfc_test_mode_write(w_even_page_buf, 0x300, PAGE_PROGRAM_SIZE);
|
|||
|
iot_delay_us(10000);
|
|||
|
|
|||
|
/* step 4:D4H program 256bytes(55,55,55,55,AA,AA,AA,AA…) to 0x000400 address */
|
|||
|
sfc_test_mode_write(w_odd_page_buf, 0x400, PAGE_PROGRAM_SIZE);
|
|||
|
iot_delay_us(10000);
|
|||
|
/* step 5:D4H program 256bytes(55,55,55,55,AA,AA,AA,AA…) to 0x000500 address */
|
|||
|
sfc_test_mode_write(w_odd_page_buf, 0x500, PAGE_PROGRAM_SIZE);
|
|||
|
iot_delay_us(10000);
|
|||
|
/* step 6:D4H program 256bytes(55,55,55,55,AA,AA,AA,AA…) to 0x000600 address */
|
|||
|
sfc_test_mode_write(w_odd_page_buf, 0x600, PAGE_PROGRAM_SIZE);
|
|||
|
iot_delay_us(10000);
|
|||
|
/* step 7:D4H program 256bytes(55,55,55,55,AA,AA,AA,AA…) to 0x000700 address */
|
|||
|
sfc_test_mode_write(w_odd_page_buf, 0x700, PAGE_PROGRAM_SIZE);
|
|||
|
iot_delay_us(10000);
|
|||
|
}
|
|||
|
|
|||
|
/* step 8: Exit test mode(66H+99H) + wait 30us */
|
|||
|
sfc_rst_ena_and_rst();
|
|||
|
iot_delay_us(15000);
|
|||
|
|
|||
|
// uint8_t cs, hold, wp, so, si, clk;
|
|||
|
// uint32_t io_map_temp;
|
|||
|
// for (cs = 0; cs <= 5; cs++) {
|
|||
|
// for (hold = 0; hold <= 5; hold++) {
|
|||
|
// if (hold == cs)
|
|||
|
// continue;
|
|||
|
// for (wp = 0; wp <= 5; wp++) {
|
|||
|
// if (wp == cs || wp == hold)
|
|||
|
// continue;
|
|||
|
// for (so = 0; so <= 5; so++) {
|
|||
|
// if (so == cs || so == hold || so == wp)
|
|||
|
// continue;
|
|||
|
// for (si = 0; si <= 5; si++){
|
|||
|
// if (si == cs || si == hold || si == wp || si == so)
|
|||
|
// continue;
|
|||
|
// for (clk = 0; clk <= 5; clk++) {
|
|||
|
// if (clk == cs || clk == hold || clk == wp || clk == so || clk == si)
|
|||
|
// continue;
|
|||
|
// io_map_temp = (0x77 << 24) | (cs << 20) | (hold << 16) | (wp << 12) | (so << 8) | (si << 4) | clk;
|
|||
|
// if (io_map_temp == 0x77345210 || io_map_temp == 0x77435210)
|
|||
|
// continue;
|
|||
|
// sfc_set_io_map(io_map_temp);
|
|||
|
// iot_delay_us(5000);
|
|||
|
// sfc_qspi_get_id_mult(rdata, MOD_SFC_SERIAL);
|
|||
|
// if (rdata[0] == 0x85) {
|
|||
|
// dprintf("get id succeed, map:0x%08x\n", io_map_temp);
|
|||
|
// cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
// uint32_t read_data = *((uint32_t*)(base));
|
|||
|
// if (read_data == 0xaaaaaaaa) {
|
|||
|
// dprintf("get map(0x%08x) ok\n", io_map_temp);
|
|||
|
// goto read_test;
|
|||
|
// }
|
|||
|
// }
|
|||
|
// }
|
|||
|
// }
|
|||
|
// }
|
|||
|
// }
|
|||
|
// }
|
|||
|
// }
|
|||
|
//read_test:
|
|||
|
|
|||
|
/* set normal cs and wp pin to exit flash full test mode */
|
|||
|
dprintf("set sfc io map:0x%08X\n", io_map_bak);
|
|||
|
// flash_full_test_exit_sfc_mtx();
|
|||
|
sfc_set_io_map(io_map_bak);
|
|||
|
iot_delay_us(10000);
|
|||
|
|
|||
|
#if 1 /* Flash reading data error after IO map recovery */
|
|||
|
/* flash init again */
|
|||
|
// ahb_emc_disable();
|
|||
|
ahb_emc_reset();
|
|||
|
// ahb_emc_enable();
|
|||
|
|
|||
|
flash_init(1);
|
|||
|
#endif
|
|||
|
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
|
|||
|
if (chip_size == 2) { /* 2MB flash */
|
|||
|
read_offset = 512;
|
|||
|
} else if (chip_size == 4) { /* 4MB flash */
|
|||
|
read_offset = 1024;
|
|||
|
}
|
|||
|
|
|||
|
// g_sfc_ctrl->read(rdata, 0, sizeof(rdata), MOD_SFC_READ_QUAD_IO_FAST);
|
|||
|
// dprintf("flash reset, read falsh data:");
|
|||
|
// for (uint32_t i = 0; i < sizeof(rdata); i++) {
|
|||
|
// iot_printf("%x ", rdata[i]);
|
|||
|
// }
|
|||
|
// iot_printf("\n");
|
|||
|
// while(1);
|
|||
|
|
|||
|
/* step 9:EBH command verify CKBD */
|
|||
|
// for (uint32_t cnt = 0; cnt < 1024 * 1024 * chip_size; cnt += 4) {
|
|||
|
// uint32_t read_data = *((uint32_t*)(base + cnt));
|
|||
|
// if (cnt / read_offset % 2 == 0) {
|
|||
|
// if (cnt % 8 == 0) {
|
|||
|
// if (read_data != 0xAAAAAAAA) {
|
|||
|
// bad_cnt++;
|
|||
|
// }
|
|||
|
// } else if (cnt % 8 == 4) {
|
|||
|
// if (read_data != 0x55555555) {
|
|||
|
// bad_cnt++;
|
|||
|
// }
|
|||
|
// } else {
|
|||
|
// }
|
|||
|
// } else if (cnt / read_offset % 2 == 1) {
|
|||
|
// if (cnt % 8 == 0) {
|
|||
|
// if (read_data != 0x55555555) {
|
|||
|
// bad_cnt++;
|
|||
|
// }
|
|||
|
// } else if (cnt % 8 == 4) {
|
|||
|
// if (read_data != 0xAAAAAAAA) {
|
|||
|
// bad_cnt++;
|
|||
|
// }
|
|||
|
// } else {
|
|||
|
// }
|
|||
|
// } else {
|
|||
|
// }
|
|||
|
// }
|
|||
|
for (uint32_t i = 0; i < 0x400000; i += 0x100) {
|
|||
|
g_sfc_ctrl->read(rdata, i, sizeof(rdata), MOD_SFC_READ_QUAD_IO_FAST);
|
|||
|
if (i / read_offset % 2 == 0) {
|
|||
|
for (uint32_t j = 0; j < sizeof(rdata); j++) {
|
|||
|
if (rdata[j] != w_even_page_buf[j]) {
|
|||
|
dprintf("page:0x%x, index:%d, data exception, rdata:0x%x, "
|
|||
|
"even data:0x%x\n", i, j, rdata[j], w_even_page_buf[j]);
|
|||
|
bad_cnt++;
|
|||
|
}
|
|||
|
}
|
|||
|
} else if (i / read_offset % 2 == 1) {
|
|||
|
for (uint32_t j = 0; j < sizeof(rdata); j++) {
|
|||
|
if (rdata[j] != w_odd_page_buf[j]) {
|
|||
|
dprintf("page:0x%x, index:%d, data exception, rdata:0x%x, "
|
|||
|
"odd data:0x%x\n", i, j, rdata[j], w_odd_page_buf[j]);
|
|||
|
bad_cnt++;
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
dprintf("i(0x%08x) exception!!!", i);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* step 10: chip erase*/
|
|||
|
g_sfc_ctrl->erase_chip();
|
|||
|
|
|||
|
if (bad_cnt) {
|
|||
|
dcase_failed();
|
|||
|
return ERR_FAIL;
|
|||
|
} else {
|
|||
|
dcase_succeed();
|
|||
|
return ERR_OK;
|
|||
|
}
|
|||
|
#endif
|
|||
|
return ERR_OK;
|
|||
|
}
|
|||
|
|
|||
|
extern void _core_start(void);
|
|||
|
|
|||
|
/* SFC API does not support software arbitration temporarily,
|
|||
|
* and multi-core access to flash will be abnormal
|
|||
|
*/
|
|||
|
#if 0
|
|||
|
void dtest_sfc_core12_main()
|
|||
|
{
|
|||
|
uint32_t data = 0;
|
|||
|
uint8_t cpu = cpu_get_mhartid();
|
|||
|
uint32_t addr_common = 3 * PAGE_PROGRAM_SIZE;
|
|||
|
|
|||
|
dprintf("cpu id:%d\n", cpu);
|
|||
|
dprintf("cpu:%d, data:%p, cpu:%p, addr_com:%p\n", cpu, &data, &cpu, &addr_common);
|
|||
|
|
|||
|
// gp_timer_init();
|
|||
|
// gp_timer_set(0, 0xffffffff, 0);
|
|||
|
// gp_timer_start(0);
|
|||
|
|
|||
|
for(uint32_t i = 0 ; i < DTEST_SFC_CORE12_RW_CNT; i++) {
|
|||
|
g_sfc_ctrl->read((uint8_t *)&data, cpu * PAGE_PROGRAM_SIZE, sizeof(data), MOD_SFC_READ_SIG);
|
|||
|
iot_printf("cpu:%d, cnt:%d, readed(%d)\n", cpu, i, data);
|
|||
|
g_sfc_ctrl->erase_page(addr_common, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->erase_page(PAGE_PROGRAM_SIZE * cpu, MOD_SW_MODE_DIS);
|
|||
|
iot_printf("cpu:%d, erased\n", cpu);
|
|||
|
data++;
|
|||
|
g_sfc_ctrl->write((uint8_t *)&data, addr_common, sizeof(data), MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write((uint8_t *)&data, cpu * PAGE_PROGRAM_SIZE, sizeof(data), MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS);
|
|||
|
iot_printf("cpu:%d, written(%d)\n", cpu, data);
|
|||
|
|
|||
|
/* sfc api used spinlock, so don't need delay */
|
|||
|
// if (cpu == 1)
|
|||
|
// iot_delay_us(100000);
|
|||
|
// else if (cpu == 2)
|
|||
|
// iot_delay_us(100000);
|
|||
|
}
|
|||
|
|
|||
|
__asm volatile ("nop\n");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
static uint32_t dtest_sfc_multicore_rw_test()
|
|||
|
{
|
|||
|
uint32_t i, cnt_sfc_pe = 0;
|
|||
|
uint32_t data_0 = 0, data_1 = 0, data_2 = 0, data_com = 0;
|
|||
|
|
|||
|
dcase_start("flash multicore access test\n");
|
|||
|
|
|||
|
dprintf("init test page\n");
|
|||
|
g_sfc_ctrl->erase_page(PAGE_PROGRAM_SIZE * 0, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write((uint8_t *)&data_0, PAGE_PROGRAM_SIZE * 0, sizeof(data_0), MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->erase_page(PAGE_PROGRAM_SIZE * 1, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write((uint8_t *)&data_1, PAGE_PROGRAM_SIZE * 1, sizeof(data_1), MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->erase_page(PAGE_PROGRAM_SIZE * 2, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write((uint8_t *)&data_2, PAGE_PROGRAM_SIZE * 2, sizeof(data_2), MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->erase_page(PAGE_PROGRAM_SIZE * 3, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write((uint8_t *)&data_com, PAGE_PROGRAM_SIZE * 3, sizeof(data_com), MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS);
|
|||
|
|
|||
|
/* clear suspended cnt */
|
|||
|
SFC_WRITE_REG(CFG_SFC_PE_STS_ADDR, (1 << PE_CMD_CNT_CLR_OFFSET));
|
|||
|
iot_delay_us(5);
|
|||
|
cnt_sfc_pe = REG_FIELD_GET(PE_CMD_CNT, SFC_READ_REG(CFG_SFC_PE_STS_ADDR));
|
|||
|
dprintf("beform multicore test, sfc suspended cnt:%d\n", cnt_sfc_pe);
|
|||
|
|
|||
|
dprintf("enable core1\n");
|
|||
|
ahb_core1_set_start((uint32_t)_core_start);
|
|||
|
ahb_core1_enable();
|
|||
|
ahb_core1_reset();
|
|||
|
iot_delay_us(10000);
|
|||
|
|
|||
|
dprintf("enable core2\n");
|
|||
|
ahb_core2_set_start((uint32_t)_core_start);
|
|||
|
ahb_core2_enable();
|
|||
|
ahb_core2_reset();
|
|||
|
iot_delay_us(10000);
|
|||
|
|
|||
|
// uint8_t cpu = cpu_get_mhartid();
|
|||
|
// uint32_t addr_common = 3 * PAGE_PROGRAM_SIZE;
|
|||
|
// uint32_t data;
|
|||
|
for (i = 0; i < 30; i++) {
|
|||
|
// g_sfc_ctrl->read((uint8_t *)&data, cpu * PAGE_PROGRAM_SIZE, sizeof(data), MOD_SFC_READ_SIG);
|
|||
|
// iot_printf("cpu:%d, cnt:%d, readed(%d)\n", cpu, i, data);
|
|||
|
// g_sfc_ctrl->erase_page(addr_common, MOD_SW_MODE_DIS);
|
|||
|
// g_sfc_ctrl->erase_page(PAGE_PROGRAM_SIZE * cpu, MOD_SW_MODE_DIS);
|
|||
|
// iot_printf("cpu:%d, erased\n", cpu);
|
|||
|
// data++;
|
|||
|
// g_sfc_ctrl->write((uint8_t *)&data, addr_common, sizeof(data), MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS);
|
|||
|
// g_sfc_ctrl->write((uint8_t *)&data, cpu * PAGE_PROGRAM_SIZE, sizeof(data), MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS);
|
|||
|
// iot_printf("cpu:%d, written(%d)\n", cpu, data);
|
|||
|
|
|||
|
iot_delay_us(500000);
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
data_0 = *(volatile uint32_t*)(ICACHE0_SFC_RAM_BASEADDR);
|
|||
|
data_1 = *(volatile uint32_t*)(ICACHE0_SFC_RAM_BASEADDR + PAGE_PROGRAM_SIZE * 1);
|
|||
|
data_2 = *(volatile uint32_t*)(ICACHE0_SFC_RAM_BASEADDR + PAGE_PROGRAM_SIZE * 2);
|
|||
|
data_com = *(volatile uint32_t*)(ICACHE0_SFC_RAM_BASEADDR + PAGE_PROGRAM_SIZE * 3);
|
|||
|
dprintf("get flash data:0x%08x, 0x%08x, 0x%08x, 0x%08x\n", data_0, data_1, data_2, data_com);
|
|||
|
}
|
|||
|
|
|||
|
/* The number of times flash is suspended by cache during erase and program */
|
|||
|
cnt_sfc_pe = REG_FIELD_GET(PE_CMD_CNT, SFC_READ_REG(CFG_SFC_PE_STS_ADDR));
|
|||
|
dprintf("after multicore test, sfc suspended cnt:%d\n", cnt_sfc_pe);
|
|||
|
|
|||
|
if (data_1 != DTEST_SFC_CORE12_RW_CNT || data_2 != DTEST_SFC_CORE12_RW_CNT
|
|||
|
|| (data_com != data_1 && data_com != data_2)) {
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
|
|||
|
dcase_success();
|
|||
|
return ERR_OK;
|
|||
|
failed:
|
|||
|
dcase_failed();
|
|||
|
return ERR_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
#else
|
|||
|
|
|||
|
void dtest_sfc_core12_main()
|
|||
|
{
|
|||
|
uint8_t cpu;
|
|||
|
uint32_t core_sfc_base;
|
|||
|
volatile uint32_t data = 0, data_last = 0, data_err = 0, read_cnt = 0;
|
|||
|
|
|||
|
cpu = cpu_get_mhartid();
|
|||
|
if (cpu == 1) {
|
|||
|
core_sfc_base = ICACHE1_SFC_RAM_BASEADDR;
|
|||
|
} else {
|
|||
|
core_sfc_base = ICACHE2_SFC_RAM_BASEADDR;
|
|||
|
}
|
|||
|
dprintf("cpu id:%d running\n", cpu);
|
|||
|
|
|||
|
gp_timer_init();
|
|||
|
gp_timer_set(0, 0xffffffff, 0);
|
|||
|
gp_timer_start(0);
|
|||
|
|
|||
|
while(1) {
|
|||
|
// cache_invalidate(DTEST_SFC_CACHE_FOR_READ + cpu, DTEST_SFC_OFFSET, 32);
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ + cpu);
|
|||
|
|
|||
|
data = *(uint32_t *)(core_sfc_base + DTEST_SFC_OFFSET);
|
|||
|
read_cnt++;
|
|||
|
|
|||
|
if (data == 0xffffffff) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// iot_printf("cpu:%d, r:%d\n", cpu, data);
|
|||
|
// iot_delay_us(1);
|
|||
|
if (data < DTEST_SFC_CORE12_CACHE_READ_CNT) {
|
|||
|
if ((data == data_last) || (data == data_last + 1)) {
|
|||
|
data_last = data;
|
|||
|
continue;
|
|||
|
} else {
|
|||
|
data_err = 1;
|
|||
|
}
|
|||
|
} else {
|
|||
|
iot_delay_us(10000 * cpu);
|
|||
|
iot_printf("cpu:%d r cnt:%d, err:%d\n", cpu, read_cnt, data_err);
|
|||
|
*(volatile uint32_t *)DTEST_SFC_CORE12_SCRATCH_ADDR |= (1 << (cpu * 2));
|
|||
|
if (data_err == 1) {
|
|||
|
*(volatile uint32_t *)DTEST_SFC_CORE12_SCRATCH_ADDR |= (1 << (cpu * 2 + 1));
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
__asm volatile ("nop\n");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
static uint32_t dtest_sfc_multicore_rw_test()
|
|||
|
{
|
|||
|
uint32_t i, cnt_sfc_pe = 0;
|
|||
|
volatile uint32_t data = 0, data_reg;
|
|||
|
|
|||
|
dcase_start("flash multicore access test\n");
|
|||
|
|
|||
|
dprintf("init flash data and scratch reg\n");
|
|||
|
g_sfc_ctrl->erase_sector(DTEST_SFC_OFFSET, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write((uint8_t *)&data, DTEST_SFC_OFFSET, sizeof(data), MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS);
|
|||
|
*(volatile uint32_t *)DTEST_SFC_CORE12_SCRATCH_ADDR = 0x0;
|
|||
|
|
|||
|
/* clear suspended cnt */
|
|||
|
SFC_WRITE_REG(CFG_SFC_PE_STS_ADDR, (1 << PE_CMD_CNT_CLR_OFFSET));
|
|||
|
iot_delay_us(5);
|
|||
|
cnt_sfc_pe = REG_FIELD_GET(PE_CMD_CNT, SFC_READ_REG(CFG_SFC_PE_STS_ADDR));
|
|||
|
dprintf("beform multicore test, sfc suspended cnt:%d\n", cnt_sfc_pe);
|
|||
|
|
|||
|
dprintf("enable core1\n");
|
|||
|
ahb_core1_set_start((uint32_t)_core_start);
|
|||
|
ahb_core1_enable();
|
|||
|
ahb_core1_reset();
|
|||
|
iot_delay_us(10000);
|
|||
|
|
|||
|
dprintf("enable core2\n");
|
|||
|
ahb_core2_set_start((uint32_t)_core_start);
|
|||
|
ahb_core2_enable();
|
|||
|
ahb_core2_reset();
|
|||
|
iot_delay_us(10000);
|
|||
|
|
|||
|
for (i = 0; i <= DTEST_SFC_CORE12_CACHE_READ_CNT; i++) {
|
|||
|
g_sfc_ctrl->erase_sector(DTEST_SFC_OFFSET, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write((uint8_t *)&i, DTEST_SFC_OFFSET, sizeof(i), MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS);
|
|||
|
// iot_printf("cpu0 w:%d\n", i);
|
|||
|
|
|||
|
/* cache is 2way, continuously skip 16K address reading,
|
|||
|
* and cache miss will be triggered during the third reading */
|
|||
|
// for (uint8_t j = 1; j < 3; j++) {
|
|||
|
// data = *(uint32_t *)(ICACHE0_SFC_RAM_BASEADDR + DTEST_SFC_OFFSET + 0x4000 * j);
|
|||
|
// }
|
|||
|
//// cache_invalidate(DTEST_SFC_CACHE_FOR_READ, DTEST_SFC_OFFSET, 0x8000);
|
|||
|
//// cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
// data = *(uint32_t *)(ICACHE0_SFC_RAM_BASEADDR + DTEST_SFC_OFFSET);
|
|||
|
}
|
|||
|
iot_delay_us(1000000);
|
|||
|
|
|||
|
/* The number of times flash is suspended by cache during erase and program */
|
|||
|
cnt_sfc_pe = REG_FIELD_GET(PE_CMD_CNT, SFC_READ_REG(CFG_SFC_PE_STS_ADDR));
|
|||
|
dprintf("after multicore test, sfc suspended cnt:%d\n", cnt_sfc_pe);
|
|||
|
|
|||
|
data_reg = *(volatile uint32_t*)DTEST_SFC_CORE12_SCRATCH_ADDR;
|
|||
|
dprintf("get scratch(0x%08x) data:0x%08x\n", DTEST_SFC_CORE12_SCRATCH_ADDR, data_reg);
|
|||
|
if (data_reg != 0x14) {
|
|||
|
dprintf("core1 or core2 get flash data error\n");
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
|
|||
|
dcase_success();
|
|||
|
return ERR_OK;
|
|||
|
failed:
|
|||
|
dcase_failed();
|
|||
|
return ERR_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
/* the test requires two flash chips, image is 906(cs0-A19 cs2-G19) */
|
|||
|
static uint32_t dtest_sfc_two_cs_test()
|
|||
|
{
|
|||
|
uint8_t size_f1 = 4;
|
|||
|
uint32_t temp, temp2;
|
|||
|
uint32_t addr_test = 0x100000;
|
|||
|
uint32_t data = 0, data_test1 = 0x11223344, data_test2 = 0xaabbccdd;
|
|||
|
|
|||
|
temp = SFC_READ_REG(CFG_SPI_CS0_CFG_ADDR);
|
|||
|
dcase_start("2 flash chip test, initial register value:0x%08x\n", temp);
|
|||
|
|
|||
|
/* io map: sfc cs1/smc cs/sfc cs0/sio3/sio2/sio1/sio0/clk */
|
|||
|
dprintf("set sfc io remap:0x78543210\n");
|
|||
|
SFC_WRITE_REG(CFG_SPI_IO_MAP0_ADDR, 0x78543210);
|
|||
|
|
|||
|
dprintf("method 1: set spi_cs1_force_sel=1\n");
|
|||
|
g_sfc_ctrl->erase_sector(addr_test, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write((uint8_t *)&data_test1, addr_test, sizeof(data_test1),
|
|||
|
MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS);
|
|||
|
cache_clear(0);
|
|||
|
data = *(uint32_t *)(ICACHE0_SFC_RAM_BASEADDR + addr_test);
|
|||
|
if (data != data_test1) {
|
|||
|
dprintf("write flash 1 data failed, rdata:0x%08x, wdata:0x%08x\n", data, data_test1);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
dprintf("write/read flash 1 succeed\n");
|
|||
|
SFC_WRITE_REG(CFG_SPI_CS0_CFG_ADDR, (1 << SPI_CS1_FORCE_SEL_OFFSET) | temp);
|
|||
|
iot_delay_us(100);
|
|||
|
g_sfc_ctrl->erase_sector(addr_test, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write((uint8_t*)&data_test2, addr_test, sizeof(data_test2),
|
|||
|
MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS);
|
|||
|
cache_clear(0);
|
|||
|
data = *(uint32_t *)(ICACHE0_SFC_RAM_BASEADDR + addr_test);
|
|||
|
if (data != data_test2) {
|
|||
|
dprintf("write flash 2 data failed, rdata:0x%08x, wdata:0x%08x\n", data, data_test2);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
SFC_WRITE_REG(CFG_SPI_CS0_CFG_ADDR, (0 << SPI_CS1_FORCE_SEL_OFFSET) | temp);
|
|||
|
cache_clear(0);
|
|||
|
data = *(uint32_t *)(ICACHE0_SFC_RAM_BASEADDR + addr_test);
|
|||
|
if (data != data_test1) {
|
|||
|
dprintf("read flash 1 data failed, rdata:0x%08x, wdata:0x%08x\n", data, data_test1);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
|
|||
|
dprintf("method 2: auto switch falsh 2 when addr greater than falsh 1\n");
|
|||
|
dprintf("set cache space sfc 8m\n");
|
|||
|
temp2 = *(uint32_t *)(ICACHE0_REG_BASEADDR + CFG_CACHE_VALID_SPACE_ADDR);
|
|||
|
*(uint32_t *)(ICACHE0_REG_BASEADDR + CFG_CACHE_VALID_SPACE_ADDR) = 0x0808;
|
|||
|
iot_delay_us(5);
|
|||
|
REG_FIELD_SET(SPI_CS0_SIZE, temp, size_f1);
|
|||
|
REG_FIELD_SET(SPI_CS1_FORCE_SEL, temp, 0);
|
|||
|
SFC_WRITE_REG(CFG_SPI_CS0_CFG_ADDR, temp);
|
|||
|
iot_delay_us(100);
|
|||
|
cache_clear(0);
|
|||
|
data = *(uint32_t *)(ICACHE0_SFC_RAM_BASEADDR + addr_test);
|
|||
|
if (data != data_test1) {
|
|||
|
dprintf("read flash 1 data failed, rdata:0x%08x, wdata:0x%08x\n", data, data_test1);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
cache_clear(0);
|
|||
|
data = *(uint32_t *)(ICACHE0_SFC_RAM_BASEADDR + addr_test + size_f1 * 0x100000);
|
|||
|
if (data != data_test2) {
|
|||
|
dprintf("read flash 2 data failed, rdata:0x%08x, wdata:0x%08x\n", data, data_test2);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
*(uint32_t *)(ICACHE0_REG_BASEADDR + CFG_CACHE_VALID_SPACE_ADDR) = temp2;
|
|||
|
|
|||
|
dcase_success();
|
|||
|
return ERR_OK;
|
|||
|
failed:
|
|||
|
dcase_failed();
|
|||
|
return ERR_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
static uint32_t dtest_sfc_remap_test()
|
|||
|
{
|
|||
|
uint32_t i;
|
|||
|
uint8_t data_w = 0x55, data_test, data_remap;
|
|||
|
uint32_t addr_test, addr_remap;
|
|||
|
|
|||
|
dcase_start("flash address remap test\n");
|
|||
|
|
|||
|
/* init wdata */
|
|||
|
for (i = 0; i < sizeof(wdata); i++) {
|
|||
|
wdata[i] = data_w;
|
|||
|
}
|
|||
|
|
|||
|
/* remap 64K, use register */
|
|||
|
dprintf("operation register completes remap, and the block size is 64K\n");
|
|||
|
addr_test = 0;
|
|||
|
addr_remap = addr_test + ADDR_MAPPING_SIZE_64K;
|
|||
|
|
|||
|
g_sfc_ctrl->erase_sector(addr_test, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->erase_sector(addr_remap, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write(wdata, addr_test, sizeof(wdata),MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS);
|
|||
|
|
|||
|
g_sfc_ctrl->read(&data_test, addr_test, sizeof(data_test), MOD_SFC_READ_SIG);
|
|||
|
g_sfc_ctrl->read(&data_remap, addr_remap, sizeof(data_remap), MOD_SFC_READ_SIG);
|
|||
|
if (data_test != data_w || data_remap != 0xff) {
|
|||
|
dprintf("read error data, w:0x%x, test:0x%x, remap:0x%x\n",
|
|||
|
data_w, data_test, data_remap);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
|
|||
|
/* remap block0 and block1 */
|
|||
|
*(volatile uint32_t *)(SFC_REG_BASEADDR + CFG_SFC_DBG_ADDR) &= ~(1 << SFC_ADDR_MAP_ENA_OFFSET);
|
|||
|
SFC_WRITE_REG(CFG_SFC_AMAP0_ADDR, 0x03020001);
|
|||
|
*(volatile uint32_t *)(SFC_REG_BASEADDR + CFG_SFC_DBG_ADDR) |= (1 << SFC_ADDR_MAP_ENA_OFFSET);
|
|||
|
|
|||
|
/* Flash address remap only works for cache, SFC API always uses the real address */
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
data_test = *(volatile uint8_t*)(ICACHE0_SFC_RAM_BASEADDR + addr_test);
|
|||
|
data_remap = *(volatile uint8_t*)(ICACHE0_SFC_RAM_BASEADDR + addr_remap);
|
|||
|
if (data_test != 0xff || data_remap != data_w) {
|
|||
|
dprintf("read error data after remap, w:0x%x, test:0x%x, remap:0x%x\n",
|
|||
|
data_w, data_test, data_remap);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
|
|||
|
/* remap 128K, use api */
|
|||
|
dprintf("operation api completes remap, and the block size is 128K\n");
|
|||
|
/* Reply to the original remap */
|
|||
|
*(volatile uint32_t *)(SFC_REG_BASEADDR + CFG_SFC_DBG_ADDR) &= ~(1 << SFC_ADDR_MAP_ENA_OFFSET);
|
|||
|
SFC_WRITE_REG(CFG_SFC_AMAP0_ADDR, 0x03020100);
|
|||
|
*(volatile uint32_t *)(SFC_REG_BASEADDR + CFG_SFC_DBG_ADDR) |= (1 << SFC_ADDR_MAP_ENA_OFFSET);
|
|||
|
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
data_test = *(volatile uint8_t*)(ICACHE0_SFC_RAM_BASEADDR + addr_test);
|
|||
|
data_remap = *(volatile uint8_t*)(ICACHE0_SFC_RAM_BASEADDR + addr_remap);
|
|||
|
if (data_test != data_w || data_remap != 0xff) {
|
|||
|
dprintf("read error data, w:0x%x, test:0x%x, remap:0x%x\n",
|
|||
|
data_w, data_test, data_remap);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
|
|||
|
/* Modify the block size to 128K */
|
|||
|
*(volatile uint32_t *)(SFC_REG_BASEADDR + CFG_SFC_DBG_ADDR) |= (1 << SFC_ADDR_MAP_MODE_OFFSET);
|
|||
|
addr_test = 0;
|
|||
|
addr_remap = addr_test + ADDR_MAPPING_SIZE_128K;
|
|||
|
|
|||
|
g_sfc_ctrl->erase_sector(addr_test, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->erase_sector(addr_remap, MOD_SW_MODE_DIS);
|
|||
|
g_sfc_ctrl->write(wdata, addr_test, sizeof(wdata),MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS);
|
|||
|
|
|||
|
g_sfc_ctrl->read(&data_test, addr_test, sizeof(data_test), MOD_SFC_READ_SIG);
|
|||
|
g_sfc_ctrl->read(&data_remap, addr_remap, sizeof(data_remap), MOD_SFC_READ_SIG);
|
|||
|
if (data_test != data_w || data_remap != 0xff) {
|
|||
|
dprintf("read error data, w:0x%x, test:0x%x, remap:0x%x\n",
|
|||
|
data_w, data_test, data_remap);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
|
|||
|
g_sfc_ctrl->addr_mapping(addr_test, addr_remap, ADDR_MAPPING_SIZE_128K);
|
|||
|
|
|||
|
cache_clear(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
data_test = *(volatile uint8_t*)(ICACHE0_SFC_RAM_BASEADDR + addr_test);
|
|||
|
data_remap = *(volatile uint8_t*)(ICACHE0_SFC_RAM_BASEADDR + addr_remap);
|
|||
|
if (data_test != 0xff || data_remap != data_w) {
|
|||
|
dprintf("read error data after remap, w:0x%x, test:0x%x, remap:0x%x\n",
|
|||
|
data_w, data_test, data_remap);
|
|||
|
goto failed;
|
|||
|
}
|
|||
|
|
|||
|
dcase_success();
|
|||
|
return ERR_OK;
|
|||
|
failed:
|
|||
|
dcase_failed();
|
|||
|
return ERR_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
extern uint32_t clk_debug_output_set(uint32_t type, uint32_t div, uint32_t gpio);
|
|||
|
|
|||
|
static uint32_t dtest_sfc_gpio_matrix_test()
|
|||
|
{
|
|||
|
#define DTEST_SFC_MTX_IO_OUTPUT_TEST 0
|
|||
|
|
|||
|
dcase_start("sfc monitor signal matrix test\n");
|
|||
|
|
|||
|
gpio_mtx_enable();
|
|||
|
apb_enable(APB_GPIO);
|
|||
|
|
|||
|
#if DTEST_SFC_MTX_IO_OUTPUT_TEST
|
|||
|
/* fpga gpio info, gpio13 is uart1 tx */
|
|||
|
/* 1. uart1_rx - gpio7, no
|
|||
|
2. uart1_tx - gpio8, yes
|
|||
|
3. uart2_rtsn - gpio34(j207-4), yes
|
|||
|
4. uart2_ctsn - gpio35(j207-3), yes
|
|||
|
5. uart2_tx - gpio36, no
|
|||
|
6. uart2_rx - gpio37, no
|
|||
|
|
|||
|
7. rfspi_clk - gpio9(j208-27), no
|
|||
|
8. rfspi_di - gpio10(j208-17), no
|
|||
|
9. rfspi_do - gpio11(j208-26), no
|
|||
|
10. rfspi_cs - gpio12(j208-25),
|
|||
|
*/
|
|||
|
static uint8_t val[6] = {0};
|
|||
|
volatile uint32_t gpio_reg_addr[6] = {
|
|||
|
GPIO_BASEADDR + CFG_GPIO9_CFG_ADDR, GPIO_BASEADDR + CFG_GPIO8_CFG_ADDR,
|
|||
|
GPIO_BASEADDR + CFG_GPIO34_CFG_ADDR, GPIO_BASEADDR + CFG_GPIO35_CFG_ADDR,
|
|||
|
GPIO_BASEADDR + CFG_GPIO10_CFG_ADDR, GPIO_BASEADDR + CFG_GPIO11_CFG_ADDR};
|
|||
|
volatile uint32_t pin_reg_addr[6] = {
|
|||
|
DIG_PIN_REG_BASEADDR + CFG_GPIO09_PIN_CFG_ADDR, DIG_PIN_REG_BASEADDR + CFG_GPIO08_PIN_CFG_ADDR,
|
|||
|
DIG_PIN_REG_BASEADDR + CFG_GPIO34_PIN_CFG_ADDR, DIG_PIN_REG_BASEADDR + CFG_GPIO35_PIN_CFG_ADDR,
|
|||
|
DIG_PIN_REG_BASEADDR + CFG_GPIO10_PIN_CFG_ADDR, DIG_PIN_REG_BASEADDR + CFG_GPIO11_PIN_CFG_ADDR};
|
|||
|
volatile uint32_t mtx_reg_addr[6] = {
|
|||
|
GPIO_MTX_REG_BASEADDR + CFG_GPIO9_OUT_CFG_ADDR, GPIO_MTX_REG_BASEADDR + CFG_GPIO8_OUT_CFG_ADDR,
|
|||
|
GPIO_MTX_REG_BASEADDR + CFG_GPIO34_OUT_CFG_ADDR, GPIO_MTX_REG_BASEADDR + CFG_GPIO35_OUT_CFG_ADDR,
|
|||
|
GPIO_MTX_REG_BASEADDR + CFG_GPIO10_OUT_CFG_ADDR, GPIO_MTX_REG_BASEADDR + CFG_GPIO11_OUT_CFG_ADDR};
|
|||
|
|
|||
|
for (uint8_t i = 0; i < 6; i++) {
|
|||
|
//set pin function sel = 0
|
|||
|
*(uint32_t *)(pin_reg_addr[i]) &= ~(0x1 << 4);
|
|||
|
//set mtx out sel = 0xff
|
|||
|
*(uint32_t *)(mtx_reg_addr[i]) = 0xff;
|
|||
|
}
|
|||
|
while (1) {
|
|||
|
for (uint8_t i = 0; i < 6; i++) {
|
|||
|
uint32_t temp;
|
|||
|
temp = *(uint32_t *)(gpio_reg_addr[i]);
|
|||
|
temp |= (1 << 10); //out enable = 1
|
|||
|
if (val[i]) {
|
|||
|
temp |= (1 << 11); //out 1
|
|||
|
val[i] = 0;
|
|||
|
} else {
|
|||
|
temp &= ~(1 << 11); //out 0
|
|||
|
val[i] = 1;
|
|||
|
}
|
|||
|
*(uint32_t *)(gpio_reg_addr[i]) = temp;
|
|||
|
}
|
|||
|
iot_delay_us(10000);
|
|||
|
dprintf("io\n");
|
|||
|
}
|
|||
|
#else
|
|||
|
uint32_t gpio_mon_clk = 28;
|
|||
|
uint32_t gpio_mon_cs0 = 29;
|
|||
|
uint32_t gpio_mon_si = 30;
|
|||
|
uint32_t gpio_mon_so = 31;
|
|||
|
uint32_t gpio_mon_wp = 32;
|
|||
|
uint32_t gpio_mon_hold = 33;
|
|||
|
uint32_t gpio_mon_cs1 = 0xff;
|
|||
|
|
|||
|
clk_debug_output_set(9, 1, 67);
|
|||
|
|
|||
|
if (gpio_mon_clk != 0xff) {
|
|||
|
gpio_pin_select(gpio_mon_clk, 0);
|
|||
|
gpio_mtx_sig_out(GPIO_MTX_SFC_SPI_CLK_OUT_MON, gpio_mon_clk);
|
|||
|
}
|
|||
|
if (gpio_mon_cs0 != 0xff) {
|
|||
|
gpio_pin_select(gpio_mon_cs0, 0);
|
|||
|
gpio_mtx_sig_out(GPIO_MTX_SFC_SPI_CS0_OUT_MON, gpio_mon_cs0);
|
|||
|
}
|
|||
|
if (gpio_mon_si != 0xff) {
|
|||
|
gpio_pin_select(gpio_mon_si, 0);
|
|||
|
gpio_mtx_sig_out(GPIO_MTX_SFC_SPI_SI_OUT_MON, gpio_mon_si);
|
|||
|
}
|
|||
|
if (gpio_mon_so != 0xff) {
|
|||
|
gpio_pin_select(gpio_mon_so, 0);
|
|||
|
gpio_mtx_sig_out(GPIO_MTX_SFC_SPI_SO_OUT_MON, gpio_mon_so);
|
|||
|
}
|
|||
|
if (gpio_mon_wp != 0xff) {
|
|||
|
gpio_pin_select(gpio_mon_wp, 0);
|
|||
|
gpio_mtx_sig_out(GPIO_MTX_SFC_SPI_WP_OUT_MON, gpio_mon_wp);
|
|||
|
}
|
|||
|
if (gpio_mon_hold != 0xff) {
|
|||
|
gpio_pin_select(gpio_mon_hold, 0);
|
|||
|
gpio_mtx_sig_out(GPIO_MTX_SFC_SPI_HOLD_OUT_MON, gpio_mon_hold);
|
|||
|
}
|
|||
|
if (gpio_mon_cs1 != 0xff) {
|
|||
|
gpio_pin_select(gpio_mon_cs1, 0);
|
|||
|
gpio_mtx_sig_out(GPIO_MTX_SFC_SPI_CS1_OUT_MON, gpio_mon_cs1);
|
|||
|
}
|
|||
|
|
|||
|
// while (1) {
|
|||
|
// dtest_sfc_get_id_test();
|
|||
|
// }
|
|||
|
#endif
|
|||
|
|
|||
|
/* never com here */
|
|||
|
dcase_success();
|
|||
|
return ERR_OK;
|
|||
|
}
|
|||
|
|
|||
|
void sfc_force_sel_cs1(uint8_t val)
|
|||
|
{
|
|||
|
uint32_t tmp;
|
|||
|
|
|||
|
tmp = SFC_READ_REG(CFG_SPI_CS0_CFG_ADDR);
|
|||
|
REG_FIELD_SET(SPI_CS1_FORCE_SEL, tmp, val);
|
|||
|
SFC_WRITE_REG(CFG_SPI_CS0_CFG_ADDR, tmp);
|
|||
|
}
|
|||
|
|
|||
|
/* enable cs1 */
|
|||
|
void sfc_cs1_enable()
|
|||
|
{
|
|||
|
uint32_t tmp;
|
|||
|
|
|||
|
tmp = SFC_READ_REG(CFG_SPI_IO_MAP0_ADDR);
|
|||
|
REG_FIELD_SET(SFC_CS1_MAP_SEL, tmp, 7);
|
|||
|
SFC_WRITE_REG(CFG_SPI_IO_MAP0_ADDR, tmp);
|
|||
|
}
|
|||
|
|
|||
|
static void dtest_sfc_main()
|
|||
|
{
|
|||
|
uint32_t case_group = 0, failed_cnt = 0;
|
|||
|
|
|||
|
ahb_emc_disable();
|
|||
|
ahb_emc_reset();
|
|||
|
ahb_emc_enable();
|
|||
|
|
|||
|
clk_system_clock_tree_config(CLK_FRQ_GP_IDX_FAST);
|
|||
|
|
|||
|
dbg_uart_init();
|
|||
|
|
|||
|
gp_timer_init();
|
|||
|
gp_timer_set(0, 0xffffffff, 0);
|
|||
|
gp_timer_start(0);
|
|||
|
|
|||
|
dconfig();
|
|||
|
dstart();
|
|||
|
dversion();
|
|||
|
|
|||
|
// if (dtest_get_case_group(&case_group) < 0) {
|
|||
|
case_group = DTEST_SFC_CASE_GET_ID |
|
|||
|
DTEST_SFC_CASE_ERASE |
|
|||
|
DTEST_SFC_CASE_WRITE |
|
|||
|
DTEST_SFC_CASE_READ |
|
|||
|
DTEST_SFC_CASE_FULL_WR |
|
|||
|
// DTEST_SFC_CASE_PUYA_FACTORY |
|
|||
|
DTEST_SFC_CASE_MULTICORE |
|
|||
|
// DTEST_SFC_CASE_TWO_CS |
|
|||
|
DTEST_SFC_CASE_REMAP |
|
|||
|
DTEST_SFC_CASE_MONITOR_SIG |
|
|||
|
DTEST_SFC_CASE_STS_REG;
|
|||
|
// }
|
|||
|
dprintf("get case group:0x%08X\n", case_group);
|
|||
|
|
|||
|
/* init sfc and flash */
|
|||
|
flash_init(1);
|
|||
|
sfc_set_endian_mode(1);
|
|||
|
|
|||
|
/* enable cache0 for read flash data */
|
|||
|
cache_disable(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
cache_enable(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
cache_fill_valid_space(DTEST_SFC_CACHE_FOR_READ);
|
|||
|
/* use cache1(core1), cache2(core2) */
|
|||
|
cache_disable(DTEST_SFC_CACHE_FOR_READ + 1);
|
|||
|
cache_enable(DTEST_SFC_CACHE_FOR_READ + 1);
|
|||
|
cache_fill_valid_space(DTEST_SFC_CACHE_FOR_READ + 1);
|
|||
|
cache_disable(DTEST_SFC_CACHE_FOR_READ + 2);
|
|||
|
cache_enable(DTEST_SFC_CACHE_FOR_READ + 2);
|
|||
|
cache_fill_valid_space(DTEST_SFC_CACHE_FOR_READ + 2);
|
|||
|
|
|||
|
/* the signal needs to be viewed by an oscilloscope or logic analyzer */
|
|||
|
if (case_group & DTEST_SFC_CASE_MONITOR_SIG) {
|
|||
|
if (dtest_sfc_gpio_matrix_test() != ERR_OK) {
|
|||
|
failed_cnt++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (case_group & DTEST_SFC_CASE_GET_ID) {
|
|||
|
if (dtest_sfc_get_id_test() != ERR_OK) {
|
|||
|
failed_cnt++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (case_group & DTEST_SFC_CASE_STS_REG) {
|
|||
|
if (dtest_sfc_get_sts_reg_test() != ERR_OK) {
|
|||
|
failed_cnt++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (case_group & DTEST_SFC_CASE_ERASE) {
|
|||
|
if (dtest_sfc_erase_test() != ERR_OK) {
|
|||
|
failed_cnt++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (case_group & DTEST_SFC_CASE_WRITE) {
|
|||
|
if (dtest_sfc_write_test() != ERR_OK) {
|
|||
|
failed_cnt++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (case_group & DTEST_SFC_CASE_READ) {
|
|||
|
if (dtest_sfc_read_test() != ERR_OK) {
|
|||
|
failed_cnt++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (case_group & DTEST_SFC_CASE_FULL_WR) {
|
|||
|
if (dtest_sfc_flash_full_wr_test() != ERR_OK) {
|
|||
|
failed_cnt++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (case_group & DTEST_SFC_CASE_PUYA_FACTORY) {
|
|||
|
if (dtest_sfc_puya_factory_test() != ERR_OK) {
|
|||
|
failed_cnt++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (case_group & DTEST_SFC_CASE_MULTICORE) {
|
|||
|
if (dtest_sfc_multicore_rw_test() != ERR_OK) {
|
|||
|
failed_cnt++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (case_group & DTEST_SFC_CASE_TWO_CS) {
|
|||
|
if (dtest_sfc_two_cs_test() != ERR_OK) {
|
|||
|
failed_cnt++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (case_group & DTEST_SFC_CASE_REMAP) {
|
|||
|
if (dtest_sfc_remap_test() != ERR_OK) {
|
|||
|
failed_cnt++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (failed_cnt) {
|
|||
|
dprintf("sfc dtest failed\n");
|
|||
|
} else {
|
|||
|
dprintf("sfc dtest succeed\n");
|
|||
|
}
|
|||
|
|
|||
|
dend();
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
int main(void)
|
|||
|
{
|
|||
|
dtest_sfc_main();
|
|||
|
return 0;
|
|||
|
}
|