sdk: update flash_ctrl

Signed-off-by: liangkangnan <liangkangnan@163.com>
verilator
liangkangnan 2023-04-03 10:36:04 +08:00
parent b61fd21057
commit 5dd0fa4034
3 changed files with 32 additions and 241 deletions

View File

@ -1,72 +1,18 @@
// Generated register defines for flash_ctrl
// Copyright information found in source file:
// Copyright lowRISC contributors.
// Licensing information found in source file:
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#ifndef _FLASH_CTRL_REG_DEFS_
#define _FLASH_CTRL_REG_DEFS_
#ifdef __cplusplus
extern "C" {
#endif
// Register width
#define FLASH_CTRL_PARAM_REG_WIDTH 32
#define FLASH_CTRL_BASE_ADDR (0x0E000000)
#define FLASH_CTRL_REG(offset) (*((volatile uint32_t *)(FLASH_CTRL_BASE_ADDR + offset)))
typedef enum {
FLASH_OP_READ = 0,
FLASH_OP_PROGRAM,
FLASH_OP_ERASE,
FLASH_OP_INIT
} flash_op_mode_e;
void flash_ctrl_init();
void flash_ctrl_deinit();
void flash_ctrl_qspi_init();
void flash_ctrl_read(uint32_t start_addr, uint32_t *data, uint32_t len);
uint8_t flash_ctrl_page_program(uint32_t page_addr, uint32_t *data, uint32_t len);
uint8_t flash_ctrl_sector_erase(uint32_t sector_addr);
// flash_ctrl control register
#define FLASH_CTRL_CTRL_REG_OFFSET 0x0
#define FLASH_CTRL_CTRL_REG_RESVAL 0x0
#define FLASH_CTRL_CTRL_START_BIT 0
#define FLASH_CTRL_CTRL_OP_MODE_MASK 0x3
#define FLASH_CTRL_CTRL_OP_MODE_OFFSET 1
#define FLASH_CTRL_CTRL_OP_MODE_FIELD \
((bitfield_field32_t) { .mask = FLASH_CTRL_CTRL_OP_MODE_MASK, .index = FLASH_CTRL_CTRL_OP_MODE_OFFSET })
#define FLASH_CTRL_CTRL_SW_CTRL_BIT 3
#define FLASH_CTRL_CTRL_PROGRAM_INIT_BIT 4
#define FLASH_CTRL_CTRL_WRITE_ERROR_BIT 5
#define FLASH_CTRL_CTRL_RESERVED_MASK 0x3ffffff
#define FLASH_CTRL_CTRL_RESERVED_OFFSET 6
#define FLASH_CTRL_CTRL_RESERVED_FIELD \
((bitfield_field32_t) { .mask = FLASH_CTRL_CTRL_RESERVED_MASK, .index = FLASH_CTRL_CTRL_RESERVED_OFFSET })
// flash_ctrl address register
#define FLASH_CTRL_ADDR_REG_OFFSET 0x4
#define FLASH_CTRL_ADDR_REG_RESVAL 0x0
#define FLASH_CTRL_ADDR_RW_ADDRESS_MASK 0x7fffff
#define FLASH_CTRL_ADDR_RW_ADDRESS_OFFSET 0
#define FLASH_CTRL_ADDR_RW_ADDRESS_FIELD \
((bitfield_field32_t) { .mask = FLASH_CTRL_ADDR_RW_ADDRESS_MASK, .index = FLASH_CTRL_ADDR_RW_ADDRESS_OFFSET })
#define FLASH_CTRL_ADDR_RESERVED_MASK 0x1ff
#define FLASH_CTRL_ADDR_RESERVED_OFFSET 23
#define FLASH_CTRL_ADDR_RESERVED_FIELD \
((bitfield_field32_t) { .mask = FLASH_CTRL_ADDR_RESERVED_MASK, .index = FLASH_CTRL_ADDR_RESERVED_OFFSET })
// flash_ctrl data register
#define FLASH_CTRL_DATA_REG_OFFSET 0x8
#define FLASH_CTRL_DATA_REG_RESVAL 0x0
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _FLASH_CTRL_REG_DEFS_
// End generated register defines for flash_ctrl
#ifndef _FLASH_CTRL_H_
#define _FLASH_CTRL_H_
#ifdef __cplusplus
extern "C" {
#endif
#define FLASH_CTRL_SECTOR_ERASE_FLAG (1 << 23)
#define FLASH_CTRL(offset) (*((volatile uint32_t *)(0x02000000 + (offset))))
void flash_ctrl_sector_erase(uint32_t sector_addr_offset);
void flash_ctrl_write(uint32_t offset, uint32_t data);
void flash_ctrl_read(uint32_t offset, uint32_t *data);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@ -3,120 +3,17 @@
#include "../../bsp/include/flash_ctrl.h"
#include "../../bsp/include/utils.h"
void flash_ctrl_init()
void flash_ctrl_sector_erase(uint32_t sector_addr_offset)
{
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) |= 1 << FLASH_CTRL_CTRL_SW_CTRL_BIT;
FLASH_CTRL(sector_addr_offset | FLASH_CTRL_SECTOR_ERASE_FLAG) = 0x0;
}
void flash_ctrl_deinit()
void flash_ctrl_write(uint32_t offset, uint32_t data)
{
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) &= ~(1 << FLASH_CTRL_CTRL_SW_CTRL_BIT);
FLASH_CTRL(offset) = data;
}
// 初始化flash为QSPI模式
void flash_ctrl_qspi_init()
void flash_ctrl_read(uint32_t offset, uint32_t *data)
{
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) &= ~(FLASH_CTRL_CTRL_OP_MODE_MASK << FLASH_CTRL_CTRL_OP_MODE_OFFSET);
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) |= (FLASH_OP_INIT << FLASH_CTRL_CTRL_OP_MODE_OFFSET);
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) |= 1 << FLASH_CTRL_CTRL_START_BIT;
while (FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) & (1 << FLASH_CTRL_CTRL_START_BIT));
}
static void flash_ctrl_program_init()
{
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) |= 1 << FLASH_CTRL_CTRL_PROGRAM_INIT_BIT;
}
static void flash_ctrl_program_deinit()
{
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) &= ~(1 << FLASH_CTRL_CTRL_PROGRAM_INIT_BIT);
}
// 读数据
void flash_ctrl_read(uint32_t start_addr, uint32_t *data, uint32_t len)
{
uint32_t addr, i;
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) &= ~(FLASH_CTRL_CTRL_OP_MODE_MASK << FLASH_CTRL_CTRL_OP_MODE_OFFSET);
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) |= (FLASH_OP_READ << FLASH_CTRL_CTRL_OP_MODE_OFFSET);
addr = start_addr;
len = len >> 2;
for (i = 0; i < len; i++) {
FLASH_CTRL_REG(FLASH_CTRL_ADDR_REG_OFFSET) = addr & FLASH_CTRL_ADDR_RW_ADDRESS_MASK;
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) |= 1 << FLASH_CTRL_CTRL_START_BIT;
while (FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) & (1 << FLASH_CTRL_CTRL_START_BIT));
data[i] = FLASH_CTRL_REG(FLASH_CTRL_DATA_REG_OFFSET);
addr += 4;
}
}
// 以word为单位进行烧写一次最多烧一个page(256个字节)
// 返回值1成功0失败
uint8_t flash_ctrl_page_program(uint32_t page_addr, uint32_t *data, uint32_t len)
{
uint32_t i, index;
uint32_t prog_len, remain_len;
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) &= ~(FLASH_CTRL_CTRL_OP_MODE_MASK << FLASH_CTRL_CTRL_OP_MODE_OFFSET);
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) |= (FLASH_OP_PROGRAM << FLASH_CTRL_CTRL_OP_MODE_OFFSET);
FLASH_CTRL_REG(FLASH_CTRL_ADDR_REG_OFFSET) = page_addr & FLASH_CTRL_ADDR_RW_ADDRESS_MASK;
if (len > 4)
flash_ctrl_program_init();
remain_len = len;
index = 0;
while (remain_len > 0) {
// 一次最多烧32个byte
if (remain_len > 32)
prog_len = 32;
else
prog_len = remain_len;
remain_len -= prog_len;
// word的个数
prog_len = prog_len >> 2;
// 每次烧写一个word
for (i = 0; i < prog_len; i++) {
FLASH_CTRL_REG(FLASH_CTRL_DATA_REG_OFFSET) = data[index];
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) |= 1 << FLASH_CTRL_CTRL_START_BIT;
while (FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) & (1 << FLASH_CTRL_CTRL_START_BIT));
index++;
}
}
if (len > 4) {
flash_ctrl_program_deinit();
while (FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) & (1 << FLASH_CTRL_CTRL_START_BIT));
}
if (FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) & (1 << FLASH_CTRL_CTRL_WRITE_ERROR_BIT))
return 0;
else
return 1;
}
// 扇区擦除
// 返回值1成功0失败
uint8_t flash_ctrl_sector_erase(uint32_t sector_addr)
{
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) &= ~(FLASH_CTRL_CTRL_OP_MODE_MASK << FLASH_CTRL_CTRL_OP_MODE_OFFSET);
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) |= (FLASH_OP_ERASE << FLASH_CTRL_CTRL_OP_MODE_OFFSET);
FLASH_CTRL_REG(FLASH_CTRL_ADDR_REG_OFFSET) = sector_addr & FLASH_CTRL_ADDR_RW_ADDRESS_MASK;
FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) |= 1 << FLASH_CTRL_CTRL_START_BIT;
while (FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) & (1 << FLASH_CTRL_CTRL_START_BIT));
if (FLASH_CTRL_REG(FLASH_CTRL_CTRL_REG_OFFSET) & (1 << FLASH_CTRL_CTRL_WRITE_ERROR_BIT))
return 0;
else
return 1;
*data = FLASH_CTRL(offset);
}

