diff --git a/configs/b-l475e-iot01a/Kconfig b/configs/b-l475e-iot01a/Kconfig index 60da88320a..92d5d0da6d 100644 --- a/configs/b-l475e-iot01a/Kconfig +++ b/configs/b-l475e-iot01a/Kconfig @@ -3,8 +3,43 @@ # see the file kconfig-language.txt in the NuttX tools repository. # -# if ARCH_BOARD_B_L475E_IOT01A +if ARCH_BOARD_B_L475E_IOT01A -# TODO +config B_L475E_IOT01A_MTD_FLASH + bool "MTD driver for external 64Mbytes flash memory" + default n + select STM32L4_DMA1 + select STM32L4_QSPI + select MTD + select MTD_MX25RXX + select MTD_SMART + select MTD_SMART_MINIMIZE_RAM + select FS_SMARTFS + ---help--- + Configures an MTD device for use with the onboard external flash + using QuadSPI interface. -# endif \ No newline at end of file +if B_L475E_IOT01A_MTD_FLASH + +config B_L475E_IOT01A_MTD_FLASH_MINOR + int "Minor number for the flash memory /dev/smart entry" + default 0 + ---help--- + Sets the minor number for the flash memory /dev/smart entry + +config B_L475E_IOT01A_MTD_PART + bool "Enable partition support" + default n + select MTD_PARTITION + ---help--- + Enables creation of partitions on the external flash memory. + +config B_L475E_IOT01A_MTD_PART_LIST + string "Flash partition size list" + default "512,8192,8192,16384" + depends on B_L475E_IOT01A_MTD_PART + ---help--- + Comma separated list of partition sizes in KB. + +endif # B_L475E_IOT01A_MTD_FLASH +endif # ARCH_BOARD_B_L475E_IOT01A diff --git a/configs/b-l475e-iot01a/include/b-l475e-iot01a_clock.h b/configs/b-l475e-iot01a/include/b-l475e-iot01a_clock.h index 16e8300d43..b8e6028952 100644 --- a/configs/b-l475e-iot01a/include/b-l475e-iot01a_clock.h +++ b/configs/b-l475e-iot01a/include/b-l475e-iot01a_clock.h @@ -96,6 +96,8 @@ #define STM32L4_LSI_FREQUENCY 32000 #define STM32L4_LSE_FREQUENCY 32768 +#define BOARD_AHB_FREQUENCY 80000000ul + #define STM32L4_BOARD_USEHSI 1 /* XXX sysclk mux = pllclk */ diff --git a/configs/b-l475e-iot01a/include/board.h b/configs/b-l475e-iot01a/include/board.h index 44bd7c914a..e4d408990f 100644 --- a/configs/b-l475e-iot01a/include/board.h +++ b/configs/b-l475e-iot01a/include/board.h @@ -164,6 +164,16 @@ #define GPIO_SPI3_MISO GPIO_SPI3_MISO_2 #define GPIO_SPI3_MOSI GPIO_SPI3_MOSI_2 +/* Quad SPI: connected to MX25R6435F external flash memory */ + +#define GPIO_QSPI_CS (GPIO_QSPI_NCS_2 | GPIO_FLOAT | GPIO_PUSHPULL | GPIO_SPEED_100MHz) +#define GPIO_QSPI_IO0 (GPIO_QSPI_BK1_IO0_2 | GPIO_FLOAT | GPIO_PUSHPULL | GPIO_SPEED_100MHz) +#define GPIO_QSPI_IO1 (GPIO_QSPI_BK1_IO1_2 | GPIO_FLOAT | GPIO_PUSHPULL | GPIO_SPEED_100MHz) +#define GPIO_QSPI_IO2 (GPIO_QSPI_BK1_IO2_2 | GPIO_FLOAT | GPIO_PUSHPULL | GPIO_SPEED_100MHz) +#define GPIO_QSPI_IO3 (GPIO_QSPI_BK1_IO3_2 | GPIO_FLOAT | GPIO_PUSHPULL | GPIO_SPEED_100MHz) +#define GPIO_QSPI_SCK (GPIO_QSPI_CLK_2 | GPIO_FLOAT | GPIO_PUSHPULL | GPIO_SPEED_100MHz) + + /************************************************************************************ * Public Data ************************************************************************************/ diff --git a/configs/b-l475e-iot01a/src/b-l475e-iot01a.h b/configs/b-l475e-iot01a/src/b-l475e-iot01a.h index e3ae007fab..f6e2beda0d 100644 --- a/configs/b-l475e-iot01a/src/b-l475e-iot01a.h +++ b/configs/b-l475e-iot01a/src/b-l475e-iot01a.h @@ -51,6 +51,8 @@ /* Configuration ************************************************************/ #define HAVE_SPSGRF 1 +#define HAVE_MX25R6435F 1 +#define HAVE_MX25R6435F_SMARTFS 1 /* SPSGRF support depends on: * @@ -81,6 +83,15 @@ # undef HAVE_SPSGRF #endif +#if !defined(CONFIG_MTD_MX25RXX) || !defined(CONFIG_STM32L4_QSPI) +# undef HAVE_MX25R6435F +#endif + +#if !defined(HAVE_MX25R6435F) || !defined(CONFIG_MTD_SMART) || \ + !defined(CONFIG_FS_SMARTFS) +# undef HAVE_MX25R6435F_SMARTFS +#endif + /* GPIO Definitions *********************************************************/ /* LEDs */ diff --git a/configs/b-l475e-iot01a/src/stm32_bringup.c b/configs/b-l475e-iot01a/src/stm32_bringup.c index f293042ba2..0760001198 100644 --- a/configs/b-l475e-iot01a/src/stm32_bringup.c +++ b/configs/b-l475e-iot01a/src/stm32_bringup.c @@ -39,16 +39,22 @@ #include +#include +#include #include #include #include +#include #include #include -#include +#include +#include +#include #include +#include "stm32l4_qspi.h" #include "b-l475e-iot01a.h" /**************************************************************************** @@ -97,6 +103,127 @@ int stm32l4_bringup(void) #endif /* CONFIG_USERLED_LOWER */ #endif /* CONFIG_USERLED && !CONFIG_ARCH_LEDS */ +#ifdef HAVE_MX25R6435F + { + /* Create an instance of the STM32L4 QSPI device driver */ + + FAR struct qspi_dev_s *g_qspi; + FAR struct mtd_dev_s *g_mtd_fs; + + g_qspi = stm32l4_qspi_initialize(0); + if (g_qspi == NULL) + { + syslog(LOG_ERR, "ERROR: stm32l4_qspi_initialize failed\n"); + return -EIO; + } + + /* Use the QSPI device instance to initialize the + * MX25R6435F flash device. + */ + + g_mtd_fs = mx25rxx_initialize(g_qspi, true); + if (!g_mtd_fs) + { + syslog(LOG_ERR, "ERROR: mx25rxx_initialize failed\n"); + return -EIO; + } + +#ifdef CONFIG_B_L475E_IOT01A_MTD_PART + { + /* Create partitions on external flash memory */ + + int partno; + int partsize; + int partoffset; + int partszbytes; + int erasesize; + FAR struct mtd_geometry_s geo; + const char *ptr = CONFIG_B_L475E_IOT01A_MTD_PART_LIST; + FAR struct mtd_dev_s *mtd_part; + char partref[4]; + + /* Now create a partition on the FLASH device */ + + partno = 0; + partoffset = 0; + + /* Query MTD geometry */ + + ret = MTD_IOCTL(g_mtd_fs, MTDIOC_GEOMETRY, + (unsigned long)(uintptr_t)&geo); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: MTDIOC_GEOMETRY failed\n"); + return ret; + } + + /* Get the Flash erase size */ + + erasesize = geo.erasesize; + + while (*ptr != '\0') + { + /* Get the partition size */ + + partsize = atoi(ptr); + if (partsize <= 0) + { + syslog(LOG_ERR, "Error while processing <%s>\n", ptr); + goto process_next_part; + } + + partszbytes = (partsize << 10); /* partsize is defined in KB */ + + if ((partszbytes < erasesize) || ((partszbytes % erasesize) != 0)) + { + syslog(LOG_ERR, "Invalid partition size: %d bytes\n", + partszbytes); + partszbytes = (partszbytes+erasesize) & -erasesize; + } + + mtd_part = mtd_partition(g_mtd_fs, partoffset, + partszbytes / erasesize); + partoffset += partszbytes / erasesize; + +#if defined(CONFIG_MTD_SMART) && defined(CONFIG_FS_SMARTFS) + /* Now initialize a SMART Flash block device and bind it to the MTD + * device */ + + sprintf(partref, "p%d", partno); + smart_initialize(CONFIG_B_L475E_IOT01A_MTD_FLASH_MINOR, + mtd_part, partref); +#endif + +process_next_part: + /* Update the pointer to point to the next size in the list */ + + while ((*ptr >= '0') && (*ptr <= '9')) + { + ptr++; + } + + if (*ptr == ',') + { + ptr++; + } + + /* Increment the part number */ + + partno++; + } + } +#else /* CONFIG_B_L475E_IOT01A_MTD_PART */ + +#ifdef HAVE_MX25R6435F_SMARTFS + /* Configure the device with no partition support */ + + smart_initialize(CONFIG_B_L475E_IOT01A_MTD_FLASH_MINOR, g_mtd_fs, NULL); +#endif /* HAVE_MX25R6435F_SMARTFS */ + +#endif /* CONFIG_B_L475E_IOT01A_MTD_PART */ + } +#endif /* HAVE_MX25R6435F */ + #ifdef HAVE_SPSGRF /* Configure Spirit/SPSGRF wireless */