diff --git a/sdk/bsp/include/flash_ctrl.h b/sdk/bsp/include/flash_ctrl.h index 316cbae..8f9e917 100644 --- a/sdk/bsp/include/flash_ctrl.h +++ b/sdk/bsp/include/flash_ctrl.h @@ -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 \ No newline at end of file +#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 diff --git a/sdk/bsp/lib/flash_ctrl.c b/sdk/bsp/lib/flash_ctrl.c index 21f50cd..e3bc785 100644 --- a/sdk/bsp/lib/flash_ctrl.c +++ b/sdk/bsp/lib/flash_ctrl.c @@ -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); } diff --git a/sdk/examples/flash_ctrl/main.c b/sdk/examples/flash_ctrl/main.c index c9fee37..75faf81 100644 --- a/sdk/examples/flash_ctrl/main.c +++ b/sdk/examples/flash_ctrl/main.c @@ -1,69 +1,17 @@ #include - -#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; }