git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9625 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
75d0d3d597
commit
2d4c475d1d
|
@ -54,17 +54,17 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
static const flash_descriptor_t *m25q_get_descriptor(void *instance);
|
static const flash_descriptor_t *m25q_get_descriptor(void *instance);
|
||||||
static flash_error_t m25q_read(void *instance, flash_address_t addr,
|
static flash_error_t m25q_read(void *instance, flash_offset_t offset,
|
||||||
uint8_t *rp, size_t n);
|
size_t n, uint8_t *rp);
|
||||||
static flash_error_t m25q_program(void *instance, flash_address_t addr,
|
static flash_error_t m25q_program(void *instance, flash_offset_t offset,
|
||||||
const uint8_t *pp, size_t n);
|
size_t n, const uint8_t *pp);
|
||||||
static flash_error_t m25q_start_erase_all(void *instance);
|
static flash_error_t m25q_start_erase_all(void *instance);
|
||||||
static flash_error_t m25q_start_erase_sector(void *instance,
|
static flash_error_t m25q_start_erase_sector(void *instance,
|
||||||
flash_sector_t sector);
|
flash_sector_t sector);
|
||||||
static flash_error_t m25q_query_erase(void *instance, uint32_t *msec);
|
static flash_error_t m25q_query_erase(void *instance, uint32_t *msec);
|
||||||
static flash_error_t m25q_verify_erase(void *instance, flash_sector_t sector);
|
static flash_error_t m25q_verify_erase(void *instance, flash_sector_t sector);
|
||||||
static flash_error_t m25q_read_sfdp(void *instance, uint8_t *rp,
|
static flash_error_t m25q_read_sfdp(void *instance, flash_offset_t offset,
|
||||||
flash_address_t addr, size_t n);
|
size_t n, uint8_t *rp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Virtual methods table.
|
* @brief Virtual methods table.
|
||||||
|
@ -319,13 +319,13 @@ static const flash_descriptor_t *m25q_get_descriptor(void *instance) {
|
||||||
return &m25q_descriptor;
|
return &m25q_descriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static flash_error_t m25q_read(void *instance, flash_address_t addr,
|
static flash_error_t m25q_read(void *instance, flash_offset_t offset,
|
||||||
uint8_t *rp, size_t n) {
|
size_t n, uint8_t *rp) {
|
||||||
M25QDriver *devp = (M25QDriver *)instance;
|
M25QDriver *devp = (M25QDriver *)instance;
|
||||||
|
|
||||||
osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U));
|
osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U));
|
||||||
osalDbgCheck((size_t)addr + n <= (size_t)m25q_descriptor.sectors_count *
|
osalDbgCheck((size_t)offset + n <= (size_t)m25q_descriptor.sectors_count *
|
||||||
(size_t)m25q_descriptor.sectors_size);
|
(size_t)m25q_descriptor.sectors_size);
|
||||||
osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
|
osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
|
||||||
"invalid state");
|
"invalid state");
|
||||||
|
|
||||||
|
@ -342,11 +342,11 @@ static flash_error_t m25q_read(void *instance, flash_address_t addr,
|
||||||
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
|
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
|
||||||
/* Fast read command in QSPI mode.*/
|
/* Fast read command in QSPI mode.*/
|
||||||
jesd216_cmd_addr_dummy_receive(devp->config->busp, M25Q_CMD_FAST_READ,
|
jesd216_cmd_addr_dummy_receive(devp->config->busp, M25Q_CMD_FAST_READ,
|
||||||
addr, M25Q_READ_DUMMY_CYCLES, n, rp);
|
offset, M25Q_READ_DUMMY_CYCLES, n, rp);
|
||||||
#else
|
#else
|
||||||
/* Normal read command in SPI mode.*/
|
/* Normal read command in SPI mode.*/
|
||||||
jesd216_cmd_addr_receive(devp->config->busp, M25Q_CMD_READ,
|
jesd216_cmd_addr_receive(devp->config->busp, M25Q_CMD_READ,
|
||||||
addr, n, rp);
|
offset, n, rp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Ready state again.*/
|
/* Ready state again.*/
|
||||||
|
@ -358,13 +358,13 @@ static flash_error_t m25q_read(void *instance, flash_address_t addr,
|
||||||
return FLASH_NO_ERROR;
|
return FLASH_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static flash_error_t m25q_program(void *instance, flash_address_t addr,
|
static flash_error_t m25q_program(void *instance, flash_offset_t offset,
|
||||||
const uint8_t *pp, size_t n) {
|
size_t n, const uint8_t *pp) {
|
||||||
M25QDriver *devp = (M25QDriver *)instance;
|
M25QDriver *devp = (M25QDriver *)instance;
|
||||||
|
|
||||||
osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U));
|
osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U));
|
||||||
osalDbgCheck((size_t)addr + n <= (size_t)m25q_descriptor.sectors_count *
|
osalDbgCheck((size_t)offset + n <= (size_t)m25q_descriptor.sectors_count *
|
||||||
(size_t)m25q_descriptor.sectors_size);
|
(size_t)m25q_descriptor.sectors_size);
|
||||||
osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
|
osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
|
||||||
"invalid state");
|
"invalid state");
|
||||||
|
|
||||||
|
@ -383,7 +383,7 @@ static flash_error_t m25q_program(void *instance, flash_address_t addr,
|
||||||
flash_error_t err;
|
flash_error_t err;
|
||||||
|
|
||||||
/* Data size that can be written in a single program page operation.*/
|
/* Data size that can be written in a single program page operation.*/
|
||||||
size_t chunk = (size_t)(((addr | PAGE_MASK) + 1U) - addr);
|
size_t chunk = (size_t)(((offset | PAGE_MASK) + 1U) - offset);
|
||||||
if (chunk > n) {
|
if (chunk > n) {
|
||||||
chunk = n;
|
chunk = n;
|
||||||
}
|
}
|
||||||
|
@ -392,7 +392,7 @@ static flash_error_t m25q_program(void *instance, flash_address_t addr,
|
||||||
jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE);
|
jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE);
|
||||||
|
|
||||||
/* Page program command.*/
|
/* Page program command.*/
|
||||||
jesd216_cmd_addr_send(devp->config->busp, M25Q_CMD_PAGE_PROGRAM, addr,
|
jesd216_cmd_addr_send(devp->config->busp, M25Q_CMD_PAGE_PROGRAM, offset,
|
||||||
chunk, pp);
|
chunk, pp);
|
||||||
|
|
||||||
/* Wait for status and check errors.*/
|
/* Wait for status and check errors.*/
|
||||||
|
@ -406,9 +406,9 @@ static flash_error_t m25q_program(void *instance, flash_address_t addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next page.*/
|
/* Next page.*/
|
||||||
addr += chunk;
|
offset += chunk;
|
||||||
pp += chunk;
|
pp += chunk;
|
||||||
n -= chunk;
|
n -= chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ready state again.*/
|
/* Ready state again.*/
|
||||||
|
@ -452,7 +452,7 @@ static flash_error_t m25q_start_erase_all(void *instance) {
|
||||||
static flash_error_t m25q_start_erase_sector(void *instance,
|
static flash_error_t m25q_start_erase_sector(void *instance,
|
||||||
flash_sector_t sector) {
|
flash_sector_t sector) {
|
||||||
M25QDriver *devp = (M25QDriver *)instance;
|
M25QDriver *devp = (M25QDriver *)instance;
|
||||||
flash_address_t addr = (flash_address_t)(sector * SECTOR_SIZE);
|
flash_offset_t offset = (flash_offset_t)(sector * SECTOR_SIZE);
|
||||||
|
|
||||||
osalDbgCheck(instance != NULL);
|
osalDbgCheck(instance != NULL);
|
||||||
osalDbgCheck(sector < m25q_descriptor.sectors_count);
|
osalDbgCheck(sector < m25q_descriptor.sectors_count);
|
||||||
|
@ -473,7 +473,7 @@ static flash_error_t m25q_start_erase_sector(void *instance,
|
||||||
jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE);
|
jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE);
|
||||||
|
|
||||||
/* Sector erase command.*/
|
/* Sector erase command.*/
|
||||||
jesd216_cmd_addr(devp->config->busp, M25Q_CMD_SECTOR_ERASE, addr);
|
jesd216_cmd_addr(devp->config->busp, M25Q_CMD_SECTOR_ERASE, offset);
|
||||||
|
|
||||||
/* Bus released.*/
|
/* Bus released.*/
|
||||||
jesd216_bus_release(devp->config->busp);
|
jesd216_bus_release(devp->config->busp);
|
||||||
|
@ -485,7 +485,7 @@ static flash_error_t m25q_verify_erase(void *instance,
|
||||||
flash_sector_t sector) {
|
flash_sector_t sector) {
|
||||||
M25QDriver *devp = (M25QDriver *)instance;
|
M25QDriver *devp = (M25QDriver *)instance;
|
||||||
uint8_t cmpbuf[M25Q_COMPARE_BUFFER_SIZE];
|
uint8_t cmpbuf[M25Q_COMPARE_BUFFER_SIZE];
|
||||||
flash_address_t addr;
|
flash_offset_t offset;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
osalDbgCheck(instance != NULL);
|
osalDbgCheck(instance != NULL);
|
||||||
|
@ -504,19 +504,19 @@ static flash_error_t m25q_verify_erase(void *instance,
|
||||||
devp->state = FLASH_READ;
|
devp->state = FLASH_READ;
|
||||||
|
|
||||||
/* Read command.*/
|
/* Read command.*/
|
||||||
addr = (flash_address_t)(sector * SECTOR_SIZE);
|
offset = (flash_offset_t)(sector * SECTOR_SIZE);
|
||||||
n = SECTOR_SIZE;
|
n = SECTOR_SIZE;
|
||||||
while (n > 0U) {
|
while (n > 0U) {
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
|
|
||||||
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
|
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
|
||||||
jesd216_cmd_addr_dummy_receive(devp->config->busp, M25Q_CMD_FAST_READ,
|
jesd216_cmd_addr_dummy_receive(devp->config->busp, M25Q_CMD_FAST_READ,
|
||||||
addr, M25Q_READ_DUMMY_CYCLES,
|
offset, M25Q_READ_DUMMY_CYCLES,
|
||||||
sizeof cmpbuf, cmpbuf);
|
sizeof cmpbuf, cmpbuf);
|
||||||
#else
|
#else
|
||||||
/* Normal read command in SPI mode.*/
|
/* Normal read command in SPI mode.*/
|
||||||
jesd216_cmd_addr_receive(devp->config->busp, M25Q_CMD_READ,
|
jesd216_cmd_addr_receive(devp->config->busp, M25Q_CMD_READ,
|
||||||
addr, sizeof cmpbuf, cmpbuf);
|
offset, sizeof cmpbuf, cmpbuf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Checking for erased state of current buffer.*/
|
/* Checking for erased state of current buffer.*/
|
||||||
|
@ -532,7 +532,7 @@ static flash_error_t m25q_verify_erase(void *instance,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addr += sizeof cmpbuf;
|
offset += sizeof cmpbuf;
|
||||||
n -= sizeof cmpbuf;
|
n -= sizeof cmpbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,13 +600,12 @@ static flash_error_t m25q_query_erase(void *instance, uint32_t *msec) {
|
||||||
return FLASH_NO_ERROR;
|
return FLASH_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static flash_error_t m25q_read_sfdp(void *instance, uint8_t *rp,
|
static flash_error_t m25q_read_sfdp(void *instance, flash_offset_t offset,
|
||||||
flash_address_t addr,
|
size_t n, uint8_t *rp) {
|
||||||
size_t n) {
|
|
||||||
|
|
||||||
(void)instance;
|
(void)instance;
|
||||||
(void)rp;
|
(void)rp;
|
||||||
(void)addr;
|
(void)offset;
|
||||||
(void)n;
|
(void)n;
|
||||||
|
|
||||||
return FLASH_NO_ERROR;
|
return FLASH_NO_ERROR;
|
||||||
|
|
|
@ -139,6 +139,36 @@ void mfs_cache_erase_id(MFSDriver *devp, uint32_t id) {
|
||||||
}
|
}
|
||||||
#endif /* MFS_CFG_ID_CACHE_SIZE > 0 */
|
#endif /* MFS_CFG_ID_CACHE_SIZE > 0 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flash write.
|
||||||
|
* @note If the option @p MFS_CFG_WRITE_VERIFY is enabled then the flash
|
||||||
|
* is also read back for verification.
|
||||||
|
*
|
||||||
|
* @param[in] devp pointer to the @p MFSDriver object
|
||||||
|
* @param[in] offset flash offset
|
||||||
|
* @param[in] n number of bytes to be read
|
||||||
|
* @param[out] rp pointer to the data buffer
|
||||||
|
* @return The operation status.
|
||||||
|
* @retval MFS_NO_ERROR if the operation has been successfully completed.
|
||||||
|
* @retval MFS_FLASH_FAILURE if the flash memory is unusable because HW
|
||||||
|
* failures.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static mfs_error_t mfs_flash_write(MFSDriver *devp,
|
||||||
|
flash_offset_t offset,
|
||||||
|
size_t n, const
|
||||||
|
uint8_t *p) {
|
||||||
|
flash_error_t ferr;
|
||||||
|
|
||||||
|
ferr = flashProgram(devp->config->flashp, offset, n, p);
|
||||||
|
if (ferr != FLASH_NO_ERROR) {
|
||||||
|
return MFS_FLASH_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MFS_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Erases and verifies all sectors belonging to a bank.
|
* @brief Erases and verifies all sectors belonging to a bank.
|
||||||
*
|
*
|
||||||
|
@ -201,19 +231,26 @@ static mfs_error_t mfs_bank_erase(MFSDriver *devp, mfs_bank_t bank) {
|
||||||
static mfs_error_t mfs_bank_set_header(MFSDriver *devp,
|
static mfs_error_t mfs_bank_set_header(MFSDriver *devp,
|
||||||
mfs_bank_t bank,
|
mfs_bank_t bank,
|
||||||
uint32_t cnt) {
|
uint32_t cnt) {
|
||||||
|
flash_sector_t sector;
|
||||||
mfs_bank_header_t header;
|
mfs_bank_header_t header;
|
||||||
|
|
||||||
|
if (bank == MFS_BANK_0) {
|
||||||
|
sector = devp->config->bank0_start;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sector = devp->config->bank1_start;
|
||||||
|
}
|
||||||
|
|
||||||
header.magic1 = MFS_BANK_MAGIC_1;
|
header.magic1 = MFS_BANK_MAGIC_1;
|
||||||
header.magic1 = MFS_BANK_MAGIC_1;
|
header.magic1 = MFS_BANK_MAGIC_1;
|
||||||
header.counter = cnt;
|
header.counter = cnt;
|
||||||
header.next = sizeof (mfs_bank_header_t);
|
header.next = sizeof (mfs_bank_header_t);
|
||||||
header.crc = crc16(0U, (const uint8_t *)&header, sizeof (uint32_t) * 4);
|
header.crc = crc16(0U, (const uint8_t *)&header, sizeof (uint32_t) * 4);
|
||||||
|
|
||||||
(void)devp;
|
return mfs_flash_write(devp,
|
||||||
(void)bank;
|
flashGetSectorOffset(devp->config->flashp, sector),
|
||||||
(void)cnt;
|
sizeof (mfs_bank_header_t),
|
||||||
|
(const uint8_t *)&header);
|
||||||
return MFS_NO_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -549,7 +586,7 @@ mfs_error_t mfsMount(MFSDriver *devp) {
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
/* Attempting to mount the managed partition.*/
|
/* Attempting to mount the managed partition.*/
|
||||||
for (i = 0; i < MFS_MAX_REPAIR_ATTEMPTS; i++) {
|
for (i = 0; i < MFS_CFG_MAX_REPAIR_ATTEMPTS; i++) {
|
||||||
mfs_error_t err;
|
mfs_error_t err;
|
||||||
|
|
||||||
err = mfs_try_mount(devp);
|
err = mfs_try_mount(devp);
|
||||||
|
|
|
@ -57,8 +57,15 @@
|
||||||
/**
|
/**
|
||||||
* @brief Maximum number of repair attempts on partition mount.
|
* @brief Maximum number of repair attempts on partition mount.
|
||||||
*/
|
*/
|
||||||
#if !defined(MFS_MAX_REPAIR_ATTEMPTS) || defined(__DOXIGEN__)
|
#if !defined(MFS_CFG_MAX_REPAIR_ATTEMPTS) || defined(__DOXIGEN__)
|
||||||
#define MFS_MAX_REPAIR_ATTEMPTS 3
|
#define MFS_CFG_MAX_REPAIR_ATTEMPTS 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Verify written data.
|
||||||
|
*/
|
||||||
|
#if !defined(MFS_CFG_WRITE_VERIFY) || defined(__DOXIGEN__)
|
||||||
|
#define MFS_CFG_WRITE_VERIFY TRUE
|
||||||
#endif
|
#endif
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
@ -70,7 +77,7 @@
|
||||||
#error "invalid MFS_CFG_ID_CACHE_SIZE value"
|
#error "invalid MFS_CFG_ID_CACHE_SIZE value"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (MFS_MAX_REPAIR_ATTEMPTS < 1) || (MFS_MAX_REPAIR_ATTEMPTS > 10)
|
#if (MFS_CFG_MAX_REPAIR_ATTEMPTS < 1) || (MFS_CFG_MAX_REPAIR_ATTEMPTS > 10)
|
||||||
#error "invalid MFS_MAX_REPAIR_ATTEMPTS value"
|
#error "invalid MFS_MAX_REPAIR_ATTEMPTS value"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -145,7 +152,7 @@ typedef struct {
|
||||||
/**
|
/**
|
||||||
* @brief First data element.
|
* @brief First data element.
|
||||||
*/
|
*/
|
||||||
flash_address_t next;
|
flash_offset_t next;
|
||||||
/**
|
/**
|
||||||
* @brief Header CRC.
|
* @brief Header CRC.
|
||||||
*/
|
*/
|
||||||
|
@ -176,7 +183,7 @@ typedef struct {
|
||||||
/**
|
/**
|
||||||
* @brief Address of the previous header or zero if none.
|
* @brief Address of the previous header or zero if none.
|
||||||
*/
|
*/
|
||||||
flash_address_t prev_header;
|
flash_offset_t prev_header;
|
||||||
} mfs_data_header_t;
|
} mfs_data_header_t;
|
||||||
|
|
||||||
#if (MFS_CFG_ID_CACHE_SIZE > 0) || defined(__DOXYGEN__)
|
#if (MFS_CFG_ID_CACHE_SIZE > 0) || defined(__DOXYGEN__)
|
||||||
|
@ -199,7 +206,7 @@ typedef struct mfs_cached_id {
|
||||||
/**
|
/**
|
||||||
* @brief Data address of the cached element.
|
* @brief Data address of the cached element.
|
||||||
*/
|
*/
|
||||||
flash_address_t addr;
|
flash_offset_t offset;
|
||||||
/**
|
/**
|
||||||
* @brief Data size of the cached element.
|
* @brief Data size of the cached element.
|
||||||
*/
|
*/
|
||||||
|
@ -272,11 +279,11 @@ typedef struct {
|
||||||
/**
|
/**
|
||||||
* @brief Pointer to the next free position in the current bank.
|
* @brief Pointer to the next free position in the current bank.
|
||||||
*/
|
*/
|
||||||
flash_address_t next_position;
|
flash_offset_t next_offset;
|
||||||
/**
|
/**
|
||||||
* @brief Pointer to the last header in the list or zero.
|
* @brief Pointer to the last header in the list or zero.
|
||||||
*/
|
*/
|
||||||
flash_address_t last_header;
|
flash_offset_t last_offset;
|
||||||
/**
|
/**
|
||||||
* @brief Used space in the current bank without considering erased records.
|
* @brief Used space in the current bank without considering erased records.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -72,4 +72,44 @@ flash_error_t flashWaitErase(BaseFlash *devp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the offset of a sector.
|
||||||
|
*/
|
||||||
|
flash_offset_t flashGetSectorOffset(BaseFlash *devp,
|
||||||
|
flash_sector_t sector) {
|
||||||
|
flash_offset_t offset;
|
||||||
|
const flash_descriptor_t *descriptor = flashGetDescriptor(devp);
|
||||||
|
|
||||||
|
osalDbgAssert(sector < descriptor->sectors_count, "invalid sector");
|
||||||
|
|
||||||
|
if (descriptor->sectors != NULL) {
|
||||||
|
offset = descriptor->sectors[sector].offset;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
offset = (flash_offset_t)sector * (flash_offset_t)descriptor->sectors_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the size of a sector.
|
||||||
|
*/
|
||||||
|
uint32_t flashGetSectorSize(BaseFlash *devp,
|
||||||
|
flash_sector_t sector) {
|
||||||
|
uint32_t size;
|
||||||
|
const flash_descriptor_t *descriptor = flashGetDescriptor(devp);
|
||||||
|
|
||||||
|
osalDbgAssert(sector < descriptor->sectors_count, "invalid sector");
|
||||||
|
|
||||||
|
if (descriptor->sectors != NULL) {
|
||||||
|
size = descriptor->sectors[sector].size;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
size = descriptor->sectors_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -78,9 +78,9 @@ typedef enum {
|
||||||
} flash_error_t;
|
} flash_error_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type of a flash address.
|
* @brief Type of a flash offset.
|
||||||
*/
|
*/
|
||||||
typedef uint32_t flash_address_t;
|
typedef uint32_t flash_offset_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type of a flash sector number.
|
* @brief Type of a flash sector number.
|
||||||
|
@ -92,13 +92,13 @@ typedef uint32_t flash_sector_t;
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/**
|
/**
|
||||||
* @brief Sector address.
|
* @brief Sector offset.
|
||||||
*/
|
*/
|
||||||
flash_address_t address;
|
flash_offset_t offset;
|
||||||
/**
|
/**
|
||||||
* @brief Sector size.
|
* @brief Sector size.
|
||||||
*/
|
*/
|
||||||
size_t size;
|
uint32_t size;
|
||||||
} flash_sector_descriptor_t;
|
} flash_sector_descriptor_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,7 +112,7 @@ typedef struct {
|
||||||
/**
|
/**
|
||||||
* @brief Size of write page.
|
* @brief Size of write page.
|
||||||
*/
|
*/
|
||||||
size_t page_size;
|
uint32_t page_size;
|
||||||
/**
|
/**
|
||||||
* @brief Number of sectors in the device.
|
* @brief Number of sectors in the device.
|
||||||
*/
|
*/
|
||||||
|
@ -125,15 +125,15 @@ typedef struct {
|
||||||
const flash_sector_descriptor_t *sectors;
|
const flash_sector_descriptor_t *sectors;
|
||||||
/**
|
/**
|
||||||
* @brief Size of sectors for devices with uniform sector size.
|
* @brief Size of sectors for devices with uniform sector size.
|
||||||
* @note If zero then the device has non uniform sectos described
|
* @note If zero then the device has non uniform sectors described
|
||||||
* by the @p sectors array.
|
* by the @p sectors array.
|
||||||
*/
|
*/
|
||||||
size_t sectors_size;
|
uint32_t sectors_size;
|
||||||
/**
|
/**
|
||||||
* @brief Flash address if memory mapped or zero.
|
* @brief Flash address if memory mapped or zero.
|
||||||
* @note Conventionally, non memory mapped devices have address zero.
|
* @note Conventionally, non memory mapped devices have address zero.
|
||||||
*/
|
*/
|
||||||
flash_address_t address;
|
flash_offset_t address;
|
||||||
} flash_descriptor_t;
|
} flash_descriptor_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,11 +144,11 @@ typedef struct {
|
||||||
/* Get flash device attributes.*/ \
|
/* Get flash device attributes.*/ \
|
||||||
const flash_descriptor_t * (*get_descriptor)(void *instance); \
|
const flash_descriptor_t * (*get_descriptor)(void *instance); \
|
||||||
/* Read operation.*/ \
|
/* Read operation.*/ \
|
||||||
flash_error_t (*read)(void *instance, flash_address_t addr, \
|
flash_error_t (*read)(void *instance, flash_offset_t offset, \
|
||||||
uint8_t *rp, size_t n); \
|
size_t n, uint8_t *rp); \
|
||||||
/* Program operation.*/ \
|
/* Program operation.*/ \
|
||||||
flash_error_t (*program)(void *instance, flash_address_t addr, \
|
flash_error_t (*program)(void *instance, flash_offset_t offset, \
|
||||||
const uint8_t *pp, size_t n); \
|
size_t n, const uint8_t *pp); \
|
||||||
/* Erase whole flash device.*/ \
|
/* Erase whole flash device.*/ \
|
||||||
flash_error_t (*start_erase_all)(void *instance); \
|
flash_error_t (*start_erase_all)(void *instance); \
|
||||||
/* Erase single sector.*/ \
|
/* Erase single sector.*/ \
|
||||||
|
@ -211,9 +211,9 @@ typedef struct {
|
||||||
* @brief Read operation.
|
* @brief Read operation.
|
||||||
*
|
*
|
||||||
* @param[in] ip pointer to a @p BaseFlash or derived class
|
* @param[in] ip pointer to a @p BaseFlash or derived class
|
||||||
* @param[in] addr flash address
|
* @param[in] offset flash offset
|
||||||
* @param[out] rp pointer to the data buffer
|
|
||||||
* @param[in] n number of bytes to be read
|
* @param[in] n number of bytes to be read
|
||||||
|
* @param[out] rp pointer to the data buffer
|
||||||
* @return An error code.
|
* @return An error code.
|
||||||
* @retval FLASH_NO_ERROR if there is no erase operation in progress.
|
* @retval FLASH_NO_ERROR if there is no erase operation in progress.
|
||||||
* @retval FLASH_BUSY_ERASING if there is an erase operation in progress.
|
* @retval FLASH_BUSY_ERASING if there is an erase operation in progress.
|
||||||
|
@ -221,16 +221,16 @@ typedef struct {
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
#define flashRead(ip, addr, rp, n) \
|
#define flashRead(ip, offset, n, rp) \
|
||||||
(ip)->vmt->read(ip, addr, rp, n)
|
(ip)->vmt->read(ip, offset, n, rp)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Program operation.
|
* @brief Program operation.
|
||||||
*
|
*
|
||||||
* @param[in] ip pointer to a @p BaseFlash or derived class
|
* @param[in] ip pointer to a @p BaseFlash or derived class
|
||||||
* @param[in] addr flash address
|
* @param[in] offset flash offset
|
||||||
* @param[in] wp pointer to the data buffer
|
|
||||||
* @param[in] n number of bytes to be programmed
|
* @param[in] n number of bytes to be programmed
|
||||||
|
* @param[in] wp pointer to the data buffer
|
||||||
* @return An error code.
|
* @return An error code.
|
||||||
* @retval FLASH_NO_ERROR if there is no erase operation in progress.
|
* @retval FLASH_NO_ERROR if there is no erase operation in progress.
|
||||||
* @retval FLASH_BUSY_ERASING if there is an erase operation in progress.
|
* @retval FLASH_BUSY_ERASING if there is an erase operation in progress.
|
||||||
|
@ -238,8 +238,8 @@ typedef struct {
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
#define flashProgram(ip, addr, pp, n) \
|
#define flashProgram(ip, offset, n, pp) \
|
||||||
(ip)->vmt->program(ip, addr, pp, n)
|
(ip)->vmt->program(ip, offset, n, pp)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Starts a whole-device erase operation.
|
* @brief Starts a whole-device erase operation.
|
||||||
|
@ -308,6 +308,8 @@ typedef struct {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
flash_error_t flashWaitErase(BaseFlash *devp);
|
flash_error_t flashWaitErase(BaseFlash *devp);
|
||||||
|
flash_offset_t flashGetSectorOffset(BaseFlash *devp, flash_sector_t sector);
|
||||||
|
uint32_t flashGetSectorSize(BaseFlash *devp, flash_sector_t sector);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -157,7 +157,7 @@ void jesd216_cmd_send(BUSDriver *busp,
|
||||||
|
|
||||||
void jesd216_cmd_addr(BUSDriver *busp,
|
void jesd216_cmd_addr(BUSDriver *busp,
|
||||||
uint32_t cmd,
|
uint32_t cmd,
|
||||||
flash_address_t addr) {
|
flash_offset_t offset) {
|
||||||
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
|
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
|
||||||
qspi_command_t mode;
|
qspi_command_t mode;
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ void jesd216_cmd_addr(BUSDriver *busp,
|
||||||
QSPI_CFG_ADDR_SIZE_24;
|
QSPI_CFG_ADDR_SIZE_24;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
mode.addr = addr;
|
mode.addr = offset;
|
||||||
mode.alt = 0U;
|
mode.alt = 0U;
|
||||||
qspiCommand(busp, &mode);
|
qspiCommand(busp, &mode);
|
||||||
#else
|
#else
|
||||||
|
@ -194,7 +194,7 @@ void jesd216_cmd_addr(BUSDriver *busp,
|
||||||
|
|
||||||
void jesd216_cmd_addr_send(BUSDriver *busp,
|
void jesd216_cmd_addr_send(BUSDriver *busp,
|
||||||
uint32_t cmd,
|
uint32_t cmd,
|
||||||
flash_address_t addr,
|
flash_offset_t offset,
|
||||||
size_t n,
|
size_t n,
|
||||||
const uint8_t *p) {
|
const uint8_t *p) {
|
||||||
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
|
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
|
||||||
|
@ -223,7 +223,7 @@ void jesd216_cmd_addr_send(BUSDriver *busp,
|
||||||
mode .cfg |= QSPI_CFG_ADDR_SIZE_32;
|
mode .cfg |= QSPI_CFG_ADDR_SIZE_32;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode.addr = addr;
|
mode.addr = offset;
|
||||||
mode.alt = 0U;
|
mode.alt = 0U;
|
||||||
qspiSend(busp, &mode, n, p);
|
qspiSend(busp, &mode, n, p);
|
||||||
#else
|
#else
|
||||||
|
@ -242,7 +242,7 @@ void jesd216_cmd_addr_send(BUSDriver *busp,
|
||||||
|
|
||||||
void jesd216_cmd_addr_receive(BUSDriver *busp,
|
void jesd216_cmd_addr_receive(BUSDriver *busp,
|
||||||
uint32_t cmd,
|
uint32_t cmd,
|
||||||
flash_address_t addr,
|
flash_offset_t offset,
|
||||||
size_t n,
|
size_t n,
|
||||||
uint8_t *p) {
|
uint8_t *p) {
|
||||||
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
|
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
|
||||||
|
@ -272,7 +272,7 @@ void jesd216_cmd_addr_receive(BUSDriver *busp,
|
||||||
mode .cfg |= QSPI_CFG_ADDR_SIZE_32;
|
mode .cfg |= QSPI_CFG_ADDR_SIZE_32;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode.addr = addr;
|
mode.addr = offset;
|
||||||
mode.alt = 0U;
|
mode.alt = 0U;
|
||||||
qspiReceive(busp, &mode, n, p);
|
qspiReceive(busp, &mode, n, p);
|
||||||
#else
|
#else
|
||||||
|
@ -292,7 +292,7 @@ void jesd216_cmd_addr_receive(BUSDriver *busp,
|
||||||
#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__)
|
#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__)
|
||||||
void jesd216_cmd_addr_dummy_receive(BUSDriver *busp,
|
void jesd216_cmd_addr_dummy_receive(BUSDriver *busp,
|
||||||
uint32_t cmd,
|
uint32_t cmd,
|
||||||
flash_address_t addr,
|
flash_offset_t offset,
|
||||||
uint8_t dummy,
|
uint8_t dummy,
|
||||||
size_t n,
|
size_t n,
|
||||||
uint8_t *p) {
|
uint8_t *p) {
|
||||||
|
@ -324,7 +324,7 @@ void jesd216_cmd_addr_dummy_receive(BUSDriver *busp,
|
||||||
mode .cfg |= QSPI_CFG_ADDR_SIZE_32;
|
mode .cfg |= QSPI_CFG_ADDR_SIZE_32;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode.addr = addr;
|
mode.addr = offset;
|
||||||
mode.alt = 0U;
|
mode.alt = 0U;
|
||||||
qspiReceive(busp, &mode, n, p);
|
qspiReceive(busp, &mode, n, p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,9 +141,10 @@
|
||||||
*/
|
*/
|
||||||
#define _jesd216_flash_methods_alone \
|
#define _jesd216_flash_methods_alone \
|
||||||
/* Read SFDP.*/ \
|
/* Read SFDP.*/ \
|
||||||
flash_error_t (*read_sfdp)(void *instance, uint8_t *rp, \
|
flash_error_t (*read_sfdp)(void *instance, \
|
||||||
flash_address_t addr, \
|
flash_offset_t offset, \
|
||||||
size_t n);
|
size_t n, \
|
||||||
|
uint8_t *rp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief @p JESD215Flash specific methods with inherited ones.
|
* @brief @p JESD215Flash specific methods with inherited ones.
|
||||||
|
@ -198,14 +199,14 @@ extern "C" {
|
||||||
size_t n, uint8_t *p);
|
size_t n, uint8_t *p);
|
||||||
void jesd216_cmd_send(BUSDriver *busp, uint32_t cmd,
|
void jesd216_cmd_send(BUSDriver *busp, uint32_t cmd,
|
||||||
size_t n, const uint8_t *p);
|
size_t n, const uint8_t *p);
|
||||||
void jesd216_cmd_addr(BUSDriver *busp, uint32_t cmd, flash_address_t addr);
|
void jesd216_cmd_addr(BUSDriver *busp, uint32_t cmd, flash_offset_t offset);
|
||||||
void jesd216_cmd_addr_send(BUSDriver *busp, uint32_t cmd,
|
void jesd216_cmd_addr_send(BUSDriver *busp, uint32_t cmd,
|
||||||
flash_address_t addr, size_t n, const uint8_t *p);
|
flash_offset_t offset, size_t n, const uint8_t *p);
|
||||||
void jesd216_cmd_addr_receive(BUSDriver *busp, uint32_t cmd,
|
void jesd216_cmd_addr_receive(BUSDriver *busp, uint32_t cmd,
|
||||||
flash_address_t addr, size_t n, uint8_t *p);
|
flash_offset_t offset, size_t n, uint8_t *p);
|
||||||
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
|
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
|
||||||
void jesd216_cmd_addr_dummy_receive(BUSDriver *busp, uint32_t cmd,
|
void jesd216_cmd_addr_dummy_receive(BUSDriver *busp, uint32_t cmd,
|
||||||
flash_address_t addr, uint8_t dummy,
|
flash_offset_t offset, uint8_t dummy,
|
||||||
size_t n, uint8_t *p);
|
size_t n, uint8_t *p);
|
||||||
#endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */
|
#endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */
|
||||||
#if JESD216_SHARED_BUS == TRUE
|
#if JESD216_SHARED_BUS == TRUE
|
||||||
|
|
|
@ -110,7 +110,7 @@ int main(void) {
|
||||||
m25qStart(&m25q, &m25qcfg1);
|
m25qStart(&m25q, &m25qcfg1);
|
||||||
|
|
||||||
/* Reading.*/
|
/* Reading.*/
|
||||||
err = flashRead(&m25q, 0, buffer, 128);
|
err = flashRead(&m25q, 0, 128, buffer);
|
||||||
if (err != FLASH_NO_ERROR)
|
if (err != FLASH_NO_ERROR)
|
||||||
chSysHalt("read error");
|
chSysHalt("read error");
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ int main(void) {
|
||||||
chSysHalt("verify erase error");
|
chSysHalt("verify erase error");
|
||||||
|
|
||||||
/* Programming a pattern.*/
|
/* Programming a pattern.*/
|
||||||
err = flashProgram(&m25q, 0, pattern, 128);
|
err = flashProgram(&m25q, 0, 128, pattern);
|
||||||
if (err != FLASH_NO_ERROR)
|
if (err != FLASH_NO_ERROR)
|
||||||
chSysHalt("program error");
|
chSysHalt("program error");
|
||||||
|
|
||||||
|
@ -143,13 +143,13 @@ int main(void) {
|
||||||
|
|
||||||
/* Reading it back.*/
|
/* Reading it back.*/
|
||||||
memset(buffer, 0, 128);
|
memset(buffer, 0, 128);
|
||||||
err = flashRead(&m25q, 16, buffer, 128);
|
err = flashRead(&m25q, 16, 128, buffer);
|
||||||
if (err != FLASH_NO_ERROR)
|
if (err != FLASH_NO_ERROR)
|
||||||
chSysHalt("read error");
|
chSysHalt("read error");
|
||||||
|
|
||||||
/* Reading it back.*/
|
/* Reading it back.*/
|
||||||
memset(buffer, 0, 128);
|
memset(buffer, 0, 128);
|
||||||
err = flashRead(&m25q, 0, buffer, 128);
|
err = flashRead(&m25q, 0, 128, buffer);
|
||||||
if (err != FLASH_NO_ERROR)
|
if (err != FLASH_NO_ERROR)
|
||||||
chSysHalt("read error");
|
chSysHalt("read error");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue