diff --git a/boards/ikea-tradfri/board.c b/boards/ikea-tradfri/board.c index 810462715a..abd8faedd5 100644 --- a/boards/ikea-tradfri/board.c +++ b/boards/ikea-tradfri/board.c @@ -36,6 +36,8 @@ static const mtd_spi_nor_params_t _ikea_tradfri_nor_params = { .spi = IKEA_TRADFRI_NOR_SPI_DEV, .mode = IKEA_TRADFRI_NOR_SPI_MODE, .cs = IKEA_TRADFRI_NOR_SPI_CS, + .wp = GPIO_UNDEF, + .hold = GPIO_UNDEF, .addr_width = 3, }; diff --git a/boards/mulle/board.c b/boards/mulle/board.c index d402ee0b16..875971a8d6 100644 --- a/boards/mulle/board.c +++ b/boards/mulle/board.c @@ -55,9 +55,11 @@ static const mtd_spi_nor_params_t mulle_nor_params = { .wait_32k_erase = 20LU * US_PER_MS, .wait_chip_wake_up = 1LU * US_PER_MS, .spi = MULLE_NOR_SPI_DEV, - .cs = MULLE_NOR_SPI_CS, .addr_width = 3, .mode = SPI_MODE_3, + .cs = MULLE_NOR_SPI_CS, + .wp = GPIO_UNDEF, + .hold = GPIO_UNDEF, .clk = SPI_CLK_10MHZ, }; diff --git a/boards/nrf52840dk/mtd.c b/boards/nrf52840dk/mtd.c index fa84ec44a7..374fba9a43 100644 --- a/boards/nrf52840dk/mtd.c +++ b/boards/nrf52840dk/mtd.c @@ -38,6 +38,8 @@ static const mtd_spi_nor_params_t _nrf52840dk_nor_params = { .spi = NRF52840DK_NOR_SPI_DEV, .mode = NRF52840DK_NOR_SPI_MODE, .cs = NRF52840DK_NOR_SPI_CS, + .wp = GPIO_UNDEF, + .hold = GPIO_UNDEF, .addr_width = 3, }; diff --git a/boards/pinetime/board.c b/boards/pinetime/board.c index 0b01f85818..7985064ef0 100644 --- a/boards/pinetime/board.c +++ b/boards/pinetime/board.c @@ -41,6 +41,8 @@ static const mtd_spi_nor_params_t _pinetime_nor_params = { .spi = PINETIME_NOR_SPI_DEV, .mode = PINETIME_NOR_SPI_MODE, .cs = PINETIME_NOR_SPI_CS, + .wp = GPIO_UNDEF, + .hold = GPIO_UNDEF, .addr_width = 3, }; diff --git a/boards/serpente/board.c b/boards/serpente/board.c index 4bd0c1af3d..9f01b0f6fc 100644 --- a/boards/serpente/board.c +++ b/boards/serpente/board.c @@ -39,6 +39,8 @@ static const mtd_spi_nor_params_t _serpente_nor_params = { .spi = SERPENTE_NOR_SPI_DEV, .mode = SERPENTE_NOR_SPI_MODE, .cs = SERPENTE_NOR_SPI_CS, + .wp = GPIO_UNDEF, + .hold = GPIO_UNDEF, .addr_width = 3, }; diff --git a/boards/weact-f411ce/board.c b/boards/weact-f411ce/board.c index bff15f3154..99512c226b 100644 --- a/boards/weact-f411ce/board.c +++ b/boards/weact-f411ce/board.c @@ -38,6 +38,8 @@ static const mtd_spi_nor_params_t _weact_nor_params = { .spi = WEACT_411CE_NOR_SPI_DEV, .mode = WEACT_411CE_NOR_SPI_MODE, .cs = WEACT_411CE_NOR_SPI_CS, + .wp = GPIO_UNDEF, + .hold = GPIO_UNDEF, .addr_width = 3, }; diff --git a/drivers/include/mtd_spi_nor.h b/drivers/include/mtd_spi_nor.h index ad9103610e..ad61670255 100644 --- a/drivers/include/mtd_spi_nor.h +++ b/drivers/include/mtd_spi_nor.h @@ -111,6 +111,8 @@ typedef struct { spi_t spi; /**< SPI bus the device is connected to */ spi_mode_t mode; /**< SPI mode */ gpio_t cs; /**< CS pin GPIO handle */ + gpio_t wp; /**< Write Protect pin GPIO handle */ + gpio_t hold; /**< HOLD pin GPIO handle */ uint8_t addr_width; /**< Number of bytes in addresses, usually 3 for small devices */ } mtd_spi_nor_params_t; diff --git a/drivers/mtd_spi_nor/mtd_spi_nor.c b/drivers/mtd_spi_nor/mtd_spi_nor.c index f7ff1b72ef..85c5a49f5e 100644 --- a/drivers/mtd_spi_nor/mtd_spi_nor.c +++ b/drivers/mtd_spi_nor/mtd_spi_nor.c @@ -46,6 +46,9 @@ #define MTD_POWER_UP_WAIT_FOR_ID (0x0F) #endif +#define SFLASH_CMD_4_BYTE_ADDR (0xB7) /**< enable 32 bit addressing */ +#define SFLASH_CMD_3_BYTE_ADDR (0xE9) /**< enable 24 bit addressing */ + #define MTD_64K (65536ul) #define MTD_64K_ADDR_MASK (0xFFFF) #define MTD_32K (32768ul) @@ -356,6 +359,26 @@ static inline void wait_for_write_complete(const mtd_spi_nor_t *dev, uint32_t us DEBUG("\n"); } +static void _init_pins(mtd_spi_nor_t *dev) +{ + DEBUG("mtd_spi_nor_init: init pins\n"); + + /* CS */ + spi_init_cs(_get_spi(dev), dev->params->cs); + + /* Write Protect - not used by the driver */ + if (gpio_is_valid(dev->params->wp)) { + gpio_init(dev->params->wp, GPIO_OUT); + gpio_set(dev->params->wp); + } + + /* Hold - not used by the driver */ + if (gpio_is_valid(dev->params->hold)) { + gpio_init(dev->params->hold, GPIO_OUT); + gpio_set(dev->params->hold); + } +} + static int mtd_spi_nor_power(mtd_dev_t *mtd, enum mtd_power_state power) { mtd_spi_nor_t *dev = (mtd_spi_nor_t *)mtd; @@ -378,6 +401,11 @@ static int mtd_spi_nor_power(mtd_dev_t *mtd, enum mtd_power_state power) return -EIO; } #endif + /* enable 32 bit address mode */ + if (dev->params->addr_width == 4) { + mtd_spi_cmd(dev, SFLASH_CMD_4_BYTE_ADDR); + } + break; case MTD_POWER_DOWN: mtd_spi_cmd(dev, dev->params->opcode->sleep); @@ -396,13 +424,12 @@ static int mtd_spi_nor_init(mtd_dev_t *mtd) DEBUG("mtd_spi_nor_init: -> spi: %lx, cs: %lx, opcodes: %p\n", (unsigned long)_get_spi(dev), (unsigned long)dev->params->cs, (void *)dev->params->opcode); - if (dev->params->addr_width == 0) { - return -EINVAL; - } + /* verify configuration */ + assert(dev->params->addr_width > 0); + assert(dev->params->addr_width <= 4); - /* CS */ - DEBUG("mtd_spi_nor_init: CS init\n"); - spi_init_cs(_get_spi(dev), dev->params->cs); + /* CS, WP, Hold */ + _init_pins(dev); /* power up the MTD device*/ DEBUG("mtd_spi_nor_init: power up MTD device");