diff --git a/src/target/rp.c b/src/target/rp.c index 079559a..2b01b33 100644 --- a/src/target/rp.c +++ b/src/target/rp.c @@ -56,19 +56,19 @@ #define RP_SRAM_BASE 0x20000000U #define RP_SRAM_SIZE 0x42000U -#define RP_GPIO_QSPI_BASE_ADDR 0x40018000U -#define RP_GPIO_QSPI_SCLK_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x04U) -#define RP_GPIO_QSPI_CS_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x0cU) -#define RP_GPIO_QSPI_SD0_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x14U) -#define RP_GPIO_QSPI_SD1_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x1cU) -#define RP_GPIO_QSPI_SD2_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x24U) -#define RP_GPIO_QSPI_SD3_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x2cU) -#define RP_GPIO_QSPI_CS_DRIVE_NORMAL (0U << 8U) -#define RP_GPIO_QSPI_CS_DRIVE_INVERT (1U << 8U) -#define RP_GPIO_QSPI_CS_DRIVE_LOW (2U << 8U) -#define RP_GPIO_QSPI_CS_DRIVE_HIGH (3U << 8U) -#define RP_GPIO_QSPI_CS_DRIVE_MASK 0x00000300U -#define RP_GPIO_QSPI_SD1_CTRL_INOVER_BITS 0x00030000U +#define RP_GPIO_QSPI_BASE_ADDR 0x40018000U +#define RP_GPIO_QSPI_SCLK_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x04U) +#define RP_GPIO_QSPI_CS_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x0cU) +#define RP_GPIO_QSPI_SD0_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x14U) +#define RP_GPIO_QSPI_SD1_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x1cU) +#define RP_GPIO_QSPI_SD2_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x24U) +#define RP_GPIO_QSPI_SD3_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x2cU) +#define RP_GPIO_QSPI_CS_DRIVE_NORMAL (0U << 8U) +#define RP_GPIO_QSPI_CS_DRIVE_INVERT (1U << 8U) +#define RP_GPIO_QSPI_CS_DRIVE_LOW (2U << 8U) +#define RP_GPIO_QSPI_CS_DRIVE_HIGH (3U << 8U) +#define RP_GPIO_QSPI_CS_DRIVE_MASK 0x00000300U +#define RP_GPIO_QSPI_SD1_CTRL_INOVER_BITS 0x00030000U #define RP_SSI_BASE_ADDR 0x18000000U #define RP_SSI_CTRL0 (RP_SSI_BASE_ADDR + 0x00U) @@ -93,40 +93,40 @@ #define RP_SSI_CTRL0_TMOD_EEPROM (3U << 8U) #define RP_SSI_CTRL0_DATA_BIT_MASK 0x001f0000U #define RP_SSI_CTRL0_DATA_BIT_SHIFT 16U -#define RP_SSI_CTRL0_DATA_BITS(x) (((x) - 1U) << RP_SSI_CTRL0_DATA_BIT_SHIFT) +#define RP_SSI_CTRL0_DATA_BITS(x) (((x)-1U) << RP_SSI_CTRL0_DATA_BIT_SHIFT) #define RP_SSI_CTRL0_MASK (RP_SSI_CTRL0_FRF_MASK | RP_SSI_CTRL0_TMOD_MASK | RP_SSI_CTRL0_DATA_BIT_MASK) #define RP_SSI_ENABLE_SSI (1U << 0U) #define RP_SSI_XIP_SPI_CTRL0_FORMAT_STD_SPI (0U << 0U) #define RP_SSI_XIP_SPI_CTRL0_FORMAT_SPLIT (1U << 0U) #define RP_SSI_XIP_SPI_CTRL0_FORMAT_FRF (2U << 0U) -#define RP_SSI_XIP_SPI_CTRL0_ADDRESS_LENGTH(x) (((x) * 2U) << 2U) +#define RP_SSI_XIP_SPI_CTRL0_ADDRESS_LENGTH(x) (((x)*2U) << 2U) #define RP_SSI_XIP_SPI_CTRL0_INSTR_LENGTH_8b (2U << 8U) -#define RP_SSI_XIP_SPI_CTRL0_WAIT_CYCLES(x) (((x) * 8U) << 11U) +#define RP_SSI_XIP_SPI_CTRL0_WAIT_CYCLES(x) (((x)*8U) << 11U) #define RP_SSI_XIP_SPI_CTRL0_XIP_CMD_SHIFT 24U #define RP_SSI_XIP_SPI_CTRL0_XIP_CMD(x) ((x) << RP_SSI_XIP_SPI_CTRL0_XIP_CMD_SHIFT) #define RP_SSI_XIP_SPI_CTRL0_TRANS_1C1A (0U << 0U) #define RP_SSI_XIP_SPI_CTRL0_TRANS_1C2A (1U << 0U) #define RP_SSI_XIP_SPI_CTRL0_TRANS_2C2A (2U << 0U) -#define RP_PADS_QSPI_BASE_ADDR 0x40020000U -#define RP_PADS_QSPI_GPIO_SD0 (RP_PADS_QSPI_BASE_ADDR + 0x08U) -#define RP_PADS_QSPI_GPIO_SD1 (RP_PADS_QSPI_BASE_ADDR + 0x0cU) -#define RP_PADS_QSPI_GPIO_SD2 (RP_PADS_QSPI_BASE_ADDR + 0x10U) -#define RP_PADS_QSPI_GPIO_SD3 (RP_PADS_QSPI_BASE_ADDR + 0x14U) -#define RP_PADS_QSPI_GPIO_SD0_OD_BITS 0x00000080U -#define RP_PADS_QSPI_GPIO_SD0_PUE_BITS 0x00000008U -#define RP_PADS_QSPI_GPIO_SD0_PDE_BITS 0x00000004U +#define RP_PADS_QSPI_BASE_ADDR 0x40020000U +#define RP_PADS_QSPI_GPIO_SD0 (RP_PADS_QSPI_BASE_ADDR + 0x08U) +#define RP_PADS_QSPI_GPIO_SD1 (RP_PADS_QSPI_BASE_ADDR + 0x0cU) +#define RP_PADS_QSPI_GPIO_SD2 (RP_PADS_QSPI_BASE_ADDR + 0x10U) +#define RP_PADS_QSPI_GPIO_SD3 (RP_PADS_QSPI_BASE_ADDR + 0x14U) +#define RP_PADS_QSPI_GPIO_SD0_OD_BITS 0x00000080U +#define RP_PADS_QSPI_GPIO_SD0_PUE_BITS 0x00000008U +#define RP_PADS_QSPI_GPIO_SD0_PDE_BITS 0x00000004U -#define RP_XIP_BASE_ADDR 0x14000000U -#define RP_XIP_CTRL (RP_XIP_BASE_ADDR + 0x00U) -#define RP_XIP_FLUSH (RP_XIP_BASE_ADDR + 0x04U) -#define RP_XIP_CTRL_ENABLE 0x00000001U +#define RP_XIP_BASE_ADDR 0x14000000U +#define RP_XIP_CTRL (RP_XIP_BASE_ADDR + 0x00U) +#define RP_XIP_FLUSH (RP_XIP_BASE_ADDR + 0x04U) +#define RP_XIP_CTRL_ENABLE 0x00000001U -#define RP_RESETS_BASE_ADDR 0x4000c000U -#define RP_RESETS_RESET (RP_RESETS_BASE_ADDR + 0x00U) -#define RP_RESETS_RESET_DONE (RP_RESETS_BASE_ADDR + 0x08U) -#define RP_RESETS_RESET_IO_QSPI_BITS 0x00000040U -#define RP_RESETS_RESET_PADS_QSPI_BITS 0x00000200U +#define RP_RESETS_BASE_ADDR 0x4000c000U +#define RP_RESETS_RESET (RP_RESETS_BASE_ADDR + 0x00U) +#define RP_RESETS_RESET_DONE (RP_RESETS_BASE_ADDR + 0x08U) +#define RP_RESETS_RESET_IO_QSPI_BITS 0x00000040U +#define RP_RESETS_RESET_PADS_QSPI_BITS 0x00000200U #define BOOTROM_FUNC_TABLE_ADDR 0x00000014U #define BOOTROM_FUNC_TABLE_TAG(x, y) ((uint8_t)(x) | ((uint8_t)(y) << 8U)) @@ -142,7 +142,7 @@ #define RP_SPI_OPCODE(x) (x) #define RP_SPI_OPCODE_MASK 0x00ffU #define RP_SPI_INTER_SHIFT 8U -#define RP_SPI_INTER_LENGTH(x) (((x) & 7U) << RP_SPI_INTER_SHIFT) +#define RP_SPI_INTER_LENGTH(x) (((x)&7U) << RP_SPI_INTER_SHIFT) #define RP_SPI_INTER_MASK 0x0700U #define RP_SPI_FRAME_OPCODE_ONLY (1 << 11U) #define RP_SPI_FRAME_OPCODE_3B_ADDR (2 << 11U) @@ -157,9 +157,9 @@ */ #define SPI_FLASH_CMD_SECTOR_ERASE 0x20 -#define FLASHCMD_BLOCK32K_ERASE 0x52 -#define FLASHCMD_BLOCK64K_ERASE 0xd8 -#define FLASHCMD_CHIP_ERASE 0x60 +#define FLASHCMD_BLOCK32K_ERASE 0x52 +#define FLASHCMD_BLOCK64K_ERASE 0xd8 +#define FLASHCMD_CHIP_ERASE 0x60 #define SPI_FLASH_CMD_READ_JEDEC_ID (RP_SPI_OPCODE(0x9fU) | RP_SPI_INTER_LENGTH(0) | RP_SPI_FRAME_OPCODE_ONLY) #define SPI_FLASH_CMD_READ_SFDP (RP_SPI_OPCODE(0x5aU) | RP_SPI_INTER_LENGTH(1) | RP_SPI_FRAME_OPCODE_3B_ADDR) @@ -205,9 +205,9 @@ static uint32_t rp_get_flash_length(target *t); static bool rp_mass_erase(target *t); // Our own implementation of bootloader functions for handling flash chip -static void __attribute__((unused))rp_flash_connect_internal(target *t); +static void __attribute__((unused)) rp_flash_connect_internal(target *t); static void rp_flash_exit_xip(target *t); -static void __attribute__((unused))rp_flash_flush_cache(target *t); +static void __attribute__((unused)) rp_flash_flush_cache(target *t); static void rp_flash_enter_xip(target *t); static void rp_spi_read_sfdp(target *const t, const uint32_t address, void *const buffer, const size_t length) @@ -622,14 +622,15 @@ static void rp_spi_read( // Connect the XIP controller to the flash pads static void rp_flash_connect_internal(target *t) { - // Use hard reset to force IO and pad controls to known state (don't touch - // IO_BANK0 as that does not affect XIP signals) + // Use hard reset to force IO and pad controls to known state (don't touch + // IO_BANK0 as that does not affect XIP signals) uint32_t reset = target_mem_read32(t, RP_RESETS_RESET); - target_mem_write32(t, RP_RESETS_RESET, reset | RP_RESETS_RESET_IO_QSPI_BITS | RP_RESETS_RESET_PADS_QSPI_BITS); - target_mem_write32(t, RP_RESETS_RESET, reset); - while (~target_mem_read32(t, RP_RESETS_RESET_DONE) & (RP_RESETS_RESET_IO_QSPI_BITS | RP_RESETS_RESET_PADS_QSPI_BITS)); + target_mem_write32(t, RP_RESETS_RESET, reset | RP_RESETS_RESET_IO_QSPI_BITS | RP_RESETS_RESET_PADS_QSPI_BITS); + target_mem_write32(t, RP_RESETS_RESET, reset); + while ( + ~target_mem_read32(t, RP_RESETS_RESET_DONE) & (RP_RESETS_RESET_IO_QSPI_BITS | RP_RESETS_RESET_PADS_QSPI_BITS)); - // Then mux XIP block onto internal QSPI flash pads + // Then mux XIP block onto internal QSPI flash pads target_mem_write32(t, RP_GPIO_QSPI_SCLK_CTRL, 0); target_mem_write32(t, RP_GPIO_QSPI_CS_CTRL, 0); target_mem_write32(t, RP_GPIO_QSPI_SD0_CTRL, 0); @@ -652,9 +653,9 @@ static void rp_flash_init_spi(target *t) // Hopefully-conservative baud rate for boot and programming target_mem_write32(t, RP_SSI_BAUD, 6); target_mem_write32(t, RP_SSI_CTRL0, - RP_SSI_CTRL0_FRF_SERIAL | // Standard 1-bit SPI serial frames - RP_SSI_CTRL0_DATA_BITS(8) | // 8 clocks per data frame - RP_SSI_CTRL0_TMOD_BIDI // TX and RX FIFOs are both used for every byte + RP_SSI_CTRL0_FRF_SERIAL | // Standard 1-bit SPI serial frames + RP_SSI_CTRL0_DATA_BITS(8) | // 8 clocks per data frame + RP_SSI_CTRL0_TMOD_BIDI // TX and RX FIFOs are both used for every byte ); // Slave selected when transfers in progress target_mem_write32(t, RP_SSI_SER, 1); @@ -664,8 +665,9 @@ static void rp_flash_init_spi(target *t) // Also allow any unbounded loops to check whether the above abort condition // was asserted, and terminate early -static int rp_flash_was_aborted(target *t) { - return target_mem_read32(t, RP_GPIO_QSPI_SD1_CTRL) & RP_GPIO_QSPI_SD1_CTRL_INOVER_BITS; +static int rp_flash_was_aborted(target *t) +{ + return target_mem_read32(t, RP_GPIO_QSPI_SD1_CTRL) & RP_GPIO_QSPI_SD1_CTRL_INOVER_BITS; } // Put bytes from one buffer, and get bytes into another buffer. @@ -676,39 +678,40 @@ static int rp_flash_was_aborted(target *t) { // If rx_skip is nonzero, this many bytes will first be consumed from the FIFO, // before reading a further count bytes into *rx. // E.g. if you have written a command+address just before calling this function. -static void rp_flash_put_get(target *t, const uint8_t *tx, uint8_t *rx, size_t count, size_t rx_skip) { - // Make sure there is never more data in flight than the depth of the RX - // FIFO. Otherwise, when we are interrupted for long periods, hardware - // will overflow the RX FIFO. - const uint max_in_flight = 16 - 2; // account for data internal to SSI - size_t tx_count = count; - size_t rx_count = count; - while (tx_count || rx_skip || rx_count) { - // NB order of reads, for pessimism rather than optimism - uint32_t tx_level = target_mem_read32(t, RP_SSI_TXFLR); - uint32_t rx_level = target_mem_read32(t, RP_SSI_RXFLR); - bool did_something = false; // Expect this to be folded into control flow, not register - if (tx_count && tx_level + rx_level < max_in_flight) { - target_mem_write32(t, RP_SSI_DR0, (uint32_t) (tx ? *tx++ : 0)); - --tx_count; - did_something = true; - } - if (rx_level) { - uint8_t rxbyte = target_mem_read32(t, RP_SSI_DR0); - did_something = true; - if (rx_skip) { - --rx_skip; - } else { - if (rx) - *rx++ = rxbyte; - --rx_count; - } - } - // APB load costs 4 cycles, so only do it on idle loops (our budget is 48 cyc/byte) - if (!did_something && rp_flash_was_aborted(t)) - break; - } - rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_HIGH); +static void rp_flash_put_get(target *t, const uint8_t *tx, uint8_t *rx, size_t count, size_t rx_skip) +{ + // Make sure there is never more data in flight than the depth of the RX + // FIFO. Otherwise, when we are interrupted for long periods, hardware + // will overflow the RX FIFO. + const uint max_in_flight = 16 - 2; // account for data internal to SSI + size_t tx_count = count; + size_t rx_count = count; + while (tx_count || rx_skip || rx_count) { + // NB order of reads, for pessimism rather than optimism + uint32_t tx_level = target_mem_read32(t, RP_SSI_TXFLR); + uint32_t rx_level = target_mem_read32(t, RP_SSI_RXFLR); + bool did_something = false; // Expect this to be folded into control flow, not register + if (tx_count && tx_level + rx_level < max_in_flight) { + target_mem_write32(t, RP_SSI_DR0, (uint32_t)(tx ? *tx++ : 0)); + --tx_count; + did_something = true; + } + if (rx_level) { + uint8_t rxbyte = target_mem_read32(t, RP_SSI_DR0); + did_something = true; + if (rx_skip) { + --rx_skip; + } else { + if (rx) + *rx++ = rxbyte; + --rx_count; + } + } + // APB load costs 4 cycles, so only do it on idle loops (our budget is 48 cyc/byte) + if (!did_something && rp_flash_was_aborted(t)) + break; + } + rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_HIGH); } // Sequence: @@ -721,55 +724,50 @@ static void rp_flash_put_get(target *t, const uint8_t *tx, uint8_t *rx, size_t c // Parts 1 and 2 are to improve compatibility with Micron parts static void rp_flash_exit_xip(target *t) { - uint8_t buf[2]; - buf[0] = 0xff; - buf[1] = 0xff; + uint8_t buf[2]; + buf[0] = 0xff; + buf[1] = 0xff; rp_flash_init_spi(t); uint32_t padctrl_save = target_mem_read32(t, RP_PADS_QSPI_GPIO_SD0); - uint32_t padctrl_tmp = (padctrl_save - & ~(RP_PADS_QSPI_GPIO_SD0_OD_BITS | RP_PADS_QSPI_GPIO_SD0_PUE_BITS | - RP_PADS_QSPI_GPIO_SD0_PDE_BITS) - ) | RP_PADS_QSPI_GPIO_SD0_OD_BITS | RP_PADS_QSPI_GPIO_SD0_PDE_BITS; + uint32_t padctrl_tmp = (padctrl_save & ~(RP_PADS_QSPI_GPIO_SD0_OD_BITS | RP_PADS_QSPI_GPIO_SD0_PUE_BITS | + RP_PADS_QSPI_GPIO_SD0_PDE_BITS)) | + RP_PADS_QSPI_GPIO_SD0_OD_BITS | RP_PADS_QSPI_GPIO_SD0_PDE_BITS; - // First two 32-clock sequences - // CSn is held high for the first 32 clocks, then asserted low for next 32 - rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_HIGH); - for (int i = 0; i < 2; ++i) { - // This gives 4 16-bit offset store instructions. Anything else seems to - // produce a large island of constants - target_mem_write32(t, RP_PADS_QSPI_GPIO_SD0, padctrl_tmp); - target_mem_write32(t, RP_PADS_QSPI_GPIO_SD1, padctrl_tmp); - target_mem_write32(t, RP_PADS_QSPI_GPIO_SD2, padctrl_tmp); - target_mem_write32(t, RP_PADS_QSPI_GPIO_SD3, padctrl_tmp); + // First two 32-clock sequences + // CSn is held high for the first 32 clocks, then asserted low for next 32 + rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_HIGH); + for (int i = 0; i < 2; ++i) { + // This gives 4 16-bit offset store instructions. Anything else seems to + // produce a large island of constants + target_mem_write32(t, RP_PADS_QSPI_GPIO_SD0, padctrl_tmp); + target_mem_write32(t, RP_PADS_QSPI_GPIO_SD1, padctrl_tmp); + target_mem_write32(t, RP_PADS_QSPI_GPIO_SD2, padctrl_tmp); + target_mem_write32(t, RP_PADS_QSPI_GPIO_SD3, padctrl_tmp); - // Brief delay (~6000 cyc) for pulls to take effect + // Brief delay (~6000 cyc) for pulls to take effect platform_delay(10); - rp_flash_put_get(t, NULL, NULL, 4, 0); + rp_flash_put_get(t, NULL, NULL, 4, 0); - padctrl_tmp = (padctrl_tmp - & ~RP_PADS_QSPI_GPIO_SD0_PDE_BITS) - | RP_PADS_QSPI_GPIO_SD0_PUE_BITS; + padctrl_tmp = (padctrl_tmp & ~RP_PADS_QSPI_GPIO_SD0_PDE_BITS) | RP_PADS_QSPI_GPIO_SD0_PUE_BITS; - rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_LOW); - } + rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_LOW); + } - // Restore IO/pad controls, and send 0xff, 0xff. Put pullup on IO2/IO3 as - // these may be used as WPn/HOLDn at this point, and we are now starting - // to issue serial commands. + // Restore IO/pad controls, and send 0xff, 0xff. Put pullup on IO2/IO3 as + // these may be used as WPn/HOLDn at this point, and we are now starting + // to issue serial commands. - target_mem_write32(t, RP_PADS_QSPI_GPIO_SD0, padctrl_save); - target_mem_write32(t, RP_PADS_QSPI_GPIO_SD1, padctrl_save); - padctrl_save = (padctrl_save - & ~RP_PADS_QSPI_GPIO_SD0_PDE_BITS - ) | RP_PADS_QSPI_GPIO_SD0_PUE_BITS; - target_mem_write32(t, RP_PADS_QSPI_GPIO_SD2, padctrl_save); - target_mem_write32(t, RP_PADS_QSPI_GPIO_SD3, padctrl_save); + target_mem_write32(t, RP_PADS_QSPI_GPIO_SD0, padctrl_save); + target_mem_write32(t, RP_PADS_QSPI_GPIO_SD1, padctrl_save); + padctrl_save = (padctrl_save & ~RP_PADS_QSPI_GPIO_SD0_PDE_BITS) | RP_PADS_QSPI_GPIO_SD0_PUE_BITS; + target_mem_write32(t, RP_PADS_QSPI_GPIO_SD2, padctrl_save); + target_mem_write32(t, RP_PADS_QSPI_GPIO_SD3, padctrl_save); - rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_LOW); - rp_flash_put_get(t, buf, NULL, 2, 0); + rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_LOW); + rp_flash_put_get(t, buf, NULL, 2, 0); target_mem_write32(t, RP_GPIO_QSPI_CS_CTRL, 0); } @@ -780,13 +778,13 @@ static void rp_flash_exit_xip(target *t) // programming. static void rp_flash_flush_cache(target *t) { - target_mem_write32(t, RP_XIP_FLUSH, 1); - // Read blocks until flush completion - target_mem_read32(t, RP_XIP_FLUSH); - // Enable the cache + target_mem_write32(t, RP_XIP_FLUSH, 1); + // Read blocks until flush completion + target_mem_read32(t, RP_XIP_FLUSH); + // Enable the cache const uint32_t ctrl = target_mem_read32(t, RP_XIP_CTRL); target_mem_write32(t, RP_XIP_CTRL, ctrl | RP_XIP_CTRL_ENABLE); - rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_NORMAL); + rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_NORMAL); } // Put the SSI into a mode where XIP accesses translate to standard @@ -796,15 +794,15 @@ static void rp_flash_enter_xip(target *t) { target_mem_write32(t, RP_SSI_ENABLE, 0); target_mem_write32(t, RP_SSI_CTRL0, - RP_SSI_CTRL0_FRF_SERIAL | // Standard 1-bit SPI serial frames - RP_SSI_CTRL0_DATA_BITS(32) | // 32 clocks per data frame - RP_SSI_CTRL0_TMOD_EEPROM // Send instr + addr, receive data + RP_SSI_CTRL0_FRF_SERIAL | // Standard 1-bit SPI serial frames + RP_SSI_CTRL0_DATA_BITS(32) | // 32 clocks per data frame + RP_SSI_CTRL0_TMOD_EEPROM // Send instr + addr, receive data ); target_mem_write32(t, RP_SSI_XIP_SPI_CTRL0, - RP_SSI_XIP_SPI_CTRL0_XIP_CMD(0x03) | // Standard 03h read - RP_SSI_XIP_SPI_CTRL0_INSTR_LENGTH_8b | // 8-bit instruction prefix - RP_SSI_XIP_SPI_CTRL0_ADDRESS_LENGTH(0x03) | // 24-bit addressing for 03h commands - RP_SSI_XIP_SPI_CTRL0_TRANS_1C1A // Command and address both in serial format + RP_SSI_XIP_SPI_CTRL0_XIP_CMD(0x03) | // Standard 03h read + RP_SSI_XIP_SPI_CTRL0_INSTR_LENGTH_8b | // 8-bit instruction prefix + RP_SSI_XIP_SPI_CTRL0_ADDRESS_LENGTH(0x03) | // 24-bit addressing for 03h commands + RP_SSI_XIP_SPI_CTRL0_TRANS_1C1A // Command and address both in serial format ); target_mem_write32(t, RP_SSI_ENABLE, RP_SSI_ENABLE_SSI); } @@ -818,7 +816,7 @@ static uint32_t rp_get_flash_length(target *t) DEBUG_INFO("Flash device ID: %02x %02x %02x\n", flash_id.manufacturer, flash_id.type, flash_id.capacity); if (flash_id.capacity >= 8 && flash_id.capacity <= 34) return 1 << flash_id.capacity; - + // Guess maximum flash size return MAX_FLASH; }