Adds the simulated QSPI (N25Q) flash to the simulation and modify sim up_spiflash.c to enable it to run with different MTD drivers based on config options (currently m25p, sst26 and w25).

This commit is contained in:
Ken Pettit 2016-07-19 07:33:44 -06:00 committed by Gregory Nutt
parent f222d37aa7
commit 148cf1ac22
5 changed files with 320 additions and 53 deletions

View file

@ -245,20 +245,6 @@ config SIM_SPIFLASH_128M
endchoice
config SIM_SPIFLASH_MANUFACTURER
hex "Hex ID of the FLASH manufacturer code"
default 0x20
depends on SIM_SPIFLASH
---help---
Allows the simulated FLASH Manufacturer ID to be set.
config SIM_SPIFLASH_MEMORY_TYPE
hex "Hex ID of the FLASH Memory Type code"
default 0x20
depends on SIM_SPIFLASH
---help---
Allows the simulated FLASH Memory Type code to be set.
config SIM_SPIFLASH_SECTORSIZE
int "FLASH Sector Erase Size"
default 65536
@ -277,6 +263,51 @@ config SIM_SPIFLASH_SUBSECTORSIZE
Sets the smaller sub-sector erase size supported by the
FLASH emulation
config SIM_SPIFLASH_M25P
bool "Enable M25Pxx FLASH"
depends on MTD_M25P
---help---
Enables simulation of an M25P type FLASH
config SIM_SPIFLASH_SST26
bool "Enable SST26 FLASH"
depends on MTD_SST26
---help---
Enables simulation of an SST26 type FLASH
config SIM_SPIFLASH_W25
bool "Enable W25 FLASH"
depends on MTD_W25
---help---
Enables simulation of a W25 type FLASH
config SIM_SPIFLASH_CUSTOM
bool "Enable Emulation of a Custom Manufacturer / ID FLASH"
depends on SIM_SPIFLASH
---help---
Enables simulation of FLASH with a custom Manufacturer, ID and Capacity
config SIM_SPIFLASH_MANUFACTURER
hex "Hex ID of the FLASH manufacturer code"
default 0x20
depends on SIM_SPIFLASH_CUSTOM
---help---
Allows the simulated FLASH Manufacturer ID to be set.
config SIM_SPIFLASH_MEMORY_TYPE
hex "Hex ID of the FLASH Memory Type code"
default 0x20
depends on SIM_SPIFLASH_CUSTOM
---help---
Allows the simulated FLASH Memory Type code to be set.
config SIM_SPIFLASH_CAPACITY
hex "Hex ID of the FLASH capacity code"
default 0x14
depends on SIM_SPIFLASH_CUSTOM
---help---
Allows the simulated FLASH Memory Capacity code to be set.
config SIM_SPIFLASH_PAGESIZE
int "FLASH Write / Program Page Size"
default 256
@ -289,4 +320,79 @@ config SIM_SPIFLASH_PAGESIZE
"wrap" causing the initial data sent to be overwritten.
This is consistent with standard SPI FLASH operation.
config SIM_QSPIFLASH
bool "Simulated QSPI FLASH with SMARTFS"
default n
select FS_SMARTFS
select MTD_SMART
---help---
Adds a simulated QSPI FLASH that responds to N25QXXX style
commands on the QSPI bus.
choice
prompt "Simulated QSPI FLASH Size"
default SIM_QSPIFLASH_1M
depends on SIM_QSPIFLASH
config SIM_QSPIFLASH_1M
bool "1 MBit (128K Byte)"
config SIM_QSPIFLASH_8M
bool "8 MBit (1M Byte)"
config SIM_QSPIFLASH_32M
bool "32 MBit (4M Byte)"
config SIM_QSPIFLASH_64M
bool "64 MBit (8M Byte)"
config SIM_QSPIFLASH_128M
bool "128 MBit (16M Byte)"
endchoice
config SIM_QSPIFLASH_MANUFACTURER
hex "Hex ID of the FLASH manufacturer code"
default 0x20
depends on SIM_QSPIFLASH
---help---
Allows the simulated FLASH Manufacturer ID to be set.
config SIM_QSPIFLASH_MEMORY_TYPE
hex "Hex ID of the FLASH Memory Type code"
default 0xba
depends on SIM_QSPIFLASH
---help---
Allows the simulated FLASH Memory Type code to be set.
config SIM_QSPIFLASH_SECTORSIZE
int "FLASH Sector Erase Size"
default 65536
depends on SIM_QSPIFLASH
---help---
Sets the large sector erase size that the part simulates.
This driver simulates QSPI devices that have both a large
sector erase as well as a "sub-sector" (per the datasheet)
erase size (typically 4K bytes).
config SIM_QSPIFLASH_SUBSECTORSIZE
int "FLASH Sub-Sector Erase Size"
default 4096
depends on SIM_QSPIFLASH
---help---
Sets the smaller sub-sector erase size supported by the
FLASH emulation
config SIM_QSPIFLASH_PAGESIZE
int "FLASH Write / Program Page Size"
default 256
depends on SIM_QSPIFLASH
---help---
Sets the size of a page program operation. The page size
represents the maximum number of bytes that can be sent
for a program operation. If more bytes than this are
sent on a single Page Program, then the address will
"wrap" causing the initial data sent to be overwritten.
This is consistent with standard SPI FLASH operation.
endif

