mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2025-02-28 01:17:07 +08:00
[DeviceDriver] Add QSPI device driver support for SFUD.
This commit is contained in:
parent
3b20db1903
commit
3a3da42738
@ -23,11 +23,21 @@
|
||||
|
||||
#ifndef RT_SFUD_DEFAULT_SPI_CFG
|
||||
/* read the JEDEC SFDP command must run at 50 MHz or less */
|
||||
#define RT_SFUD_DEFAULT_SPI_CFG \
|
||||
{ \
|
||||
.mode = RT_SPI_MODE_0 | RT_SPI_MSB, \
|
||||
.data_width = 8, \
|
||||
.max_hz = 50 * 1000 * 1000, \
|
||||
#define RT_SFUD_DEFAULT_SPI_CFG \
|
||||
{ \
|
||||
.mode = RT_SPI_MODE_0 | RT_SPI_MSB, \
|
||||
.data_width = 8, \
|
||||
.max_hz = 50 * 1000 * 1000, \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SFUD_USING_QSPI
|
||||
#define RT_SFUD_DEFAULT_QSPI_CFG \
|
||||
{ \
|
||||
RT_SFUD_DEFAULT_SPI_CFG, \
|
||||
.medium_size = 0x800000, \
|
||||
.ddr_mode = 0, \
|
||||
.qspi_dl_width = 4, \
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -116,31 +126,90 @@ static sfud_err spi_write_read(const sfud_spi *spi, const uint8_t *write_buf, si
|
||||
sfud_err result = SFUD_SUCCESS;
|
||||
sfud_flash *sfud_dev = (sfud_flash *) (spi->user_data);
|
||||
struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (sfud_dev->user_data);
|
||||
|
||||
#ifdef SFUD_USING_QSPI
|
||||
struct rt_qspi_device *qspi_dev = RT_NULL;
|
||||
#endif
|
||||
if (write_size) {
|
||||
RT_ASSERT(write_buf);
|
||||
}
|
||||
if (read_size) {
|
||||
RT_ASSERT(read_buf);
|
||||
}
|
||||
|
||||
if (write_size && read_size) {
|
||||
if (rt_spi_send_then_recv(rtt_dev->rt_spi_device, write_buf, write_size, read_buf, read_size) != RT_EOK) {
|
||||
result = SFUD_ERR_TIMEOUT;
|
||||
#ifdef SFUD_USING_QSPI
|
||||
if(rtt_dev->rt_spi_device->bus->mode & RT_SPI_BUS_MODE_QSPI) {
|
||||
qspi_dev = (struct rt_qspi_device *) (rtt_dev->rt_spi_device);
|
||||
if (write_size && read_size) {
|
||||
if (rt_qspi_send_then_recv(qspi_dev, write_buf, write_size, read_buf, read_size) == 0) {
|
||||
result = SFUD_ERR_TIMEOUT;
|
||||
}
|
||||
} else if (write_size) {
|
||||
if (rt_qspi_send(qspi_dev, write_buf, write_size) == 0) {
|
||||
result = SFUD_ERR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
} else if (write_size) {
|
||||
if (rt_spi_send(rtt_dev->rt_spi_device, write_buf, write_size) == 0) {
|
||||
result = SFUD_ERR_TIMEOUT;
|
||||
}
|
||||
} else {
|
||||
if (rt_spi_recv(rtt_dev->rt_spi_device, read_buf, read_size) == 0) {
|
||||
result = SFUD_ERR_TIMEOUT;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (write_size && read_size) {
|
||||
if (rt_spi_send_then_recv(rtt_dev->rt_spi_device, write_buf, write_size, read_buf, read_size) != RT_EOK) {
|
||||
result = SFUD_ERR_TIMEOUT;
|
||||
}
|
||||
} else if (write_size) {
|
||||
if (rt_spi_send(rtt_dev->rt_spi_device, write_buf, write_size) == 0) {
|
||||
result = SFUD_ERR_TIMEOUT;
|
||||
}
|
||||
} else {
|
||||
if (rt_spi_recv(rtt_dev->rt_spi_device, read_buf, read_size) == 0) {
|
||||
result = SFUD_ERR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef SFUD_USING_QSPI
|
||||
/**
|
||||
* QSPI fast read data
|
||||
*/
|
||||
static sfud_err qspi_read(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi_read_cmd_format *qspi_read_cmd_format, uint8_t *read_buf, size_t read_size) {
|
||||
struct rt_qspi_message message;
|
||||
sfud_err result = SFUD_SUCCESS;
|
||||
|
||||
sfud_flash *sfud_dev = (sfud_flash *) (spi->user_data);
|
||||
struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (sfud_dev->user_data);
|
||||
struct rt_qspi_device *qspi_dev = (struct rt_qspi_device *) (rtt_dev->rt_spi_device);
|
||||
|
||||
/* set message struct */
|
||||
message.instruction.content = qspi_read_cmd_format->instruction;
|
||||
message.instruction.qspi_lines = qspi_read_cmd_format->instruction_lines;
|
||||
|
||||
message.address.content = addr;
|
||||
message.address.size = qspi_read_cmd_format->address_size;
|
||||
message.address.qspi_lines = qspi_read_cmd_format->address_lines;
|
||||
|
||||
message.alternate_bytes.content = 0;
|
||||
message.alternate_bytes.size = 0;
|
||||
message.alternate_bytes.qspi_lines = 0;
|
||||
|
||||
message.dummy_cycles = qspi_read_cmd_format->dummy_cycles;
|
||||
|
||||
message.parent.send_buf = RT_NULL;
|
||||
message.parent.recv_buf = read_buf;
|
||||
message.parent.length = read_size;
|
||||
message.parent.cs_release = 1;
|
||||
message.parent.cs_take = 1;
|
||||
message.qspi_data_lines = qspi_read_cmd_format->data_lines;
|
||||
|
||||
if (rt_qspi_transfer_message(qspi_dev, &message) != read_size) {
|
||||
result = SFUD_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void spi_lock(const sfud_spi *spi) {
|
||||
sfud_flash *sfud_dev = (sfud_flash *) (spi->user_data);
|
||||
struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (sfud_dev->user_data);
|
||||
@ -203,6 +272,9 @@ sfud_err sfud_spi_port_init(sfud_flash *flash) {
|
||||
|
||||
/* port SPI device interface */
|
||||
flash->spi.wr = spi_write_read;
|
||||
#ifdef SFUD_USING_QSPI
|
||||
flash->spi.qspi_read = qspi_read;
|
||||
#endif
|
||||
flash->spi.lock = spi_lock;
|
||||
flash->spi.unlock = spi_unlock;
|
||||
flash->spi.user_data = flash;
|
||||
@ -213,8 +285,7 @@ sfud_err sfud_spi_port_init(sfud_flash *flash) {
|
||||
flash->retry.delay = retry_delay_100us;
|
||||
/* 60 seconds timeout */
|
||||
flash->retry.times = 60 * 10000;
|
||||
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -246,6 +317,10 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
|
||||
* @note you also can change the SPI to other configuration after initialized finish */
|
||||
struct rt_spi_configuration cfg = RT_SFUD_DEFAULT_SPI_CFG;
|
||||
extern sfud_err sfud_device_init(sfud_flash *flash);
|
||||
#ifdef SFUD_USING_QSPI
|
||||
struct rt_qspi_configuration qspi_cfg = RT_SFUD_DEFAULT_QSPI_CFG;
|
||||
struct rt_qspi_device *qspi_dev = RT_NULL;
|
||||
#endif
|
||||
|
||||
RT_ASSERT(spi_flash_dev_name);
|
||||
RT_ASSERT(spi_dev_name);
|
||||
@ -277,7 +352,17 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
|
||||
goto error;
|
||||
}
|
||||
sfud_dev->spi.name = spi_dev_name_bak;
|
||||
rt_spi_configure(rtt_dev->rt_spi_device, &cfg);
|
||||
|
||||
#ifdef SFUD_USING_QSPI
|
||||
/* set the qspi line number and configure the QSPI bus */
|
||||
if(rtt_dev->rt_spi_device->bus->mode &RT_SPI_BUS_MODE_QSPI) {
|
||||
qspi_dev = (struct rt_qspi_device *)rtt_dev->rt_spi_device;
|
||||
qspi_cfg.qspi_dl_width = qspi_dev->config.qspi_dl_width;
|
||||
rt_qspi_configure(qspi_dev, &qspi_cfg);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
rt_spi_configure(rtt_dev->rt_spi_device, &cfg);
|
||||
}
|
||||
/* SFUD flash device initialize */
|
||||
{
|
||||
@ -296,6 +381,17 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
|
||||
rtt_dev->geometry.sector_count = sfud_dev->chip.capacity / sfud_dev->chip.erase_gran;
|
||||
rtt_dev->geometry.bytes_per_sector = sfud_dev->chip.erase_gran;
|
||||
rtt_dev->geometry.block_size = sfud_dev->chip.erase_gran;
|
||||
#ifdef SFUD_USING_QSPI
|
||||
/* reconfigure the QSPI bus for medium size */
|
||||
if(rtt_dev->rt_spi_device->bus->mode &RT_SPI_BUS_MODE_QSPI) {
|
||||
qspi_cfg.medium_size = sfud_dev->chip.capacity;
|
||||
rt_qspi_configure(qspi_dev, &qspi_cfg);
|
||||
if(qspi_dev->enter_qspi_mode != RT_NULL)
|
||||
qspi_dev->enter_qspi_mode(qspi_dev);
|
||||
}
|
||||
/* set data lines width */
|
||||
sfud_qspi_fast_read_enable(sfud_dev, qspi_dev->config.qspi_dl_width);
|
||||
#endif /* SFUD_USING_QSPI */
|
||||
}
|
||||
|
||||
/* register device */
|
||||
|
Loading…
x
Reference in New Issue
Block a user