diff --git a/example/boot2/boot2.ld b/example/boot2/boot2.ld index 60f96ad..a4f3b3f 100644 --- a/example/boot2/boot2.ld +++ b/example/boot2/boot2.ld @@ -37,9 +37,9 @@ SECTIONS { . = ALIGN(4); _boot2_copy_self_start_addr = .; - *(.text*) - *(.rodata*) - *(.data*) + *(*.text*) + *(*.rodata*) + *(*.data*) . = ALIGN(4); } >RAM AT > FLASH :text diff --git a/example/boot2/main.c b/example/boot2/main.c index 90e08d2..30a42d0 100644 --- a/example/boot2/main.c +++ b/example/boot2/main.c @@ -245,11 +245,18 @@ int main(void) } } if (boot_pin_high > boot_pin_low) { + printf("enter boot mode\r\n"); while (1) { uart_state_machine(UART_ID_0); } } else { - jump_to_address(0x00100000); + printf("enter flash mode\r\n"); + flash_enter_quad_xip(6); + printf("xip success\r\n"); + for (uint32_t i = 0; i < 32; i += 4) { + printf("0x%08lX: 0x%08lX\r\n", 0x10000200 + i, *(volatile uint32_t *)(0x10000200 + i)); + } + jump_to_address(0x10100000); } return 0; diff --git a/example/boot2/src/flash.c b/example/boot2/src/flash.c index 8b00696..8d01856 100644 --- a/example/boot2/src/flash.c +++ b/example/boot2/src/flash.c @@ -99,3 +99,57 @@ 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); } + +void flash_enter_quad_xip(uint16_t div) +{ + uint8_t buffer[8]; + + pads_qspi_hw->io_qspi_sclk = (GPIO_PADS_DRIVE_STRENGTH_8MA << GPIO_PADS_DRIVE_POS) | (GPIO_PADS_SLEW_RATE_FAST << GPIO_PADS_SLEW_RATE_POS); + pads_qspi_hw_clear->io_qspi_sd0 = 1 << GPIO_PADS_SCHMITT_POS; + pads_qspi_hw_clear->io_qspi_sd1 = 1 << GPIO_PADS_SCHMITT_POS; + pads_qspi_hw_clear->io_qspi_sd2 = 1 << GPIO_PADS_SCHMITT_POS; + pads_qspi_hw_clear->io_qspi_sd3 = 1 << GPIO_PADS_SCHMITT_POS; + + ssi_hw->ssienr = 0; + /* div must be even */ + if (div & 1) { + div = div + 1; + } + ssi_hw->baudr = div; + ssi_hw->rx_sample_dly = 1; + /* 8bits per data frame */ + ssi_hw->ctrlr0 = (7 << SSI_CTRLR0_DFS_32_POS) | SSI_CTRLR0_TMOD_VALUE_TX_AND_RX_MASK; + ssi_hw->ssienr = 1; + flash_do_cmd(FLASHCMD_READ_STATUS2, (uint8_t *)0, buffer, 1); + if ((buffer[0] & SREG_DATA) == 0) { + flash_enable_write(); + buffer[0] = 0; + buffer[1] = SREG_DATA; + flash_do_cmd(FLASHCMD_WRITE_STATUS, buffer, (uint8_t *)0, 2); + flash_wait_ready(); + } + ssi_hw->ssienr = 0; + /* 32bits per data frame, quad and xip */ + ssi_hw->ctrlr0 = (31 << SSI_CTRLR0_DFS_32_POS) | \ + SSI_CTRLR0_SPI_FRF_VALUE_QUAD_MASK | \ + SSI_CTRLR0_TMOD_VALUE_EEPROM_READ_MASK; + /* NDF=0, single 32b read */ + ssi_hw->ctrlr1 = 0; + ssi_hw->spi_ctrlr0 = (8 << SSI_SPI_CTRLR0_ADDR_L_POS) | \ + (4 << SSI_SPI_CTRLR0_WAIT_CYCLES_POS) | \ + SSI_SPI_CTRLR0_INST_L_VALUE_8B_MASK | \ + SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_1C2A_MASK; + ioqspi_hw->io[1].ctrl = 0; + ssi_hw->ssienr = 1; + ssi_hw->dr0 = 0xEB; + ssi_hw->dr0 = MODE_CONTINUOUS_READ; + flash_wait_ready(); + ssi_hw->ssienr = 0; + ssi_hw->spi_ctrlr0 = (MODE_CONTINUOUS_READ << SSI_SPI_CTRLR0_XIP_CMD_POS) | \ + (8 << SSI_SPI_CTRLR0_ADDR_L_POS) | \ + (4 << SSI_SPI_CTRLR0_WAIT_CYCLES_POS) | \ + SSI_SPI_CTRLR0_INST_L_VALUE_NONE_MASK | \ + SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_2C2A_MASK; + ioqspi_hw->io[1].ctrl = 0; + ssi_hw->ssienr = 1; +} diff --git a/example/boot2/src/flash.h b/example/boot2/src/flash.h index 8f6a483..5f78c7d 100644 --- a/example/boot2/src/flash.h +++ b/example/boot2/src/flash.h @@ -5,12 +5,17 @@ #define FLASHCMD_PAGE_PROGRAM (0x02) #define FLASHCMD_READ_DATA (0x03) +#define FLASHCMD_WRITE_STATUS (0x01) #define FLASHCMD_READ_STATUS (0x05) +#define FLASHCMD_READ_STATUS2 (0x35) #define FLASHCMD_WRITE_ENABLE (0x06) #define FLASHCMD_SECTOR_ERASE (0x20) #define FLASHCMD_READ_SFDP (0x5A) #define FLASHCMD_READ_JEDEC_ID (0x9F) +#define SREG_DATA (0x02) // Enable quad-SPI mode +#define MODE_CONTINUOUS_READ (0xA0) + #define FLASH_WRITE_SIZE (256) #define FLASH_READ_SIZE (256) #define FLASH_ERASE_SIZE (4096) @@ -22,6 +27,7 @@ extern "C" { void flash_erase(uint32_t addr); void flash_write(uint32_t addr, uint8_t *data, uint32_t length); void flash_read(uint32_t addr, uint8_t *data, uint32_t length); +void flash_enter_quad_xip(uint16_t div); #ifdef __cplusplus }