View file

@ -57,7 +57,7 @@ CSRCS = up_initialize.c up_idle.c up_interruptcontext.c up_initialstate.c
CSRCS += up_createstack.c up_usestack.c up_releasestack.c up_stackframe.c
CSRCS += up_unblocktask.c up_blocktask.c up_releasepending.c
CSRCS += up_reprioritizertr.c up_exit.c up_schedulesigaction.c up_spiflash.c
CSRCS += up_allocateheap.c up_devconsole.c
CSRCS += up_allocateheap.c up_devconsole.c up_qspiflash.c
HOSTSRCS = up_hostusleep.c

View file

@ -71,32 +71,86 @@
*
****************************************************************************/
#if defined(CONFIG_FS_SMARTFS) && defined(CONFIG_SIM_SPIFLASH)
#if defined(CONFIG_FS_SMARTFS) && (defined(CONFIG_SIM_SPIFLASH) || defined(CONFIG_SIM_QSPIFLASH))
static void up_init_smartfs(void)
{
FAR struct mtd_dev_s *mtd;
int minor = 0;
#if defined(CONFIG_MTD_M25P) || defined(CONFIG_MTD_W25) || defined(CONFIG_MTD_SST26)
FAR struct spi_dev_s *spi;
#endif
#ifdef CONFIG_MTD_N25QXXX
FAR struct qspi_dev_s *qspi;
#endif
#ifdef CONFIG_SIM_SPIFLASH
#ifdef CONFIG_MTD_M25P
/* Initialize a simulated SPI FLASH block device m25p MTD driver */
spi = up_spiflashinitialize();
mtd = m25p_initialize(spi);
spi = up_spiflashinitialize("m25p");
if (spi != NULL)
{
mtd = m25p_initialize(spi);
/* Now initialize a SMART Flash block device and bind it to the MTD device */
/* Now initialize a SMART Flash block device and bind it to the MTD device */
smart_initialize(0, mtd, NULL);
if (mtd != NULL)
{
smart_initialize(minor++, mtd, "_m25p");
}
}
#endif
#ifdef CONFIG_MTD_SST26
/* Initialize a simulated SPI FLASH block device sst26 MTD driver */
spi = up_spiflashinitialize("sst26");
if (spi != NULL)
{
mtd = sst26_initialize_spi(spi);
/* Now initialize a SMART Flash block device and bind it to the MTD device */
if (mtd != NULL)
{
smart_initialize(minor++, mtd, "_sst26");
}
}
#endif
#ifdef CONFIG_MTD_W25
/* Initialize a simulated SPI FLASH block device m25p MTD driver */
/* Initialize a simulated SPI FLASH block device w25 MTD driver */
spi = up_spiflashinitialize();
mtd = w25_initialize(spi);
spi = up_spiflashinitialize("w25");
if (spi != NULL)
{
mtd = w25_initialize(spi);
/* Now initialize a SMART Flash block device and bind it to the MTD device */
/* Now initialize a SMART Flash block device and bind it to the MTD device */
smart_initialize(0, mtd, NULL);
if (mtd != NULL)
{
smart_initialize(minor++, mtd, "_w25");
}
}
#endif
#endif /* CONFIG_SIM_SPIFLASH */
#if defined(CONFIG_MTD_N25QXXX) && defined(CONFIG_SIM_QSPIFLASH)
/* Initialize a simulated SPI FLASH block device n25qxxx MTD driver */
qspi = up_qspiflashinitialize();
if (qspi != NULL)
{
mtd = n25qxxx_initialize(qspi, 0);
/* Now initialize a SMART Flash block device and bind it to the MTD device */
if (mtd != NULL)
{
smart_initialize(minor++, mtd, "_n25q");
}
}
#endif
}
#endif
@ -238,7 +292,7 @@ void up_initialize(void)
(void)telnet_initialize();
#endif
#if defined(CONFIG_FS_SMARTFS) && defined(CONFIG_SIM_SPIFLASH)
#if defined(CONFIG_FS_SMARTFS) && (defined(CONFIG_SIM_SPIFLASH) || defined(CONFIG_SIM_QSPIFLASH))
up_init_smartfs();
#endif
}

