sdk:examples: update spi_master
Signed-off-by: liangkangnan <liangkangnan@163.com>pull/4/head
parent
22e6866dea
commit
9a8637be12
|
@ -13,6 +13,8 @@
|
||||||
* 5.擦除的最小单位是子扇区,编程(写)的最小单位是页,读的最小单位是字节
|
* 5.擦除的最小单位是子扇区,编程(写)的最小单位是页,读的最小单位是字节
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static uint8_t current_spi_mode;
|
||||||
|
|
||||||
|
|
||||||
void flash_n25q_init(uint16_t clk_div)
|
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_level(1);
|
||||||
spi0_set_ss_ctrl_by_sw(1);
|
spi0_set_ss_ctrl_by_sw(1);
|
||||||
spi0_set_enable(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, ...
|
// 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];
|
uint8_t tran_addr[3];
|
||||||
|
|
||||||
|
if (current_spi_mode == SPI_MODE_STANDARD)
|
||||||
cmd = CMD_READ;
|
cmd = CMD_READ;
|
||||||
|
else
|
||||||
|
cmd = CMD_FAST_READ;
|
||||||
|
|
||||||
tran_addr[0] = (addr >> 16) & 0xff;
|
tran_addr[0] = (addr >> 16) & 0xff;
|
||||||
tran_addr[1] = (addr >> 8) & 0xff;
|
tran_addr[1] = (addr >> 8) & 0xff;
|
||||||
tran_addr[2] = (addr >> 0) & 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_set_ss_level(0);
|
||||||
spi0_master_write_bytes(&cmd, 1);
|
spi0_master_write_bytes(&cmd, 1);
|
||||||
spi0_master_write_bytes(tran_addr, 3);
|
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_master_read_bytes(data, len);
|
||||||
spi0_set_ss_level(1);
|
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_enhanced_volatile_conf_reg(data);
|
||||||
|
|
||||||
flash_n25q_write_enable(0);
|
flash_n25q_write_enable(0);
|
||||||
|
|
||||||
|
if (en)
|
||||||
|
current_spi_mode = SPI_MODE_QUAD;
|
||||||
|
else
|
||||||
|
current_spi_mode = SPI_MODE_STANDARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置n25q dummy cycles
|
// 设置n25q dummy cycles
|
||||||
|
@ -225,55 +243,16 @@ void flash_n25q_set_dummy_clock_cycles(uint8_t num)
|
||||||
flash_n25q_write_enable(0);
|
flash_n25q_write_enable(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flash_n25q_quad_output_fast_read(uint32_t addr, uint8_t data[], uint32_t len)
|
// 读flash ID
|
||||||
{
|
|
||||||
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
|
|
||||||
n25q_id_t flash_n25q_read_id()
|
n25q_id_t flash_n25q_read_id()
|
||||||
{
|
{
|
||||||
n25q_id_t id;
|
n25q_id_t id;
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
uint8_t data[3];
|
uint8_t data[3];
|
||||||
|
|
||||||
|
if (current_spi_mode == SPI_MODE_STANDARD)
|
||||||
cmd = CMD_READ_ID;
|
cmd = CMD_READ_ID;
|
||||||
|
else
|
||||||
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;
|
cmd = CMD_MULTI_IO_READ_ID;
|
||||||
|
|
||||||
spi0_set_ss_level(0);
|
spi0_set_ss_level(0);
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#define CMD_READ (0x03)
|
#define CMD_READ (0x03)
|
||||||
#define CMD_FAST_READ (0x0b)
|
#define CMD_FAST_READ (0x0b)
|
||||||
#define CMD_QUAD_OUTPUT_FAST_READ (0x6b)
|
#define CMD_QUAD_OUTPUT_FAST_READ (0x6b)
|
||||||
#define CMD_4_4_4_FAST_READ (0xeb)
|
|
||||||
#define CMD_WRITE_DISABLE (0x04)
|
#define CMD_WRITE_DISABLE (0x04)
|
||||||
#define CMD_READ_STATUS_REG (0x05)
|
#define CMD_READ_STATUS_REG (0x05)
|
||||||
#define CMD_WRITE_ENABLE (0x06)
|
#define CMD_WRITE_ENABLE (0x06)
|
||||||
|
@ -32,7 +31,6 @@
|
||||||
#define CMD_WRITE_VOL_CONF_REG (0x81)
|
#define CMD_WRITE_VOL_CONF_REG (0x81)
|
||||||
#define CMD_READ_NONVOL_CONF_REG (0xB5)
|
#define CMD_READ_NONVOL_CONF_REG (0xB5)
|
||||||
|
|
||||||
|
|
||||||
#define DUMMY_CNT (0xa)
|
#define DUMMY_CNT (0xa)
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,13 +42,12 @@ typedef struct {
|
||||||
|
|
||||||
void flash_n25q_init(uint16_t clk_div);
|
void flash_n25q_init(uint16_t clk_div);
|
||||||
n25q_id_t flash_n25q_read_id();
|
n25q_id_t flash_n25q_read_id();
|
||||||
n25q_id_t flash_n25q_multi_io_read_id();
|
|
||||||
void flash_n25q_write_enable(uint8_t en);
|
void flash_n25q_write_enable(uint8_t en);
|
||||||
uint8_t flash_n25q_read_reg(uint8_t cmd);
|
uint8_t flash_n25q_read_reg(uint8_t cmd);
|
||||||
void flash_n25q_write_reg(uint8_t cmd, uint8_t data);
|
void flash_n25q_write_reg(uint8_t cmd, uint8_t data);
|
||||||
uint8_t flash_n25q_read_status_reg();
|
uint8_t flash_n25q_read_status_reg();
|
||||||
uint8_t flash_n25q_is_busy();
|
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_subsector_erase(uint32_t subsector);
|
||||||
void flash_n25q_sector_erase(uint32_t sector);
|
void flash_n25q_sector_erase(uint32_t sector);
|
||||||
void flash_n25q_page_program(uint8_t data[], uint32_t len, uint32_t page);
|
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_write_enhanced_volatile_conf_reg(uint8_t data);
|
||||||
void flash_n25q_enable_quad_mode(uint8_t en);
|
void flash_n25q_enable_quad_mode(uint8_t en);
|
||||||
void flash_n25q_set_dummy_clock_cycles(uint8_t num);
|
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();
|
uint8_t flash_n25q_read_nonvolatile_conf_reg();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,13 +16,90 @@ uint8_t program_data[BUFFER_SIZE];
|
||||||
uint8_t read_data[BUFFER_SIZE];
|
uint8_t read_data[BUFFER_SIZE];
|
||||||
|
|
||||||
|
|
||||||
int main()
|
static void standard_spi_test()
|
||||||
{
|
{
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
n25q_id_t id;
|
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_io0_func(IO0_UART0_TX);
|
||||||
pinmux_set_io3_func(IO3_UART0_RX);
|
pinmux_set_io3_func(IO3_UART0_RX);
|
||||||
|
// SPI引脚配置
|
||||||
pinmux_set_io10_func(IO10_SPI_CLK);
|
pinmux_set_io10_func(IO10_SPI_CLK);
|
||||||
pinmux_set_io11_func(IO11_SPI_SS);
|
pinmux_set_io11_func(IO11_SPI_SS);
|
||||||
pinmux_set_io12_func(IO12_SPI_DQ0);
|
pinmux_set_io12_func(IO12_SPI_DQ0);
|
||||||
|
@ -33,51 +110,8 @@ int main()
|
||||||
uart0_init(uart0_putc);
|
uart0_init(uart0_putc);
|
||||||
flash_n25q_init(5);
|
flash_n25q_init(5);
|
||||||
|
|
||||||
xprintf("read ID through standard SPI mode\n");
|
standard_spi_test();
|
||||||
id = flash_n25q_read_id();
|
quad_spi_test();
|
||||||
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);
|
|
||||||
|
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue