Files
kunlun/dtest/dtest3/kl3_sfc_test/sfc_main.c
2024-09-28 14:24:04 +08:00

1282 lines
46 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/****************************************************************************
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 3Enter 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 4D4H 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 5D4H 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 6D4H 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 7D4H 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 4D4H 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 5D4H 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 6D4H 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 7D4H 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 4D4H 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 5D4H 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 6D4H 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 7D4H 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 9EBH 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;
}