| | |
| | | .is_open = 0, |
| | | #else |
| | | .is_open = 1, // Flash has been opened by default in XIP mode |
| | | .state = FLASH_STATE_READY, |
| | | #endif |
| | | }, |
| | | }; |
| | | |
| | | #if defined(XIP_EN) |
| | | extern struct FLASH_CMD_T flash_cmd[FLASH_MAX_NUM][FLASH_OPCODE_NUM]; |
| | | struct FLASH_CMD_T flash_cmd[FLASH_MAX_NUM][FLASH_OPCODE_NUM] = { |
| | | { |
| | | // QUAD |
| | | //{false, FLASH_DATA_IN, FLASH_CMD_DATA_QUAD_DUAL, FLASH_CMD_OP_ADDR_3B, FLASH_SECTOR_SIZE, 1, 0x6B}, |
| | | {false, FLASH_DATA_IN, FLASH_CMD_OP_SERIAL, FLASH_CMD_OP_ADDR_3B, FLASH_SECTOR_SIZE, 3, 0xEB}, |
| | | {false, FLASH_DATA_OUT, FLASH_CMD_DATA_QUAD_DUAL, FLASH_CMD_OP_ADDR_3B, FLASH_PAGE_SIZE, 0, 0x32}, |
| | | // DUAL |
| | | //{false, FLASH_DATA_IN, FLASH_CMD_DATA_QUAD_DUAL, FLASH_CMD_OP_ADDR_3B, FLASH_SECTOR_SIZE, 1, 0x3B}, |
| | | //{false, FLASH_DATA_IN, FLASH_CMD_OP_SERIAL, FLASH_CMD_OP_ADDR_3B, FLASH_SECTOR_SIZE, 1, 0xBB}, |
| | | //{false, FLASH_DATA_OUT, FLASH_CMD_ALL_SERIAL, FLASH_CMD_OP_ADDR_3B, FLASH_PAGE_SIZE, 0, 0x02}, |
| | | // STD |
| | | //{false, FLASH_DATA_IN, FLASH_CMD_ALL_SERIAL, FLASH_CMD_OP_ADDR_3B, FLASH_SECTOR_SIZE, 0, 0x03}, |
| | | //{false, FLASH_DATA_OUT, FLASH_CMD_ALL_SERIAL, FLASH_CMD_OP_ADDR_3B, FLASH_PAGE_SIZE, 0, 0x02}, |
| | | {false, FLASH_DATA_IN, FLASH_CMD_ALL_SERIAL, FLASH_CMD_OP_ONLY, 1, 0, 0x05}, |
| | | {false, FLASH_DATA_IN, FLASH_CMD_ALL_SERIAL, FLASH_CMD_OP_ONLY, 1, 0, 0x35}, |
| | | {false, FLASH_DATA_OUT, FLASH_CMD_ALL_SERIAL, FLASH_CMD_OP_ADDR_3B, 0, 0, 0x20}, |
| | | {false, FLASH_DATA_OUT, FLASH_CMD_ALL_SERIAL, FLASH_CMD_OP_ADDR_3B, 0, 0, 0xD8}, |
| | | {false, FLASH_DATA_OUT, FLASH_CMD_ALL_SERIAL, FLASH_CMD_OP_ONLY, 0, 0, 0x06}, |
| | | {false, FLASH_DATA_OUT, FLASH_CMD_ALL_SERIAL, FLASH_CMD_OP_ONLY, 2, 0, 0x01}, |
| | | {false, FLASH_DATA_IN, FLASH_CMD_ALL_SERIAL, FLASH_CMD_OP_ONLY, 3, 0, 0x9F}, |
| | | {false, FLASH_DATA_OUT, FLASH_CMD_ALL_SERIAL, FLASH_CMD_OP_ONLY, 0, 0, 0xB9}, // Deep power down |
| | | {false, FLASH_DATA_OUT, FLASH_CMD_ALL_SERIAL, FLASH_CMD_OP_ONLY, 0, 0, 0xAB}, // Release from Deep power down |
| | | }, |
| | | }; |
| | | #else |
| | | static const struct FLASH_CMD_T flash_cmd[FLASH_MAX_NUM][FLASH_OPCODE_NUM] = { |
| | | { |
| | | // QUAD |
| | |
| | | {false, FLASH_DATA_OUT, FLASH_CMD_ALL_SERIAL, FLASH_CMD_OP_ONLY, 0, 0, 0xAB}, // Release from Deep power down |
| | | }, |
| | | }; |
| | | #endif |
| | | |
| | | static void flash_wait_status(enum FLASH_DEV_T id, uint32_t mask, uint32_t status) |
| | | static void RAM_FUNC flash_wait_status(enum FLASH_DEV_T id, uint32_t mask, uint32_t status) |
| | | { |
| | | uint32_t start = sys_timer_get(); |
| | | while ((flash_handle[id].base->STATUS & mask) == status) |
| | |
| | | } |
| | | } |
| | | |
| | | static void flash_reset_cmd(enum FLASH_DEV_T id) |
| | | static void RAM_FUNC flash_reset_cmd(enum FLASH_DEV_T id) |
| | | { |
| | | flash_handle[id].base->STATUS = FLASH_STATUS_RESET_MSK; |
| | | /* Wait for the RESET flag cleared by HW */ |
| | | flash_wait_status(id, FLASH_STATUS_RESET_MSK, FLASH_STATUS_RESET_MSK); |
| | | } |
| | | |
| | | static void flash_write_cmd(enum FLASH_DEV_T id, enum FLASH_OPCODE_T opcode) |
| | | static void RAM_FUNC flash_write_cmd(enum FLASH_DEV_T id, enum FLASH_OPCODE_T opcode) |
| | | { |
| | | /* Wait for the CMD and MCINT flag all be 0 */ |
| | | flash_wait_status(id, FLASH_STATUS_MCINIT_MSK, FLASH_STATUS_MCINIT_MSK); |
| | |
| | | } |
| | | |
| | | #if FLASH_WRITE_EN |
| | | static void flash_write_variable_len_cmd(enum FLASH_DEV_T id, const uint32_t len) |
| | | static void RAM_FUNC flash_write_variable_len_cmd(enum FLASH_DEV_T id, const uint32_t len) |
| | | { |
| | | /* Wait for the CMD and MCINT flag all be 0 */ |
| | | flash_wait_status(id, FLASH_STATUS_MCINIT_MSK, FLASH_STATUS_MCINIT_MSK); |
| | |
| | | } |
| | | #endif |
| | | |
| | | static void flash_write_mem_cmd(enum FLASH_DEV_T id, enum FLASH_OPCODE_T opcode) |
| | | static void RAM_FUNC flash_write_mem_cmd(enum FLASH_DEV_T id, enum FLASH_OPCODE_T opcode) |
| | | { |
| | | /* Wait for the CMD and MCINT flag all be 0 */ |
| | | flash_wait_status(id, FLASH_STATUS_MCINIT_MSK, FLASH_STATUS_MCINIT_MSK); |
| | |
| | | FLASH_MCMD_OPCODE(flash_cmd[id][opcode].opcode); |
| | | } |
| | | |
| | | static uint8_t flash_read_status(enum FLASH_DEV_T id) |
| | | static uint8_t RAM_FUNC flash_read_status(enum FLASH_DEV_T id) |
| | | { |
| | | flash_write_cmd(id, FLASH_OPCODE_GET_STATUS); |
| | | flash_wait_status(id, FLASH_STATUS_INTRQ_MSK, 0U); |
| | |
| | | return (val1); |
| | | } |
| | | |
| | | static void flash_wait_done(enum FLASH_DEV_T id, uint32_t timeout) |
| | | static void RAM_FUNC flash_wait_done(enum FLASH_DEV_T id, uint32_t timeout) |
| | | { |
| | | uint32_t start = sys_timer_get(); |
| | | /* Check WIP bit */ |
| | |
| | | #endif |
| | | |
| | | #if FLASH_WRITE_EN |
| | | static int flash_page_write_nbytes(enum FLASH_DEV_T id, uint32_t addr, const uint8_t *buf, uint32_t len) |
| | | static int RAM_FUNC flash_page_write_nbytes(enum FLASH_DEV_T id, uint32_t addr, const uint8_t *buf, uint32_t len) |
| | | { |
| | | // Write enable |
| | | flash_write_cmd(id, FLASH_OPCODE_WRITE_ENABLE); |
| | |
| | | return DRV_OK; |
| | | } |
| | | |
| | | static int flash_page_write(enum FLASH_DEV_T id, uint32_t page, const uint8_t *buf) |
| | | static int RAM_FUNC flash_page_write(enum FLASH_DEV_T id, uint32_t page, const uint8_t *buf) |
| | | { |
| | | LOG_INFO(TRACE_MODULE_DRIVER, "flash_page_write %d\r\n", page); |
| | | // LOG_INFO(TRACE_MODULE_DRIVER, "flash_page_write %d\r\n", page); |
| | | |
| | | // Write enable |
| | | flash_write_cmd(id, FLASH_OPCODE_WRITE_ENABLE); |
| | |
| | | { |
| | | return ret; |
| | | } |
| | | |
| | | #if defined(XIP_EN) |
| | | uint32_t lock = int_lock(); |
| | | #endif |
| | | |
| | | // Reset the flash controller to switch to command mode |
| | | flash_reset_cmd(id); |
| | |
| | | flash_handle[id].state = FLASH_STATE_READY; |
| | | } |
| | | |
| | | #if defined(XIP_EN) |
| | | int_unlock(lock); |
| | | #endif |
| | | |
| | | return DRV_OK; |
| | | } |
| | | |
| | |
| | | { |
| | | return ret; |
| | | } |
| | | |
| | | #if defined(XIP_EN) |
| | | uint32_t lock = int_lock(); |
| | | #endif |
| | | |
| | | // Reset the flash controller to switch to command mode |
| | | flash_reset_cmd(id); |
| | |
| | | // update state |
| | | flash_handle[id].state = FLASH_STATE_READY; |
| | | } |
| | | |
| | | #if defined(XIP_EN) |
| | | int_unlock(lock); |
| | | #endif |
| | | |
| | | return DRV_OK; |
| | | } |
| | | |
| | |
| | | |
| | | flash_init_write_nbytes_cfg(id, start_addr, buf, len); |
| | | |
| | | #if defined(XIP_EN) |
| | | uint32_t lock = int_lock(); |
| | | #endif |
| | | |
| | | // Reset the flash controller to switch to command mode |
| | | flash_reset_cmd(id); |
| | | if (flash_handle[id].config.dma_en) |
| | |
| | | flash_handle[id].state = FLASH_STATE_READY; |
| | | } |
| | | |
| | | #if defined(XIP_EN) |
| | | int_unlock(lock); |
| | | #endif |
| | | |
| | | return DRV_OK; |
| | | } |
| | | |
| | |
| | | uint32_t offset_addr = start_addr - flash_handle[id].config.start_addr; |
| | | uint32_t page_start = offset_addr / flash_handle[id].config.page_size; |
| | | uint32_t page_end = (offset_addr + len) / flash_handle[id].config.page_size; |
| | | |
| | | #if defined(XIP_EN) |
| | | uint32_t lock = int_lock(); |
| | | #endif |
| | | |
| | | // Reset the flash controller to switch to command mode |
| | | flash_reset_cmd(id); |
| | |
| | | // update state |
| | | flash_handle[id].state = FLASH_STATE_READY; |
| | | } |
| | | |
| | | #if defined(XIP_EN) |
| | | int_unlock(lock); |
| | | #endif |
| | | |
| | | return DRV_OK; |
| | | } |
| | | #else |
| | |
| | | return ret; |
| | | } |
| | | |
| | | #ifndef XIP_EN |
| | | // Reset the flash controller to switch to command mode |
| | | flash_reset_cmd(id); |
| | | |
| | |
| | | // update state |
| | | flash_handle[id].state = FLASH_STATE_READY; |
| | | } |
| | | |
| | | #else |
| | | memcpy(buf, (uint8_t *)(start_addr), len); |
| | | // update state |
| | | flash_handle[id].state = FLASH_STATE_READY; |
| | | #endif |
| | | return DRV_OK; |
| | | } |
| | | |