diff --git a/sdk/examples/spi_master/flash_n25q.c b/sdk/examples/spi_master/flash_n25q.c index 68a95ca..cd4fda8 100644 --- a/sdk/examples/spi_master/flash_n25q.c +++ b/sdk/examples/spi_master/flash_n25q.c @@ -13,6 +13,8 @@ * 5.擦除的最小单位是子扇区,编程(写)的最小单位是页,读的最小单位是字节 */ +static uint8_t current_spi_mode; + void flash_n25q_init(uint16_t clk_div) { @@ -25,6 +27,8 @@ void flash_n25q_init(uint16_t clk_div) spi0_set_ss_level(1); spi0_set_ss_ctrl_by_sw(1); spi0_set_enable(1); + + current_spi_mode = SPI_MODE_STANDARD; } // 写使能 @@ -86,12 +90,16 @@ uint8_t flash_n25q_is_busy() // 读数据 // addr: 0, 1, 2, ... -void flash_n25q_read_data(uint8_t data[], uint32_t len, uint32_t addr) +void flash_n25q_read(uint8_t data[], uint32_t len, uint32_t addr) { - uint8_t cmd; + uint8_t cmd, i; uint8_t tran_addr[3]; - cmd = CMD_READ; + if (current_spi_mode == SPI_MODE_STANDARD) + cmd = CMD_READ; + else + cmd = CMD_FAST_READ; + tran_addr[0] = (addr >> 16) & 0xff; tran_addr[1] = (addr >> 8) & 0xff; tran_addr[2] = (addr >> 0) & 0xff; @@ -99,6 +107,11 @@ void flash_n25q_read_data(uint8_t data[], uint32_t len, uint32_t addr) spi0_set_ss_level(0); spi0_master_write_bytes(&cmd, 1); spi0_master_write_bytes(tran_addr, 3); + if (current_spi_mode != SPI_MODE_STANDARD) { + for (i = 0; i < (DUMMY_CNT >> 1); i++) + spi0_master_read_bytes(data, 1); + spi0_reset_rxfifo(); + } spi0_master_read_bytes(data, len); spi0_set_ss_level(1); } @@ -208,6 +221,11 @@ void flash_n25q_enable_quad_mode(uint8_t en) flash_n25q_write_enhanced_volatile_conf_reg(data); flash_n25q_write_enable(0); + + if (en) + current_spi_mode = SPI_MODE_QUAD; + else + current_spi_mode = SPI_MODE_STANDARD; } // 设置n25q dummy cycles @@ -225,56 +243,17 @@ void flash_n25q_set_dummy_clock_cycles(uint8_t num) flash_n25q_write_enable(0); } -void flash_n25q_quad_output_fast_read(uint32_t addr, uint8_t data[], uint32_t len) -{ - uint8_t tran_addr[3]; - uint8_t cmd, i; - - cmd = CMD_QUAD_OUTPUT_FAST_READ; - - tran_addr[0] = (addr >> 16) & 0xff; - tran_addr[1] = (addr >> 8) & 0xff; - tran_addr[2] = (addr >> 0) & 0xff; - - spi0_set_ss_level(0); - spi0_master_write_bytes(&cmd, 1); - spi0_master_write_bytes(tran_addr, 3); - for (i = 0; i < (DUMMY_CNT >> 1); i++) - spi0_master_read_bytes(data, 1); - spi0_reset_rxfifo(); - spi0_master_read_bytes(data, len); - spi0_set_ss_level(1); -} - -// 标准SPI模式读flash ID +// 读flash ID n25q_id_t flash_n25q_read_id() { n25q_id_t id; uint8_t cmd; uint8_t data[3]; - cmd = CMD_READ_ID; - - spi0_set_ss_level(0); - spi0_master_write_bytes(&cmd, 1); - spi0_master_read_bytes(data, 3); - spi0_set_ss_level(1); - - id.manf_id = data[0]; - id.mem_type = data[1]; - id.mem_cap = data[2]; - - return id; -} - -// DUAL/QUAD SPI模式读flash ID -n25q_id_t flash_n25q_multi_io_read_id() -{ - n25q_id_t id; - uint8_t cmd; - uint8_t data[3]; - - cmd = CMD_MULTI_IO_READ_ID; + if (current_spi_mode == SPI_MODE_STANDARD) + cmd = CMD_READ_ID; + else + cmd = CMD_MULTI_IO_READ_ID; spi0_set_ss_level(0); spi0_master_write_bytes(&cmd, 1); diff --git a/sdk/examples/spi_master/flash_n25q.h b/sdk/examples/spi_master/flash_n25q.h index c12040f..4a24910 100644 --- a/sdk/examples/spi_master/flash_n25q.h +++ b/sdk/examples/spi_master/flash_n25q.h @@ -13,7 +13,6 @@ #define CMD_READ (0x03) #define CMD_FAST_READ (0x0b) #define CMD_QUAD_OUTPUT_FAST_READ (0x6b) -#define CMD_4_4_4_FAST_READ (0xeb) #define CMD_WRITE_DISABLE (0x04) #define CMD_READ_STATUS_REG (0x05) #define CMD_WRITE_ENABLE (0x06) @@ -32,7 +31,6 @@ #define CMD_WRITE_VOL_CONF_REG (0x81) #define CMD_READ_NONVOL_CONF_REG (0xB5) - #define DUMMY_CNT (0xa) @@ -44,13 +42,12 @@ typedef struct { void flash_n25q_init(uint16_t clk_div); n25q_id_t flash_n25q_read_id(); -n25q_id_t flash_n25q_multi_io_read_id(); void flash_n25q_write_enable(uint8_t en); uint8_t flash_n25q_read_reg(uint8_t cmd); void flash_n25q_write_reg(uint8_t cmd, uint8_t data); uint8_t flash_n25q_read_status_reg(); uint8_t flash_n25q_is_busy(); -void flash_n25q_read_data(uint8_t data[], uint32_t len, uint32_t addr); +void flash_n25q_read(uint8_t data[], uint32_t len, uint32_t addr); void flash_n25q_subsector_erase(uint32_t subsector); void flash_n25q_sector_erase(uint32_t sector); void flash_n25q_page_program(uint8_t data[], uint32_t len, uint32_t page); @@ -58,7 +55,6 @@ uint8_t flash_n25q_read_enhanced_volatile_conf_reg(); void flash_n25q_write_enhanced_volatile_conf_reg(uint8_t data); void flash_n25q_enable_quad_mode(uint8_t en); void flash_n25q_set_dummy_clock_cycles(uint8_t num); -void flash_n25q_quad_output_fast_read(uint32_t addr, uint8_t data[], uint32_t len); uint8_t flash_n25q_read_nonvolatile_conf_reg(); #endif diff --git a/sdk/examples/spi_master/main.c b/sdk/examples/spi_master/main.c index 6374cde..e487664 100644 --- a/sdk/examples/spi_master/main.c +++ b/sdk/examples/spi_master/main.c @@ -16,13 +16,90 @@ uint8_t program_data[BUFFER_SIZE]; uint8_t read_data[BUFFER_SIZE]; -int main() +static void standard_spi_test() { uint16_t i; n25q_id_t id; + xprintf("Standard SPI test started...\n"); + + id = flash_n25q_read_id(); + xprintf("manf id = 0x%2x\n", id.manf_id); + xprintf("mem type = 0x%2x\n", id.mem_type); + xprintf("mem cap = 0x%2x\n", id.mem_cap); + + // 初始化要编程的数据 + for (i = 0; i < BUFFER_SIZE; i++) + program_data[i] = i; + + // 擦除第0个子扇区 + flash_n25q_subsector_erase(0); + xprintf("program data: \n"); + // 打印读出来的数据 + for (i = 0; i < BUFFER_SIZE; i++) + xprintf("0x%x\n", program_data[i]); + // 编程第1页 + flash_n25q_page_program(program_data, BUFFER_SIZE, 1); + // 读第1页 + flash_n25q_read(read_data, BUFFER_SIZE, N25Q_PAGE_TO_ADDR(1)); + xprintf("read data: \n"); + // 打印读出来的数据 + for (i = 0; i < BUFFER_SIZE; i++) + xprintf("0x%x\n", read_data[i]); + + xprintf("Standard SPI test end...\n"); +} + +static void quad_spi_test() +{ + uint16_t i; + n25q_id_t id; + + xprintf("\nQuad SPI test started...\n"); + + flash_n25q_set_dummy_clock_cycles(DUMMY_CNT); + // 使能N25Q QSPI模式 + flash_n25q_enable_quad_mode(1); + // 使能SPI控制器QSPI模式 + spi0_set_spi_mode(SPI_MODE_QUAD); + + id = flash_n25q_read_id(); + xprintf("manf id = 0x%2x\n", id.manf_id); + xprintf("mem type = 0x%2x\n", id.mem_type); + xprintf("mem cap = 0x%2x\n", id.mem_cap); + + // 初始化要编程的数据 + for (i = 0; i < BUFFER_SIZE; i++) + program_data[i] = i; + + // 擦除第1个子扇区 + flash_n25q_subsector_erase(1); + xprintf("program data: \n"); + // 打印读出来的数据 + for (i = 0; i < BUFFER_SIZE; i++) + xprintf("0x%x\n", program_data[i]); + // 编程第16页 + flash_n25q_page_program(program_data, BUFFER_SIZE, 16); + // 读第16页 + flash_n25q_read(read_data, BUFFER_SIZE, N25Q_PAGE_TO_ADDR(16)); + xprintf("read data: \n"); + // 打印读出来的数据 + for (i = 0; i < BUFFER_SIZE; i++) + xprintf("0x%x\n", read_data[i]); + + // 失能N25Q QSPI模式 + flash_n25q_enable_quad_mode(0); + spi0_set_spi_mode(SPI_MODE_STANDARD); + + xprintf("Quad SPI test end...\n"); +} + +int main() +{ + // UART引脚配置 pinmux_set_io0_func(IO0_UART0_TX); pinmux_set_io3_func(IO3_UART0_RX); + // SPI引脚配置 pinmux_set_io10_func(IO10_SPI_CLK); pinmux_set_io11_func(IO11_SPI_SS); pinmux_set_io12_func(IO12_SPI_DQ0); @@ -33,51 +110,8 @@ int main() uart0_init(uart0_putc); flash_n25q_init(5); - xprintf("read ID through standard SPI mode\n"); - id = flash_n25q_read_id(); - xprintf("manf id = 0x%2x\n", id.manf_id); - xprintf("mem type = 0x%2x\n", id.mem_type); - xprintf("mem cap = 0x%2x\n", id.mem_cap); - - // 初始化要编程的数据 - for (i = 0; i < BUFFER_SIZE; i++) - program_data[i] = i; - - xprintf("start erase subsector...\n"); - // 擦除第0个子扇区 - flash_n25q_subsector_erase(0x00); - xprintf("start program page...\n"); - xprintf("program data: \n"); - // 打印读出来的数据 - for (i = 0; i < BUFFER_SIZE; i++) - xprintf("0x%x\n", program_data[i]); - // 编程第1页 - flash_n25q_page_program(program_data, BUFFER_SIZE, 0x01); - xprintf("start read page...\n"); - // 读第1页 - flash_n25q_read_data(read_data, BUFFER_SIZE, N25Q_PAGE_TO_ADDR(1)); - xprintf("read data: \n"); - // 打印读出来的数据 - for (i = 0; i < BUFFER_SIZE; i++) - xprintf("0x%x\n", read_data[i]); - - - flash_n25q_set_dummy_clock_cycles(DUMMY_CNT); - // 使能N25Q QSPI模式 - flash_n25q_enable_quad_mode(1); - // 使能SPI控制器QSPI模式 - spi0_set_spi_mode(SPI_MODE_QUAD); - xprintf("read ID through QUAD SPI mode\n"); - id = flash_n25q_multi_io_read_id(); - xprintf("manf id = 0x%2x\n", id.manf_id); - xprintf("mem type = 0x%2x\n", id.mem_type); - xprintf("mem cap = 0x%2x\n", id.mem_cap); - flash_n25q_quad_output_fast_read(N25Q_PAGE_TO_ADDR(1), read_data, BUFFER_SIZE); - xprintf("fast read data: \n"); - for (i = 0; i < BUFFER_SIZE; i++) - xprintf("0x%x\n", read_data[i]); - // 失能N25Q QSPI模式 - flash_n25q_enable_quad_mode(0); + standard_spi_test(); + quad_spi_test(); while (1); }