View file

@ -336,7 +336,12 @@ void netdriver_loop(void);
#ifdef CONFIG_SIM_SPIFLASH
struct spi_dev_s;
struct spi_dev_s *up_spiflashinitialize(void);
struct spi_dev_s *up_spiflashinitialize(FAR const char *name);
#endif
#ifdef CONFIG_SIM_QSPIFLASH
struct qspi_dev_s;
struct qspi_dev_s *up_qspiflashinitialize(void);
#endif
#endif /* __ASSEMBLY__ */

View file

@ -1,7 +1,7 @@
/************************************************************************************
* arch/sim/src/up_spiflash.c
*
* Copyright (C) 2014 Ken Pettit. All rights reserved.
* Copyright (C) 2014, 2016 Ken Pettit. All rights reserved.
* Author: Ken Pettit <pettitkd@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
@ -63,33 +63,37 @@
/* Define the FLASH SIZE in bytes */
#ifdef CONFIG_SIM_SPIFLASH_1M
# define CONFIG_SPIFLASH_SIZE (128 * 1024)
# define CONFIG_SPIFLASH_CAPACITY 0x11
# define CONFIG_SPIFLASH_SIZE (128 * 1024)
# define CONFIG_SPIFLASH_CAPACITY 0x11
#ifndef CONFIG_SIM_SPIFLASH_SECTORSIZE
# define CONFIG_SIM_SPIFLASH_SECTORSIZE 2048
# define CONFIG_SIM_SPIFLASH_SECTORSIZE 2048
#endif
#endif
#ifdef CONFIG_SIM_SPIFLASH_8M
# define CONFIG_SPIFLASH_SIZE (1024 * 1024)
# define CONFIG_SPIFLASH_CAPACITY 0x14
# define CONFIG_SPIFLASH_SIZE (1024 * 1024)
# define CONFIG_SPIFLASH_CAPACITY_SST26 0x3F
# define CONFIG_SPIFLASH_CAPACITY 0x14
#endif
#ifdef CONFIG_SIM_SPIFLASH_32M
# define CONFIG_SPIFLASH_SIZE (4 * 1024 * 1024)
# define CONFIG_SPIFLASH_CAPACITY 0x16
# define CONFIG_SPIFLASH_SIZE (4 * 1024 * 1024)
# define CONFIG_SPIFLASH_CAPACITY_SST26 0x42
# define CONFIG_SPIFLASH_CAPACITY 0x16
#endif
#ifdef CONFIG_SIM_SPIFLASH_64M
# define CONFIG_SPIFLASH_SIZE (8 * 1024 * 1024)
# define CONFIG_SPIFLASH_CAPACITY 0x17
# define CONFIG_SPIFLASH_SIZE (8 * 1024 * 1024)
# define CONFIG_SPIFLASH_CAPACITY_SST26 0x43
# define CONFIG_SPIFLASH_CAPACITY 0x17
#endif
#ifdef CONFIG_SIM_SPIFLASH_128M
# define CONFIG_SPIFLASH_SIZE (16 * 1024 * 1024)
# define CONFIG_SPIFLASH_CAPACITY 0x18
# define CONFIG_SPIFLASH_SIZE (16 * 1024 * 1024)
# define CONFIG_SPIFLASH_CAPACITY_SST26 0x44
# define CONFIG_SPIFLASH_CAPACITY 0x18
#endif
#ifndef CONFIG_SIM_SPIFLASH_MANUFACTURER
@ -169,14 +173,18 @@
struct sim_spiflashdev_s
{
struct spi_dev_s spidev; /* Externally visible part of the SPI interface */
uint32_t selected; /* SPIn base address */
int wren;
int state;
uint16_t read_data;
uint8_t last_cmd;
unsigned long address;
unsigned char data[CONFIG_SPIFLASH_SIZE];
struct spi_dev_s spidev; /* Externally visible part of the SPI interface */
uint32_t selected; /* SPIn base address */
FAR char * name; /* Name of the flash type (m25p, w25, etc.) */
int wren;
int state;
uint16_t read_data;
uint8_t last_cmd;
uint8_t capacity;
uint8_t manuf;
uint8_t type;
unsigned long address;
unsigned char data[CONFIG_SPIFLASH_SIZE];
};
/************************************************************************************
@ -236,9 +244,72 @@ static const struct spi_ops_s g_spiops =
.registercallback = 0,
};
struct sim_spiflashdev_s g_spidev =
#ifdef CONFIG_SIM_SPIFLASH_M25P
struct sim_spiflashdev_s g_spidev_m25p =
{
.spidev = { &g_spiops },
.name = "m25p",
.manuf = 0x20,
.type = 0x20,
.capacity = CONFIG_SPIFLASH_CAPACITY
};
#endif
#ifdef CONFIG_SIM_SPIFLASH_SST26
struct sim_spiflashdev_s g_spidev_sst26 =
{
.spidev = { &g_spiops },
.name = "sst26",
.manuf = 0xBF,
#ifdef CONFIG_SST26_MEMORY_TYPE
.type = CONFIG_SST26_MEMORY_TYPE,
#else
.type = 0x25,
#endif
.capacity = CONFIG_SPIFLASH_CAPACITY_SST26
};
#endif
#ifdef CONFIG_SIM_SPIFLASH_W25
struct sim_spiflashdev_s g_spidev_w25 =
{
.spidev = { &g_spiops },
.name = "w25",
.manuf = 0xef,
.type = 0x30,
.capacity = CONFIG_SPIFLASH_CAPACITY
};
#endif
#ifdef CONFIG_SIM_SPIFLASH_CUSTOM
struct sim_spiflashdev_s g_spidev_custom =
{
.spidev = { &g_spiops },
.name = "custom",
.manuf = CONFIG_SIM_SPIFLASH_MANUFACTURER,
.type = CONFIG_SIM_SPIFLASH_MEMORY_TYPE,
.capacity = CONFIG_SIM_SPIFLASH_CAPACITY
};
#endif
struct sim_spiflashdev_s *gp_spidev[] =
{
#ifdef CONFIG_SIM_SPIFLASH_M25P
&g_spidev_m25p,
#endif
#ifdef CONFIG_SIM_SPIFLASH_SST26
&g_spidev_sst26,
#endif
#ifdef CONFIG_SIM_SPIFLASH_W25
&g_spidev_w25,
#endif
#ifdef CONFIG_SIM_SPIFLASH_CUSTOM
&g_spidev_custom,
#endif
// Null termination pointer at end of list
NULL
};
/************************************************************************************
@ -662,17 +733,17 @@ static void spiflash_writeword(FAR struct sim_spiflashdev_s *priv, uint16_t data
/* Read ID States */
case SPIFLASH_STATE_RDID1:
priv->read_data = CONFIG_SIM_SPIFLASH_MANUFACTURER;
priv->read_data = priv->manuf; //CONFIG_SIM_SPIFLASH_MANUFACTURER;
priv->state = SPIFLASH_STATE_RDID2;
break;
case SPIFLASH_STATE_RDID2:
priv->read_data = CONFIG_SIM_SPIFLASH_MEMORY_TYPE;
priv->read_data = priv->type; //CONFIG_SIM_SPIFLASH_MEMORY_TYPE;
priv->state = SPIFLASH_STATE_RDID3;
break;
case SPIFLASH_STATE_RDID3:
priv->read_data = CONFIG_SPIFLASH_CAPACITY;
priv->read_data = priv->capacity; //CONFIG_SPIFLASH_CAPACITY;
priv->state = SPIFLASH_STATE_IDLE;
break;
@ -834,13 +905,44 @@ static uint16_t spiflash_readword(FAR struct sim_spiflashdev_s *priv)
*
************************************************************************************/
FAR struct spi_dev_s *up_spiflashinitialize()
FAR struct spi_dev_s *up_spiflashinitialize(FAR const char *name)
{
FAR struct sim_spiflashdev_s *priv = NULL;
int x;
irqstate_t flags = enter_critical_section();
priv = &g_spidev;
/* Loop through all supported flash devices */
/* Default to custom FLASH if not specified */
if (name == NULL)
{
name = "custom";
}
for (x = 0; gp_spidev[x] != NULL; x++)
{
/* Search for the specified flash by name */
if (strcmp(name, gp_spidev[x]->name) == 0)
{
break;
}
}
/* Test if flash device found */
if (gp_spidev[x] == NULL)
{
/* Specified device not supported */
return NULL;
}
/* Configure the selected flash device */
priv = gp_spidev[x];
priv->selected = 0;
priv->wren = 0;
priv->address = 0;