diff --git a/example/boot2/CMakeLists.txt b/example/boot2/CMakeLists.txt index d154bdc..7b6de43 100644 --- a/example/boot2/CMakeLists.txt +++ b/example/boot2/CMakeLists.txt @@ -11,4 +11,5 @@ target_sources(${EXAMPLE_NAME}.elf PUBLIC boot2_pre.S) add_subdirectory(${SDK_BASE_DIR} sdk) target_link_libraries(${EXAMPLE_NAME}.elf sdk) - +add_subdirectory(${EXAMPLE_BASE_DIR}/src src) +target_link_libraries(${EXAMPLE_NAME}.elf src) diff --git a/example/boot2/src/CMakeLists.txt b/example/boot2/src/CMakeLists.txt new file mode 100644 index 0000000..5c87fca --- /dev/null +++ b/example/boot2/src/CMakeLists.txt @@ -0,0 +1,10 @@ +file(GLOB FILELIST +flash.c +) + +set(TARGET src) +add_library(${TARGET} STATIC ${FILELIST}) + +target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(${TARGET} PUBLIC ${SDK_BASE_DIR}/driver/inc) +target_include_directories(${TARGET} PUBLIC ${SDK_BASE_DIR}/driver/inc/reg) diff --git a/example/boot2/src/flash.c b/example/boot2/src/flash.c new file mode 100644 index 0000000..842830c --- /dev/null +++ b/example/boot2/src/flash.c @@ -0,0 +1,98 @@ +#include "gpio.h" +#include "ssi_reg.h" +#include "flash.h" + +static void flash_cs_force_low(void) +{ + io_rw_32 *reg; + + /* force QSPI_CS low level as selected */ + reg = (io_rw_32 *)(IO_QSPI_BASE + GPIO_QSPI_CS_CTRL_OFFSET); + *reg = GPIO_OVER_OUT_FORCE_LOW << GPIO_OVER_OUT_POS; +} + +static void flash_cs_force_high(void) +{ + io_rw_32 *reg; + + /* force QSPI_CS high level as disselected */ + reg = (io_rw_32 *)(IO_QSPI_BASE + GPIO_QSPI_CS_CTRL_OFFSET); + *reg = GPIO_OVER_OUT_FORCE_HIGH << GPIO_OVER_OUT_POS; +} + +static void flash_put_get(uint8_t *tx, uint8_t *rx, uint32_t count, uint32_t rx_skip) +{ + uint32_t tx_count = count; + uint32_t rx_count = count; + while (tx_count || rx_skip || rx_count) { + uint32_t tx_level = ssi_hw->txflr; + uint32_t rx_level = ssi_hw->rxflr; + if (tx_count && tx_level + rx_level < 14) { + ssi_hw->dr0 = (uint32_t) (tx ? *tx++ : 0); + --tx_count; + } + if (rx_level) { + uint8_t rxbyte = ssi_hw->dr0; + if (rx_skip) { + --rx_skip; + } else { + if (rx) + *rx++ = rxbyte; + --rx_count; + } + } + } + flash_cs_force_high(); +} + +static void flash_do_cmd(uint8_t cmd, uint8_t *tx, uint8_t *rx, uint32_t count) +{ + flash_cs_force_low(); + ssi_hw->dr0 = cmd; + flash_put_get(tx, rx, count, 1); +} + +static void flash_put_cmd_addr(uint8_t cmd, uint32_t addr) +{ + flash_cs_force_low(); + addr |= cmd << 24; + for (int i = 0; i < 4; ++i) { + ssi_hw->dr0 = addr >> 24; + addr <<= 8; + } +} + +static void flash_enable_write(void) +{ + flash_do_cmd(FLASHCMD_WRITE_ENABLE, (void *)0, (void *)0, 0); +} + +static void flash_wait_ready(void) +{ + uint8_t stat; + do { + flash_do_cmd(FLASHCMD_READ_STATUS, (void *)0, &stat, 1); + } while (stat & 0x1); +} + +void flash_erase(uint32_t addr) +{ + flash_enable_write(); + flash_put_cmd_addr(FLASHCMD_SECTOR_ERASE, addr); + flash_put_get((void *)0, (void *)0, 0, 4); + flash_wait_ready(); +} + +void flash_write(uint32_t addr, uint8_t *data) +{ + flash_enable_write(); + flash_put_cmd_addr(FLASHCMD_PAGE_PROGRAM, addr); + flash_put_get(data, (void *)0, FLASH_WRITE_SIZE, 4); + flash_wait_ready(); +} + +void flash_read(uint32_t addr, uint8_t *data, uint32_t length) +{ + flash_put_cmd_addr(FLASHCMD_READ_DATA, addr); + flash_put_get((void *)0, data, length, 4); +} diff --git a/example/boot2/src/flash.h b/example/boot2/src/flash.h new file mode 100644 index 0000000..553ca64 --- /dev/null +++ b/example/boot2/src/flash.h @@ -0,0 +1,29 @@ +#ifndef __FLASH_H__ +#define __FLASH_H__ + +#include "stdint.h" + +#define FLASHCMD_PAGE_PROGRAM (0x02) +#define FLASHCMD_READ_DATA (0x03) +#define FLASHCMD_READ_STATUS (0x05) +#define FLASHCMD_WRITE_ENABLE (0x06) +#define FLASHCMD_SECTOR_ERASE (0x20) +#define FLASHCMD_READ_SFDP (0x5A) +#define FLASHCMD_READ_JEDEC_ID (0x9F) + +#define FLASH_WRITE_SIZE (256) +#define FLASH_ERASE_SIZE (4096) + +#ifdef __cplusplus +extern "C" { +#endif + +void flash_erase(uint32_t addr); +void flash_write(uint32_t addr, uint8_t *data); +void flash_read(uint32_t addr, uint8_t *data, uint32_t length); + +#ifdef __cplusplus +} +#endif + +#endif /* __FLASH_H__ */ \ No newline at end of file diff --git a/project.build b/project.build index 6a72c46..3d13023 100644 --- a/project.build +++ b/project.build @@ -50,6 +50,7 @@ cmake_definition+= -DCMAKE_EXE_LINKER_FLAGS="$(LDFLAGS)" cmake_definition+= -DCONFIG_COMX=$(COMX) cmake_definition+= -DSDK_BASE_DIR=$(SDK_BASE_DIR) cmake_definition+= -DEXAMPLE_NAME=$(EXAMPLE_NAME) +cmake_definition+= -DEXAMPLE_BASE_DIR=$(EXAMPLE_BASE_DIR) FINAL_NAME_PRE := $(EXAMPLE_BASE_DIR)/build/$(EXAMPLE_NAME)