diff --git a/arch b/arch index 131d15e8191..3a926c8edd6 160000 --- a/arch +++ b/arch @@ -1 +1 @@ -Subproject commit 131d15e81914f13308331ebe10a8737bade31601 +Subproject commit 3a926c8edd68eac7b60d4430ef9d4284215e3372 diff --git a/drivers/mtd/st25fl1.c b/drivers/mtd/st25fl1.c index 4694320d08f..61667ff1846 100644 --- a/drivers/mtd/st25fl1.c +++ b/drivers/mtd/st25fl1.c @@ -311,7 +311,7 @@ static inline void st25fl1_unlock(FAR struct qspi_dev_s *qspi); static int st25fl1_command(FAR struct qspi_dev_s *qspi, uint8_t cmd); static int st25fl1_command_address(FAR struct qspi_dev_s *qspi, uint8_t cmd, - off_t address); + off_t addr, uint8_t addrlen); static int st25fl1_command_read(FAR struct qspi_dev_s *qspi, uint8_t cmd, FAR void *buffer, size_t buflen); static int st25fl1_command_write(FAR struct qspi_dev_s *qspi, uint8_t cmd, @@ -324,7 +324,6 @@ static void st25fl1_write_disable(FAR struct qspi_dev_s *qspi); static int st25fl1_readid(FAR struct st25fl1_dev_s *priv); static void st25fl1_unprotect(FAR struct st25fl1_dev_s *priv); -static uint8_t st25fl1_waitwritecomplete(FAR struct st25fl1_dev_s *priv); static int st25fl1_erase_sector(FAR struct st25fl1_dev_s *priv, off_t offset); static int st25fl1_erase_chip(FAR struct st25fl1_dev_s *priv); static void st25fl1_read_byte(FAR struct st25fl1_dev_s *priv, FAR uint8_t *buffer, @@ -401,10 +400,39 @@ static inline void st25fl1_unlock(FAR struct qspi_dev_s *qspi) static int st25fl1_command(FAR struct qspi_dev_s *qspi, uint8_t cmd) { - /* This function just allows us to insert debug output */ + struct qspi_xfrinfo_s xfrinfo; fvdbg("CMD: %02x\n", cmd); - return QSPI_COMMAND(qspi, (uint16_t)cmd); + + xfrinfo.flags = 0; + xfrinfo.addrlen = 0; + xfrinfo.cmd = cmd; + xfrinfo.buflen = 0; + xfrinfo.addr = 0; + xfrinfo.buffer = NULL; + + return QSPI_COMMAND(qspi, &xfrinfo); +} + +/************************************************************************************ + * Name: st25fl1_command_address + ************************************************************************************/ + +static int st25fl1_command_address(FAR struct qspi_dev_s *qspi, uint8_t cmd, + off_t addr, uint8_t addrlen) +{ + struct qspi_xfrinfo_s xfrinfo; + + fvdbg("CMD: %02x Address: %04lx addrlen=%d\n", cmd, (unsigned long)addr, addrlen); + + xfrinfo.flags = QSPIXFR_ADDRESS; + xfrinfo.addrlen = addrlen; + xfrinfo.cmd = cmd; + xfrinfo.buflen = 0; + xfrinfo.addr = addr; + xfrinfo.buffer = NULL; + + return QSPI_COMMAND(qspi, &xfrinfo); } /************************************************************************************ @@ -414,10 +442,18 @@ static int st25fl1_command(FAR struct qspi_dev_s *qspi, uint8_t cmd) static int st25fl1_command_read(FAR struct qspi_dev_s *qspi, uint8_t cmd, FAR void *buffer, size_t buflen) { - /* This function just allows us to insert debug output */ + struct qspi_xfrinfo_s xfrinfo; fvdbg("CMD: %02x buflen: %lu\n", cmd, (unsigned long)buflen); - return QSPI_COMMAND_READ(qspi, (uint16_t)cmd, buffer, buflen); + + xfrinfo.flags = QSPIXFR_READDATA; + xfrinfo.addrlen = 0; + xfrinfo.cmd = cmd; + xfrinfo.buflen = buflen; + xfrinfo.addr = 0; + xfrinfo.buffer = buffer; + + return QSPI_COMMAND(qspi, &xfrinfo); } /************************************************************************************ @@ -427,10 +463,18 @@ static int st25fl1_command_read(FAR struct qspi_dev_s *qspi, uint8_t cmd, static int st25fl1_command_write(FAR struct qspi_dev_s *qspi, uint8_t cmd, FAR const void *buffer, size_t buflen) { - /* This function just allows us to insert debug output */ + struct qspi_xfrinfo_s xfrinfo; fvdbg("CMD: %02x buflen: %lu\n", cmd, (unsigned long)buflen); - return QSPI_COMMAND_WRITE(qspi, (uint16_t)cmd, buffer, buflen); + + xfrinfo.flags = QSPIXFR_WRITEDATA; + xfrinfo.addrlen = 0; + xfrinfo.cmd = cmd; + xfrinfo.buflen = buflen; + xfrinfo.addr = 0; + xfrinfo.buffer = (FAR void *)buffer; + + return QSPI_COMMAND(qspi, &xfrinfo); } /************************************************************************************ @@ -584,31 +628,13 @@ static void st25fl1_unprotect(FAR struct st25fl1_dev_s *priv) #warning Missing Logic } -/************************************************************************************ - * Name: st25fl1_waitwritecomplete - ************************************************************************************/ - -static uint8_t st25fl1_waitwritecomplete(struct st25fl1_dev_s *priv) -{ - uint8_t status; - - /* Loop as long as the memory is busy with a write cycle */ - - do - { -#warning Missing Logic - } - while ((status & STATUS1_BUSY_MASK) == STATUS1_BUSY); - - return status; -} - /************************************************************************************ * Name: st25fl1_erase_sector ************************************************************************************/ static int st25fl1_erase_sector(struct st25fl1_dev_s *priv, off_t sector) { + off_t address; #ifdef CONFIG_DEBUG uint8_t status; #endif @@ -635,8 +661,10 @@ static int st25fl1_erase_sector(struct st25fl1_dev_s *priv, off_t sector) /* Send the sector erase command */ + address = (off_t)sector << priv->sectorshift; + st25fl1_write_enable(priv->qspi); - st25fl1_command_address(priv->qspi, ST25FL1_SECTOR_ERASE, sector); + st25fl1_command_address(priv->qspi, ST25FL1_SECTOR_ERASE, address, 3); /* Wait for erasure to finish */ diff --git a/include/nuttx/spi/qspi.h b/include/nuttx/spi/qspi.h index 127b8c83065..c306faac422 100644 --- a/include/nuttx/spi/qspi.h +++ b/include/nuttx/spi/qspi.h @@ -131,67 +131,29 @@ * Name: QSPI_COMMAND * * Description: - * Send a command to the QSPI device + * Perform one QSPI command transfer * * Input Parameters: - * dev - Device-specific state data - * cmd - The command to send. the size of the data is determined by the - * number of bits selected for the QSPI interface. + * dev - Device-specific state data + * xfrinfo - Describes the command transfer to be performed. * * Returned Value: * Zero (OK) on SUCCESS, a negated errno on value of failure * ****************************************************************************/ -#define QSPI_COMMAND(d,c) ((d)->ops->command(d,(uint16_t)c)) +#define QSPI_COMMAND(d,x) (d)->ops->command(d,x) -/**************************************************************************** - * Name: QSPI_COMMAND_WRITE - * - * Description: - * Send a command then send a block of data. - * - * Input Parameters: - * dev - Device-specific state data - * cmd - The command to send. the size of the data is determined by - * the number of bits selected for the QSPI interface. - * buffer - A pointer to the buffer of data to be sent - * buflen - the length of data to send from the buffer in number of words. - * The wordsize is determined by the number of bits-per-word - * selected for the QSPI interface. If nbits <= 8, the data is - * packed into uint8_t's; if nbits >8, the data is packed into - * uint16_t's - * - * Returned Value: - * Zero (OK) on SUCCESS, a negated errno on value of failure - * - ****************************************************************************/ +/* QSPI Transfer Flags */ -#define QSPI_COMMAND_WRITE(d,c,b,l) ((d)->ops->command_write(d,c,b,l)) +#define QSPIXFR_ADDRESS (1 << 0) /* Enable address transfer */ +#define QSPIXFR_READDATA (1 << 1) /* Enable read data transfer */ +#define QSPIXFR_WRITEDATA (1 << 2) /* Enable write data transfer */ -/**************************************************************************** - * Name: QSPI_COMMAND_READ - * - * Description: - * Receive a block of data from QSPI. Required. - * - * Input Parameters: - * dev - Device-specific state data - * cmd - The command to send. the size of the data is determined by - * the number of bits selected for the QSPI interface. - * buffer - A pointer to the buffer in which to receive data - * buflen - the length of data that can be received in the buffer in number - * of words. The wordsize is determined by the number of bits- - * per-word selected for the QSPI interface. If nbits <= 8, the - * data is packed into uint8_t's; if nbits >8, the data is packed - * into uint16_t's - * - * Returned Value: - * Zero (OK) on SUCCESS, a negated errno on value of failure - * - ****************************************************************************/ - -#define QSPI_COMMAND_READ(d,c,b,l) ((d)->ops->command_read(d,c,b,l)) +#define QSPIXFR_ISADDRESS(f) (((f) & QSPIXFR_ADDRESS) != 0) +#define QSPIXFR_ISDATA(f) (((f) & (QSPIXFR_READDATA | QSPIXFR_WRITEDATA)) != 0) +#define QSPIXFR_ISREAD(f) (((f) & QSPIXFR_READDATA) != 0) +#define QSPIXFR_ISWRITE(f) (((f) & QSPIXFR_WRITEDATA) != 0) /**************************************************************************** * Public Types @@ -207,6 +169,18 @@ enum qspi_mode_e QSPIDEV_MODE3 /* CPOL=1 CHPHA=1 */ }; +/* This structure describes one transfer */ + +struct qspi_xfrinfo_s +{ + uint8_t flags; /* See QSPIXFR_* definitions */ + uint8_t addrlen; /* Address length in bytes (if QSPIXFR_ADDRESS) */ + uint16_t cmd; /* Command */ + uint16_t buflen; /* Data buffer length in bytes (if QSPIXFR_DATA) */ + uint32_t addr; /* Address (if QSPIXFR_ADDRESS) */ + FAR void *buffer; /* Data buffer (if QSPIXFR_DATA) */ +}; + /* The QSPI vtable */ struct qspi_dev_s; @@ -216,11 +190,8 @@ struct qspi_ops_s CODE uint32_t (*setfrequency)(FAR struct qspi_dev_s *dev, uint32_t frequency); CODE void (*setmode)(FAR struct qspi_dev_s *dev, enum qspi_mode_e mode); CODE void (*setbits)(FAR struct qspi_dev_s *dev, int nbits); - CODE int (*command)(FAR struct qspi_dev_s *dev, uint16_t command); - CODE int (*command_write)(FAR struct qspi_dev_s *dev, uint16_t cmd, - FAR const void *buffer, size_t buflen); - CODE int (*command_read)(FAR struct qspi_dev_s *dev, uint16_t cmd, - FAR void *buffer, size_t buflen); + CODE int (*command)(FAR struct qspi_dev_s *dev, + FAR struct qspi_xfrinfo_s *xfrinfo); }; /* QSPI private data. This structure only defines the initial fields of the