From e2bf669d6c6aa56309ceb158cf2f119c19accd9e Mon Sep 17 00:00:00 2001 From: Christian Klarhorst Date: Sat, 26 Oct 2024 17:10:34 +0200 Subject: [PATCH] bios: add flash_transfer_cmd Allows to send arbitrary SPI CMDs to the FLASH. Examples (depending on flash chip): - flash_transfer_cmd 0x9F 0x00 0x00 0x00 -> Read ID reg - flash_transfer_cmd 0x06 0x01 0x00 -> Global write protect off --- litex/soc/software/bios/cmds/cmd_spiflash.c | 31 +++++++++++++++++++++ litex/soc/software/liblitespi/spiflash.c | 2 +- litex/soc/software/liblitespi/spiflash.h | 1 + 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/litex/soc/software/bios/cmds/cmd_spiflash.c b/litex/soc/software/bios/cmds/cmd_spiflash.c index 7b1dacc62..e62c09c83 100644 --- a/litex/soc/software/bios/cmds/cmd_spiflash.c +++ b/litex/soc/software/bios/cmds/cmd_spiflash.c @@ -141,4 +141,35 @@ static void flash_erase_range_handler(int nb_params, char **params) } define_command(flash_erase_range, flash_erase_range_handler, "Erase flash range", SPIFLASH_CMDS); + +static void flash_transfer_cmd(int nb_params, char **params) +{ + int i; + char *c; + uint8_t w_buf[MAX_PARAM]; + uint8_t r_buf[MAX_PARAM]; + + if (nb_params == 0) { + printf("flash_transfer_cmd , ..."); + return; + } + + for (i = 0; i < nb_params; ++i) { + w_buf[i] = strtoul(params[i], &c, 0); + if (*c != 0) { + printf("Incorrect value of parameter %d", i); + return; + } + } + + transfer_cmd(w_buf, r_buf, nb_params); + + printf("Result:"); + for (i = 0; i < nb_params; ++i) { + printf("%02x ", r_buf[i]); + } + printf("\n"); +} + +define_command(flash_transfer_cmd, flash_transfer_cmd, "Transfer CMD to/from flash", SPIFLASH_CMDS); #endif diff --git a/litex/soc/software/liblitespi/spiflash.c b/litex/soc/software/liblitespi/spiflash.c index a8f8bf866..a8e9d9805 100644 --- a/litex/soc/software/liblitespi/spiflash.c +++ b/litex/soc/software/liblitespi/spiflash.c @@ -131,7 +131,7 @@ static uint32_t transfer_byte(uint8_t b) return spiflash_core_master_rxtx_read(); } -static void transfer_cmd(volatile uint8_t *bs, volatile uint8_t *resp, int len) +void transfer_cmd(volatile uint8_t *bs, volatile uint8_t *resp, int len) { spiflash_len_mask_width_write(8, 1, 1); spiflash_core_master_cs_write(1); diff --git a/litex/soc/software/liblitespi/spiflash.h b/litex/soc/software/liblitespi/spiflash.h index 2ac19525d..5cfa415e2 100644 --- a/litex/soc/software/liblitespi/spiflash.h +++ b/litex/soc/software/liblitespi/spiflash.h @@ -14,6 +14,7 @@ void spiflash_memspeed(void); void spiflash_init(void); int spiflash_write_stream(uint32_t addr, uint8_t *stream, uint32_t len); void spiflash_erase_range(uint32_t addr, uint32_t len); +void transfer_cmd(volatile uint8_t *bs, volatile uint8_t *resp, int len); #ifdef __cplusplus }