b-l475e-iot01a: add basic support for external Macronix QuadSPI flash memory

This commit is contained in:
Simon Piriou 2017-08-06 10:52:12 -06:00 committed by Gregory Nutt
parent b1f50490bd
commit 38569d50fb
5 changed files with 189 additions and 4 deletions

View File

@ -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
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

View File

@ -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 */

View File

@ -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
************************************************************************************/

View File

@ -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 */

View File

@ -39,16 +39,22 @@
#include <nuttx/config.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/mount.h>
#include <syslog.h>
#include <errno.h>
#include <nuttx/input/buttons.h>
#include <nuttx/leds/userled.h>
#include <nuttx/board.h>
#include <nuttx/spi/qspi.h>
#include <nuttx/mtd/mtd.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#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 */