sdk:lib: add flash n25q

Signed-off-by: liangkangnan <liangkangnan@163.com>
pull/4/head
liangkangnan 2021-10-22 09:02:43 +08:00
parent 90d9349128
commit d8a7a67787
5 changed files with 69 additions and 94 deletions

View File

@ -28,6 +28,7 @@ C_SRCS += $(BSP_DIR)/lib/rvic.c
C_SRCS += $(BSP_DIR)/lib/i2c.c
C_SRCS += $(BSP_DIR)/lib/spi.c
C_SRCS += $(BSP_DIR)/lib/pinmux.c
C_SRCS += $(BSP_DIR)/lib/flash_n25q.c
LINKER_SCRIPT := $(BSP_DIR)/link.lds

View File

@ -40,8 +40,10 @@ typedef struct {
uint8_t mem_cap;
} n25q_id_t;
void flash_n25q_init(uint16_t clk_div);
n25q_id_t flash_n25q_read_id();
void flash_n25q_init(uint32_t controller, uint16_t clk_div);
void flash_n25q_set_spi_mode(uint8_t mode);
void flash_n25q_set_spi_controller(uint32_t controller);
n25q_id_t flash_n25q_read_id(uint8_t cmd);
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);
@ -51,10 +53,7 @@ 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);
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);
uint8_t flash_n25q_read_nonvolatile_conf_reg();
#endif

View File

