mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-02-06 17:12:01 +08:00
[DM][MTD] Add common MTD drivers
1. CFI-Nor flash DM driver. 2. SPI-Nor flash DM driver. Signed-off-by: GuEe-GUI <2991707448@qq.com>
This commit is contained in:
@@ -2,7 +2,24 @@ menuconfig RT_USING_MTD_NOR
|
||||
bool "Using MTD Nor Flash device drivers"
|
||||
default n
|
||||
|
||||
config RT_USING_MTD_NAND
|
||||
config RT_USING_MTD_NOR_CFI
|
||||
bool "CFI Flash driver"
|
||||
depends on RT_USING_DM
|
||||
depends on RT_USING_MTD_NOR
|
||||
default n
|
||||
|
||||
config RT_USING_MTD_NOR_SPI
|
||||
bool "SPI Nor Flash driver"
|
||||
depends on RT_USING_DM
|
||||
depends on RT_USING_MTD_NOR
|
||||
depends on RT_USING_SPI
|
||||
select RT_USING_SFUD
|
||||
select RT_SFUD_USING_SFDP
|
||||
select RT_SFUD_USING_FLASH_INFO_TABLE
|
||||
select SFUD_USING_QSPI if RT_USING_QSPI
|
||||
default n
|
||||
|
||||
menuconfig RT_USING_MTD_NAND
|
||||
bool "Using MTD Nand Flash device drivers"
|
||||
default n
|
||||
|
||||
|
||||
@@ -15,6 +15,12 @@ if GetDepend(['RT_USING_MTD_NAND']):
|
||||
src += ['mtd_nand.c']
|
||||
depend += ['RT_USING_MTD_NAND']
|
||||
|
||||
if GetDepend(['RT_USING_MTD_NOR_CFI']):
|
||||
src += ['mtd-cfi.c']
|
||||
|
||||
if GetDepend(['RT_USING_MTD_NOR_SPI']):
|
||||
src += ['mtd-spi-nor.c']
|
||||
|
||||
if src:
|
||||
group = DefineGroup('DeviceDrivers', src, depend = depend, CPPPATH = CPPPATH)
|
||||
|
||||
|
||||
1336
components/drivers/mtd/mtd-cfi.c
Normal file
1336
components/drivers/mtd/mtd-cfi.c
Normal file
File diff suppressed because it is too large
Load Diff
166
components/drivers/mtd/mtd-cfi.h
Normal file
166
components/drivers/mtd/mtd-cfi.h
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-02-25 GuEe-GUI the first version
|
||||
*/
|
||||
|
||||
#ifndef __MTD_CFI_H__
|
||||
#define __MTD_CFI_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
/* Values for the width of the port */
|
||||
#define FLASH_CFI_8BIT 0x01
|
||||
#define FLASH_CFI_16BIT 0x02
|
||||
#define FLASH_CFI_32BIT 0x04
|
||||
#define FLASH_CFI_64BIT 0x08
|
||||
/* Values for the width of the chip */
|
||||
#define FLASH_CFI_BY8 0x01
|
||||
#define FLASH_CFI_BY16 0x02
|
||||
#define FLASH_CFI_BY32 0x04
|
||||
#define FLASH_CFI_BY64 0x08
|
||||
/* Values for the flash device interface */
|
||||
#define FLASH_CFI_X8 0x00
|
||||
#define FLASH_CFI_X16 0x01
|
||||
#define FLASH_CFI_X8X16 0x02
|
||||
#define FLASH_CFI_X16X32 0x05
|
||||
|
||||
/* Convert between bit value and numeric value */
|
||||
#define FLASH_CFI_SHIFT_WIDTH 3
|
||||
|
||||
#define FLASH_CMD_CFI 0x98
|
||||
#define FLASH_CMD_READ_ID 0x90
|
||||
#define FLASH_CMD_RESET 0xff
|
||||
#define FLASH_CMD_BLOCK_ERASE 0x20
|
||||
#define FLASH_CMD_ERASE_CONFIRM 0xd0
|
||||
#define FLASH_CMD_WRITE 0x40
|
||||
#define FLASH_CMD_PROTECT 0x60
|
||||
#define FLASH_CMD_SETUP 0x60
|
||||
#define FLASH_CMD_SET_CR_CONFIRM 0x03
|
||||
#define FLASH_CMD_PROTECT_SET 0x01
|
||||
#define FLASH_CMD_PROTECT_CLEAR 0xd0
|
||||
#define FLASH_CMD_CLEAR_STATUS 0x50
|
||||
#define FLASH_CMD_READ_STATUS 0x70
|
||||
#define FLASH_CMD_WRITE_TO_BUFFER 0xe8
|
||||
#define FLASH_CMD_WRITE_BUFFER_PROG 0xe9
|
||||
#define FLASH_CMD_WRITE_BUFFER_CONFIRM 0xd0
|
||||
|
||||
#define FLASH_STATUS_DONE 0x80
|
||||
#define FLASH_STATUS_ESS 0x40
|
||||
#define FLASH_STATUS_ECLBS 0x20
|
||||
#define FLASH_STATUS_PSLBS 0x10
|
||||
#define FLASH_STATUS_VPENS 0x08
|
||||
#define FLASH_STATUS_PSS 0x04
|
||||
#define FLASH_STATUS_DPS 0x02
|
||||
#define FLASH_STATUS_R 0x01
|
||||
#define FLASH_STATUS_PROTECT 0x01
|
||||
|
||||
#define FLASH_CONTINUATION_CODE 0x7f
|
||||
|
||||
#define FLASH_OFFSET_MANUFACTURER_ID 0x00
|
||||
#define FLASH_OFFSET_DEVICE_ID 0x01
|
||||
#define FLASH_OFFSET_LOWER_SW_BITS 0x0c
|
||||
#define FLASH_OFFSET_DEVICE_ID2 0x0e
|
||||
#define FLASH_OFFSET_DEVICE_ID3 0x0f
|
||||
#define FLASH_OFFSET_CFI 0x55
|
||||
#define FLASH_OFFSET_CFI_ALT 0x555
|
||||
#define FLASH_OFFSET_CFI_RESP 0x10 /* "QRY" */
|
||||
#define FLASH_OFFSET_PRIMARY_VENDOR 0x13 /* Primary OEM command set */
|
||||
#define FLASH_OFFSET_EXT_QUERY_T_P_ADDR 0x15 /* Extended query table primary address */
|
||||
#define FLASH_OFFSET_WTOUT 0x1f
|
||||
#define FLASH_OFFSET_WBTOUT 0x20
|
||||
#define FLASH_OFFSET_ETOUT 0x21
|
||||
#define FLASH_OFFSET_CETOUT 0x22
|
||||
#define FLASH_OFFSET_WMAX_TOUT 0x23
|
||||
#define FLASH_OFFSET_WBMAX_TOUT 0x24
|
||||
#define FLASH_OFFSET_EMAX_TOUT 0x25
|
||||
#define FLASH_OFFSET_CEMAX_TOUT 0x26
|
||||
#define FLASH_OFFSET_SIZE 0x27 /* 2^N bytes */
|
||||
#define FLASH_OFFSET_INTERFACE 0x28
|
||||
#define FLASH_OFFSET_BUFFER_SIZE 0x2a
|
||||
#define FLASH_OFFSET_NUM_ERASE_REGIONS 0x2c
|
||||
#define FLASH_OFFSET_ERASE_REGIONS 0x2d
|
||||
#define FLASH_OFFSET_PROTECT 0x02
|
||||
#define FLASH_OFFSET_USER_PROTECTION 0x85
|
||||
#define FLASH_OFFSET_INTEL_PROTECTION 0x81
|
||||
|
||||
#define CFI_CMDSET_NONE 0
|
||||
#define CFI_CMDSET_INTEL_EXTENDED 1
|
||||
#define CFI_CMDSET_AMD_STANDARD 2
|
||||
#define CFI_CMDSET_INTEL_STANDARD 3
|
||||
#define CFI_CMDSET_AMD_EXTENDED 4
|
||||
#define CFI_CMDSET_MITSU_STANDARD 256
|
||||
#define CFI_CMDSET_MITSU_EXTENDED 257
|
||||
#define CFI_CMDSET_SST 258
|
||||
#define CFI_CMDSET_INTEL_PROG_REGIONS 512
|
||||
|
||||
#define AMD_CMD_RESET 0xf0
|
||||
#define AMD_CMD_WRITE 0xa0
|
||||
#define AMD_CMD_ERASE_START 0x80
|
||||
#define AMD_CMD_ERASE_SECTOR 0x30
|
||||
#define AMD_CMD_UNLOCK_START 0xaa
|
||||
#define AMD_CMD_UNLOCK_ACK 0x55
|
||||
#define AMD_CMD_WRITE_TO_BUFFER 0x25
|
||||
#define AMD_CMD_WRITE_BUFFER_CONFIRM 0x29
|
||||
#define AMD_CMD_SET_PPB_ENTRY 0xc0
|
||||
#define AMD_CMD_SET_PPB_EXIT_BC1 0x90
|
||||
#define AMD_CMD_SET_PPB_EXIT_BC2 0x00
|
||||
#define AMD_CMD_PPB_UNLOCK_BC1 0x80
|
||||
#define AMD_CMD_PPB_UNLOCK_BC2 0x30
|
||||
#define AMD_CMD_PPB_LOCK_BC1 0xa0
|
||||
#define AMD_CMD_PPB_LOCK_BC2 0x00
|
||||
|
||||
#define AMD_STATUS_TOGGLE 0x40
|
||||
#define AMD_STATUS_ERROR 0x20
|
||||
|
||||
#define ATM_CMD_UNLOCK_SECT 0x70
|
||||
#define ATM_CMD_SOFTLOCK_START 0x80
|
||||
#define ATM_CMD_LOCK_SECT 0x40
|
||||
|
||||
union cfi_word
|
||||
{
|
||||
rt_uint8_t w8;
|
||||
rt_uint16_t w16;
|
||||
rt_uint32_t w32;
|
||||
rt_uint64_t w64;
|
||||
};
|
||||
|
||||
#ifndef CFI_FLASH_SECT_MAX
|
||||
#define CFI_FLASH_SECT_MAX 512
|
||||
#endif
|
||||
|
||||
#ifndef CFI_QUERY_ERASE_REGIONS_MAX
|
||||
#define CFI_QUERY_ERASE_REGIONS_MAX CFI_FLASH_SECT_MAX
|
||||
#endif
|
||||
|
||||
rt_packed(struct cfi_query
|
||||
{
|
||||
rt_uint8_t query[3]; /* "Q" "R" "Y" */
|
||||
rt_uint16_t primary_id; /* Unaligned */
|
||||
rt_uint16_t primary_address; /* Unaligned */
|
||||
rt_uint16_t alternate_id; /* Unaligned */
|
||||
rt_uint16_t alternate_address; /* Unaligned */
|
||||
rt_uint8_t vcc_min;
|
||||
rt_uint8_t vcc_max;
|
||||
rt_uint8_t vpp_min;
|
||||
rt_uint8_t vpp_max;
|
||||
rt_uint8_t word_write_timeout_type;
|
||||
rt_uint8_t buf_write_timeout_type;
|
||||
rt_uint8_t block_erase_timeout_type;
|
||||
rt_uint8_t chip_erase_timeout_type;
|
||||
rt_uint8_t word_write_timeout_max;
|
||||
rt_uint8_t buf_write_timeout_max;
|
||||
rt_uint8_t block_erase_timeout_max;
|
||||
rt_uint8_t chip_erase_timeout_max;
|
||||
rt_uint8_t dev_size;
|
||||
rt_uint16_t interface_desc; /* Aligned */
|
||||
rt_uint16_t max_buf_write_size; /* Aligned */
|
||||
rt_uint8_t num_erase_regions;
|
||||
rt_uint32_t erase_region_info[CFI_QUERY_ERASE_REGIONS_MAX]; /* Unaligned */
|
||||
});
|
||||
|
||||
#endif /* __MTD_CFI_H__ */
|
||||
98
components/drivers/mtd/mtd-spi-nor.c
Normal file
98
components/drivers/mtd/mtd-spi-nor.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-02-25 GuEe-GUI the first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include "dev_spi_flash_sfud.h"
|
||||
|
||||
extern rt_err_t rt_spidev_device_init(struct rt_spi_device *dev, const char *name);
|
||||
|
||||
static rt_err_t spi_nor_flash_probe(struct rt_spi_device *spi_dev)
|
||||
{
|
||||
rt_spi_flash_device_t flash;
|
||||
const char *dev_name = rt_dm_dev_get_name(&spi_dev->parent);
|
||||
const char *vendor = spi_dev->id ? spi_dev->id->name : "spi-nor";
|
||||
|
||||
rt_spidev_device_init(spi_dev, dev_name);
|
||||
|
||||
if (!(flash = rt_sfud_flash_probe(vendor, dev_name)))
|
||||
{
|
||||
/* Maybe is not support by SFUD now, user could access it later */
|
||||
return -RT_ENOSYS;
|
||||
}
|
||||
|
||||
rt_dm_dev_set_name_auto(&flash->flash_device, "nor");
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static const struct rt_spi_device_id spi_nor_flash_ids[] =
|
||||
{
|
||||
/*
|
||||
* Allow non-DT platform devices to bind to the "spi-nor" modalias, and
|
||||
* hack around the fact that the SPI core does not provide uevent
|
||||
* matching for .ofw_ids
|
||||
*/
|
||||
{ "spi-nor" },
|
||||
|
||||
/*
|
||||
* Entries not used in DTs that should be safe to drop after replacing
|
||||
* them with "spi-nor" in platform data.
|
||||
*/
|
||||
{ "s25sl064a" }, { "w25x16" }, { "m25p10" }, { "m25px64" },
|
||||
|
||||
/*
|
||||
* Entries that were used in DTs without "jedec,spi-nor" fallback and
|
||||
* should be kept for backward compatibility.
|
||||
*/
|
||||
{ "at25df321a" }, { "at25df641" }, { "at26df081a" },
|
||||
{ "mx25l4005a" }, { "mx25l1606e" }, { "mx25l6405d" }, { "mx25l12805d" },
|
||||
{ "mx25l25635e" }, { "mx66l51235l" },
|
||||
{ "n25q064" }, { "n25q128a11" }, { "n25q128a13" }, { "n25q512a" },
|
||||
{ "s25fl256s1" }, { "s25fl512s" }, { "s25sl12801" }, { "s25fl008k" },
|
||||
{ "s25fl064k" },
|
||||
{ "sst25vf040b" }, { "sst25vf016b" }, { "sst25vf032b" }, { "sst25wf040" },
|
||||
{ "m25p40" }, { "m25p80" }, { "m25p16" }, { "m25p32" },
|
||||
{ "m25p64" }, { "m25p128" },
|
||||
{ "w25x80" }, { "w25x32" }, { "w25q32" }, { "w25q32dw" },
|
||||
{ "w25q80bl" }, { "w25q128" }, { "w25q256" },
|
||||
|
||||
/* Flashes that can't be detected using JEDEC */
|
||||
{ "m25p05-nonjedec" }, { "m25p10-nonjedec" }, { "m25p20-nonjedec" },
|
||||
{ "m25p40-nonjedec" }, { "m25p80-nonjedec" }, { "m25p16-nonjedec" },
|
||||
{ "m25p32-nonjedec" }, { "m25p64-nonjedec" }, { "m25p128-nonjedec" },
|
||||
|
||||
/* Everspin MRAMs (non-JEDEC) */
|
||||
{ "mr25h128" }, /* 128 Kib, 40 MHz */
|
||||
{ "mr25h256" }, /* 256 Kib, 40 MHz */
|
||||
{ "mr25h10" }, /* 1 Mib, 40 MHz */
|
||||
{ "mr25h40" }, /* 4 Mib, 40 MHz */
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static const struct rt_ofw_node_id spi_nor_flash_ofw_ids[] =
|
||||
{
|
||||
/*
|
||||
* Generic compatibility for SPI NOR that can be identified by the
|
||||
* JEDEC READ ID opcode (0x9F). Use this, if possible.
|
||||
*/
|
||||
{ .compatible = "jedec,spi-nor" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct rt_spi_driver spi_nor_flash_driver =
|
||||
{
|
||||
.ids = spi_nor_flash_ids,
|
||||
.ofw_ids = spi_nor_flash_ofw_ids,
|
||||
|
||||
.probe = spi_nor_flash_probe,
|
||||
};
|
||||
RT_SPI_DRIVER_EXPORT(spi_nor_flash_driver);
|
||||
Reference in New Issue
Block a user