View File

@ -1,69 +1,17 @@
#include <stdint.h>
#include "../../bsp/include/uart.h"
#include "../../bsp/include/xprintf.h"
#include "../../bsp/include/pinmux.h"
#include "../../bsp/include/utils.h"
#include "../../bsp/include/flash_ctrl.h"
#define DATA_BUF_LEN (32)
// bytes = DATA_BUF_LEN * 4
#define DATA_BYTES (DATA_BUF_LEN << 2)
static uint32_t write_data_buf[DATA_BUF_LEN];
static uint32_t read_data_buf[DATA_BUF_LEN];
int main()
{
uint32_t i;
uint32_t data;
// UART引脚配置
pinmux_set_io0_func(IO0_UART0_TX);
pinmux_set_io3_func(IO3_UART0_RX);
// UART初始化
uart_init(UART0, uart0_putc);
flash_ctrl_sector_erase(0x0);
flash_ctrl_write(0x00, 0x12345678);
flash_ctrl_read(0x00, &data);
flash_ctrl_init();
if (data != 0x12345678)
return -1;
// 擦除0子扇区
if (!flash_ctrl_sector_erase(0))
xprintf("erase failed...\n");
// 构造编程数据
for (i = 0; i < DATA_BUF_LEN; i++)
write_data_buf[i] = i;
// 编程第0页
if (!flash_ctrl_page_program(0, write_data_buf, DATA_BYTES))
xprintf("program failed...\n");
// 读0x0地址开始的数据
flash_ctrl_read(0, read_data_buf, DATA_BYTES);
flash_ctrl_deinit();
// 打印读到的数据
for (i = 0; i < DATA_BUF_LEN; i++)
xprintf("0x%x\n", read_data_buf[i]);
/************************** QSPI测试 **************************/
flash_ctrl_init();
// QSPI初始化
flash_ctrl_qspi_init();
// 读0x0地址开始的数据
flash_ctrl_read(0, read_data_buf, DATA_BYTES);
flash_ctrl_deinit();
xprintf("\nquad spi test, read data:\n");
// 打印读到的数据
for (i = 0; i < DATA_BUF_LEN; i++)
xprintf("0x%x\n", read_data_buf[i]);
while (1);
return 0;
}