@ -3,7 +3,7 @@
#include "../../bsp/include/spi.h"
#include "../../bsp/include/rvic.h"
#include "../../bsp/include/utils.h"
#include "flash_n25q.h"
#include "../../bsp/include/flash_n25q.h"
/* N25Q064特点:
* 1.64Mb8MB
@ -14,21 +14,32 @@
*/
static uint8_t current_spi_mode;
static uint32_t spi_base_addr;
void flash_n25q_init(uint16_t clk_div)
void flash_n25q_init(uint32_t controller, uint16_t clk_div)
{
spi_set_clk_div(SPI0, clk_div);
spi_set_role_mode(SPI0, SPI_ROLE_MODE_MASTER);
spi_set_spi_mode(SPI0, SPI_MODE_STANDARD);
spi_set_cp_mode(SPI0, SPI_CPOL_0_CPHA_0);
spi_set_msb_first(SPI0);
spi_master_set_ss_delay(SPI0, 1);
spi_set_ss_level(SPI0, 1);
spi_set_ss_ctrl_by_sw(SPI0, 1);
spi_set_enable(SPI0, 1);
spi_base_addr = controller;
current_spi_mode = SPI_MODE_STANDARD;
spi_set_clk_div(spi_base_addr, clk_div);
spi_set_role_mode(spi_base_addr, SPI_ROLE_MODE_MASTER);
spi_set_spi_mode(spi_base_addr, SPI_MODE_STANDARD);
spi_set_cp_mode(spi_base_addr, SPI_CPOL_0_CPHA_0);
spi_set_msb_first(spi_base_addr);
spi_master_set_ss_delay(spi_base_addr, 1);
spi_set_ss_level(spi_base_addr, 1);
spi_set_ss_ctrl_by_sw(spi_base_addr, 1);
spi_set_enable(spi_base_addr, 1);
}
void flash_n25q_set_spi_mode(uint8_t mode)
{
current_spi_mode = mode;
}
void flash_n25q_set_spi_controller(uint32_t controller)
{
spi_base_addr = controller;
}
// 写使能
@ -42,9 +53,9 @@ void flash_n25q_write_enable(uint8_t en)
else
cmd = CMD_WRITE_DISABLE;
spi_set_ss_level(SPI0, 0);
spi_master_write_bytes(SPI0, &cmd, 1);
spi_set_ss_level(SPI0, 1);
spi_set_ss_level(spi_base_addr, 0);
spi_master_write_bytes(spi_base_addr, &cmd, 1);
spi_set_ss_level(spi_base_addr, 1);
}
// 读寄存器
@ -52,10 +63,10 @@ uint8_t flash_n25q_read_reg(uint8_t cmd)
{
uint8_t data;
spi_set_ss_level(SPI0, 0);
spi_master_write_bytes(SPI0, &cmd, 1);
spi_master_read_bytes(SPI0, &data, 1);
spi_set_ss_level(SPI0, 1);
spi_set_ss_level(spi_base_addr, 0);
spi_master_write_bytes(spi_base_addr, &cmd, 1);
spi_master_read_bytes(spi_base_addr, &data, 1);
spi_set_ss_level(spi_base_addr, 1);
return data;
}
@ -63,10 +74,10 @@ uint8_t flash_n25q_read_reg(uint8_t cmd)
// 写寄存器
void flash_n25q_write_reg(uint8_t cmd, uint8_t data)
{
spi_set_ss_level(SPI0, 0);
spi_master_write_bytes(SPI0, &cmd, 1);
spi_master_write_bytes(SPI0, &data, 1);
spi_set_ss_level(SPI0, 1);
spi_set_ss_level(spi_base_addr, 0);
spi_master_write_bytes(spi_base_addr, &cmd, 1);
spi_master_write_bytes(spi_base_addr, &data, 1);
spi_set_ss_level(spi_base_addr, 1);
}
// 读状态寄存器
@ -104,16 +115,16 @@ void flash_n25q_read(uint8_t data[], uint32_t len, uint32_t addr)
tran_addr[1] = (addr >> 8) & 0xff;
tran_addr[2] = (addr >> 0) & 0xff;
spi_set_ss_level(SPI0, 0);
spi_master_write_bytes(SPI0, &cmd, 1);
spi_master_write_bytes(SPI0, tran_addr, 3);
spi_set_ss_level(spi_base_addr, 0);
spi_master_write_bytes(spi_base_addr, &cmd, 1);
spi_master_write_bytes(spi_base_addr, tran_addr, 3);
if (current_spi_mode != SPI_MODE_STANDARD) {
for (i = 0; i < (DUMMY_CNT >> 1); i++)
spi_master_read_bytes(SPI0, data, 1);
spi_reset_rxfifo(SPI0);
spi_master_read_bytes(spi_base_addr, data, 1);
spi_reset_rxfifo(spi_base_addr);
}
spi_master_read_bytes(SPI0, data, len);
spi_set_ss_level(SPI0, 1);
spi_master_read_bytes(spi_base_addr, data, len);
spi_set_ss_level(spi_base_addr, 1);
}
static void sector_erase(uint8_t cmd, uint32_t addr)
@ -126,10 +137,10 @@ static void sector_erase(uint8_t cmd, uint32_t addr)
tran_addr[1] = (addr >> 8) & 0xff;
tran_addr[2] = (addr >> 0) & 0xff;
spi_set_ss_level(SPI0, 0);
spi_master_write_bytes(SPI0, &cmd, 1);
spi_master_write_bytes(SPI0, tran_addr, 3);
spi_set_ss_level(SPI0, 1);
spi_set_ss_level(spi_base_addr, 0);
spi_master_write_bytes(spi_base_addr, &cmd, 1);
spi_master_write_bytes(spi_base_addr, tran_addr, 3);
spi_set_ss_level(spi_base_addr, 1);
while (flash_n25q_is_busy());
@ -167,43 +178,17 @@ void flash_n25q_page_program(uint8_t data[], uint32_t len, uint32_t page)
cmd = CMD_PAGE_PROGRAM;
spi_set_ss_level(SPI0, 0);
spi_master_write_bytes(SPI0, &cmd, 1);
spi_master_write_bytes(SPI0, tran_addr, 3);
spi_master_write_bytes(SPI0, data, len);
spi_set_ss_level(SPI0, 1);
spi_set_ss_level(spi_base_addr, 0);
spi_master_write_bytes(spi_base_addr, &cmd, 1);
spi_master_write_bytes(spi_base_addr, tran_addr, 3);
spi_master_write_bytes(spi_base_addr, data, len);
spi_set_ss_level(spi_base_addr, 1);
while (flash_n25q_is_busy());
flash_n25q_write_enable(0);
}
// 读增强型易失配置寄存器
uint8_t flash_n25q_read_enhanced_volatile_conf_reg()
{
uint8_t data;
data = flash_n25q_read_reg(CMD_READ_ENHANCED_VOL_CONF_REG);
return data;
}
// 读非易失配置寄存器
uint8_t flash_n25q_read_nonvolatile_conf_reg()
{
uint8_t data;
data = flash_n25q_read_reg(CMD_READ_NONVOL_CONF_REG);
return data;
}
// 写增强型易失配置寄存器
void flash_n25q_write_enhanced_volatile_conf_reg(uint8_t data)
{
flash_n25q_write_reg(CMD_WRITE_ENHANCED_VOL_CONF_REG, data);
}
// 使能QUAD SPI模式
void flash_n25q_enable_quad_mode(uint8_t en)
{
@ -211,21 +196,16 @@ void flash_n25q_enable_quad_mode(uint8_t en)
flash_n25q_write_enable(1);
data = flash_n25q_read_enhanced_volatile_conf_reg();
data = flash_n25q_read_reg(CMD_READ_ENHANCED_VOL_CONF_REG);
if (en) {
data &= ~(1 << 7);
data |= 1 << 6;
} else {
data |= 0x3 << 6;
}
flash_n25q_write_enhanced_volatile_conf_reg(data);
flash_n25q_write_reg(CMD_WRITE_ENHANCED_VOL_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
@ -244,21 +224,15 @@ void flash_n25q_set_dummy_clock_cycles(uint8_t num)
}
// 读flash ID
n25q_id_t flash_n25q_read_id()
n25q_id_t flash_n25q_read_id(uint8_t cmd)
{
n25q_id_t id;
uint8_t cmd;
uint8_t data[3];
if (current_spi_mode == SPI_MODE_STANDARD)
cmd = CMD_READ_ID;
else
cmd = CMD_MULTI_IO_READ_ID;
spi_set_ss_level(SPI0, 0);
spi_master_write_bytes(SPI0, &cmd, 1);
spi_master_read_bytes(SPI0, data, 3);
spi_set_ss_level(SPI0, 1);
spi_set_ss_level(spi_base_addr, 0);
spi_master_write_bytes(spi_base_addr, &cmd, 1);
spi_master_read_bytes(spi_base_addr, data, 3);
spi_set_ss_level(spi_base_addr, 1);
id.manf_id = data[0];
id.mem_type = data[1];

View File

@ -13,8 +13,7 @@ TARGET = spi_master
#INCLUDES += -I.
C_SRCS := \
main.c \
flash_n25q.c
main.c
BSP_DIR = ../../bsp

View File

@ -7,7 +7,7 @@
#include "../../bsp/include/rvic.h"
#include "../../bsp/include/pinmux.h"
#include "../../bsp/include/sim_ctrl.h"
#include "flash_n25q.h"
#include "../../bsp/include/flash_n25q.h"
#define BUFFER_SIZE (64)
@ -24,7 +24,7 @@ static void standard_spi_test()
xprintf("Standard SPI test started...\n");
// 读flash ID
id = flash_n25q_read_id();
id = flash_n25q_read_id(CMD_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);
@ -64,9 +64,10 @@ static void quad_spi_test()
flash_n25q_enable_quad_mode(1);
// 使能SPI控制器QSPI模式
spi_set_spi_mode(SPI0, SPI_MODE_QUAD);
flash_n25q_set_spi_mode(SPI_MODE_QUAD);
// 读flash ID
id = flash_n25q_read_id();
id = flash_n25q_read_id(CMD_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);
@ -93,6 +94,7 @@ static void quad_spi_test()
// 失能N25Q QSPI模式
flash_n25q_enable_quad_mode(0);
spi_set_spi_mode(SPI0, SPI_MODE_STANDARD);
flash_n25q_set_spi_mode(SPI_MODE_STANDARD);
xprintf("Quad SPI test end...\n");
}
@ -111,7 +113,7 @@ int main()
pinmux_set_io15_func(IO15_SPI_DQ3);
uart_init(UART0, uart0_putc);
flash_n25q_init(5);
flash_n25q_init(SPI0, 5);
standard_spi_test();
quad_spi_test();