diff --git a/os/ex/Micron/m25q.c b/os/ex/Micron/m25q.c index c109a61e4..3dbb3df62 100644 --- a/os/ex/Micron/m25q.c +++ b/os/ex/Micron/m25q.c @@ -54,17 +54,17 @@ /*===========================================================================*/ static const flash_descriptor_t *m25q_get_descriptor(void *instance); -static flash_error_t m25q_read(void *instance, flash_address_t addr, - uint8_t *rp, size_t n); -static flash_error_t m25q_program(void *instance, flash_address_t addr, - const uint8_t *pp, size_t n); +static flash_error_t m25q_read(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp); +static flash_error_t m25q_program(void *instance, flash_offset_t offset, + size_t n, const uint8_t *pp); static flash_error_t m25q_start_erase_all(void *instance); static flash_error_t m25q_start_erase_sector(void *instance, flash_sector_t sector); 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_read_sfdp(void *instance, uint8_t *rp, - flash_address_t addr, size_t n); +static flash_error_t m25q_read_sfdp(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp); /** * @brief Virtual methods table. @@ -319,13 +319,13 @@ static const flash_descriptor_t *m25q_get_descriptor(void *instance) { return &m25q_descriptor; } -static flash_error_t m25q_read(void *instance, flash_address_t addr, - uint8_t *rp, size_t n) { +static flash_error_t m25q_read(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp) { M25QDriver *devp = (M25QDriver *)instance; osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U)); - osalDbgCheck((size_t)addr + n <= (size_t)m25q_descriptor.sectors_count * - (size_t)m25q_descriptor.sectors_size); + osalDbgCheck((size_t)offset + n <= (size_t)m25q_descriptor.sectors_count * + (size_t)m25q_descriptor.sectors_size); osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), "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 /* Fast read command in QSPI mode.*/ 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 /* Normal read command in SPI mode.*/ jesd216_cmd_addr_receive(devp->config->busp, M25Q_CMD_READ, - addr, n, rp); + offset, n, rp); #endif /* Ready state again.*/ @@ -358,13 +358,13 @@ static flash_error_t m25q_read(void *instance, flash_address_t addr, return FLASH_NO_ERROR; } -static flash_error_t m25q_program(void *instance, flash_address_t addr, - const uint8_t *pp, size_t n) { +static flash_error_t m25q_program(void *instance, flash_offset_t offset, + size_t n, const uint8_t *pp) { M25QDriver *devp = (M25QDriver *)instance; osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U)); - osalDbgCheck((size_t)addr + n <= (size_t)m25q_descriptor.sectors_count * - (size_t)m25q_descriptor.sectors_size); + osalDbgCheck((size_t)offset + n <= (size_t)m25q_descriptor.sectors_count * + (size_t)m25q_descriptor.sectors_size); osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), "invalid state"); @@ -383,7 +383,7 @@ static flash_error_t m25q_program(void *instance, flash_address_t addr, flash_error_t err; /* 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) { 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); /* 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); /* Wait for status and check errors.*/ @@ -406,9 +406,9 @@ static flash_error_t m25q_program(void *instance, flash_address_t addr, } /* Next page.*/ - addr += chunk; - pp += chunk; - n -= chunk; + offset += chunk; + pp += chunk; + n -= chunk; } /* 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, flash_sector_t sector) { 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(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); /* 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.*/ jesd216_bus_release(devp->config->busp); @@ -485,7 +485,7 @@ static flash_error_t m25q_verify_erase(void *instance, flash_sector_t sector) { M25QDriver *devp = (M25QDriver *)instance; uint8_t cmpbuf[M25Q_COMPARE_BUFFER_SIZE]; - flash_address_t addr; + flash_offset_t offset; size_t n; osalDbgCheck(instance != NULL); @@ -504,19 +504,19 @@ static flash_error_t m25q_verify_erase(void *instance, devp->state = FLASH_READ; /* Read command.*/ - addr = (flash_address_t)(sector * SECTOR_SIZE); + offset = (flash_offset_t)(sector * SECTOR_SIZE); n = SECTOR_SIZE; while (n > 0U) { uint8_t *p; #if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI 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); #else /* Normal read command in SPI mode.*/ jesd216_cmd_addr_receive(devp->config->busp, M25Q_CMD_READ, - addr, sizeof cmpbuf, cmpbuf); + offset, sizeof cmpbuf, cmpbuf); #endif /* 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; } @@ -600,13 +600,12 @@ static flash_error_t m25q_query_erase(void *instance, uint32_t *msec) { return FLASH_NO_ERROR; } -static flash_error_t m25q_read_sfdp(void *instance, uint8_t *rp, - flash_address_t addr, - size_t n) { +static flash_error_t m25q_read_sfdp(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp) { (void)instance; (void)rp; - (void)addr; + (void)offset; (void)n; return FLASH_NO_ERROR; diff --git a/os/ex/subsystems/mfs/mfs.c b/os/ex/subsystems/mfs/mfs.c index d138852e9..58ddcbe81 100644 --- a/os/ex/subsystems/mfs/mfs.c +++ b/os/ex/subsystems/mfs/mfs.c @@ -139,6 +139,36 @@ void mfs_cache_erase_id(MFSDriver *devp, uint32_t id) { } #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. * @@ -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, mfs_bank_t bank, uint32_t cnt) { + flash_sector_t sector; 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.counter = cnt; header.next = sizeof (mfs_bank_header_t); header.crc = crc16(0U, (const uint8_t *)&header, sizeof (uint32_t) * 4); - (void)devp; - (void)bank; - (void)cnt; - - return MFS_NO_ERROR; + return mfs_flash_write(devp, + flashGetSectorOffset(devp->config->flashp, sector), + sizeof (mfs_bank_header_t), + (const uint8_t *)&header); } /** @@ -549,7 +586,7 @@ mfs_error_t mfsMount(MFSDriver *devp) { unsigned i; /* 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; err = mfs_try_mount(devp); diff --git a/os/ex/subsystems/mfs/mfs.h b/os/ex/subsystems/mfs/mfs.h index 28b8436a6..ec5719738 100644 --- a/os/ex/subsystems/mfs/mfs.h +++ b/os/ex/subsystems/mfs/mfs.h @@ -57,8 +57,15 @@ /** * @brief Maximum number of repair attempts on partition mount. */ -#if !defined(MFS_MAX_REPAIR_ATTEMPTS) || defined(__DOXIGEN__) -#define MFS_MAX_REPAIR_ATTEMPTS 3 +#if !defined(MFS_CFG_MAX_REPAIR_ATTEMPTS) || defined(__DOXIGEN__) +#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 /** @} */ @@ -70,7 +77,7 @@ #error "invalid MFS_CFG_ID_CACHE_SIZE value" #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" #endif @@ -145,7 +152,7 @@ typedef struct { /** * @brief First data element. */ - flash_address_t next; + flash_offset_t next; /** * @brief Header CRC. */ @@ -176,7 +183,7 @@ typedef struct { /** * @brief Address of the previous header or zero if none. */ - flash_address_t prev_header; + flash_offset_t prev_header; } mfs_data_header_t; #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. */ - flash_address_t addr; + flash_offset_t offset; /** * @brief Data size of the cached element. */ @@ -272,11 +279,11 @@ typedef struct { /** * @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. */ - flash_address_t last_header; + flash_offset_t last_offset; /** * @brief Used space in the current bank without considering erased records. */ diff --git a/os/hal/lib/peripherals/flash/hal_flash.c b/os/hal/lib/peripherals/flash/hal_flash.c index b65ca3768..439a9c6aa 100644 --- a/os/hal/lib/peripherals/flash/hal_flash.c +++ b/os/hal/lib/peripherals/flash/hal_flash.c @@ -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; +} + /** @} */ diff --git a/os/hal/lib/peripherals/flash/hal_flash.h b/os/hal/lib/peripherals/flash/hal_flash.h index b15c18b25..f7066e2ef 100644 --- a/os/hal/lib/peripherals/flash/hal_flash.h +++ b/os/hal/lib/peripherals/flash/hal_flash.h @@ -78,9 +78,9 @@ typedef enum { } 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. @@ -92,13 +92,13 @@ typedef uint32_t flash_sector_t; */ typedef struct { /** - * @brief Sector address. + * @brief Sector offset. */ - flash_address_t address; + flash_offset_t offset; /** * @brief Sector size. */ - size_t size; + uint32_t size; } flash_sector_descriptor_t; /** @@ -112,7 +112,7 @@ typedef struct { /** * @brief Size of write page. */ - size_t page_size; + uint32_t page_size; /** * @brief Number of sectors in the device. */ @@ -125,15 +125,15 @@ typedef struct { const flash_sector_descriptor_t *sectors; /** * @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. */ - size_t sectors_size; + uint32_t sectors_size; /** * @brief Flash address if memory mapped or zero. * @note Conventionally, non memory mapped devices have address zero. */ - flash_address_t address; + flash_offset_t address; } flash_descriptor_t; /** @@ -144,11 +144,11 @@ typedef struct { /* Get flash device attributes.*/ \ const flash_descriptor_t * (*get_descriptor)(void *instance); \ /* Read operation.*/ \ - flash_error_t (*read)(void *instance, flash_address_t addr, \ - uint8_t *rp, size_t n); \ + flash_error_t (*read)(void *instance, flash_offset_t offset, \ + size_t n, uint8_t *rp); \ /* Program operation.*/ \ - flash_error_t (*program)(void *instance, flash_address_t addr, \ - const uint8_t *pp, size_t n); \ + flash_error_t (*program)(void *instance, flash_offset_t offset, \ + size_t n, const uint8_t *pp); \ /* Erase whole flash device.*/ \ flash_error_t (*start_erase_all)(void *instance); \ /* Erase single sector.*/ \ @@ -211,9 +211,9 @@ typedef struct { * @brief Read operation. * * @param[in] ip pointer to a @p BaseFlash or derived class - * @param[in] addr flash address - * @param[out] rp pointer to the data buffer + * @param[in] offset flash offset * @param[in] n number of bytes to be read + * @param[out] rp pointer to the data buffer * @return An error code. * @retval FLASH_NO_ERROR if there is no erase operation in progress. * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. @@ -221,16 +221,16 @@ typedef struct { * * @api */ -#define flashRead(ip, addr, rp, n) \ - (ip)->vmt->read(ip, addr, rp, n) +#define flashRead(ip, offset, n, rp) \ + (ip)->vmt->read(ip, offset, n, rp) /** * @brief Program operation. * * @param[in] ip pointer to a @p BaseFlash or derived class - * @param[in] addr flash address - * @param[in] wp pointer to the data buffer + * @param[in] offset flash offset * @param[in] n number of bytes to be programmed + * @param[in] wp pointer to the data buffer * @return An error code. * @retval FLASH_NO_ERROR if there is no erase operation in progress. * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. @@ -238,8 +238,8 @@ typedef struct { * * @api */ -#define flashProgram(ip, addr, pp, n) \ - (ip)->vmt->program(ip, addr, pp, n) +#define flashProgram(ip, offset, n, pp) \ + (ip)->vmt->program(ip, offset, n, pp) /** * @brief Starts a whole-device erase operation. @@ -308,6 +308,8 @@ typedef struct { extern "C" { #endif 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 } #endif diff --git a/os/hal/lib/peripherals/flash/hal_jesd216_flash.c b/os/hal/lib/peripherals/flash/hal_jesd216_flash.c index cd422f53b..9cc986c04 100644 --- a/os/hal/lib/peripherals/flash/hal_jesd216_flash.c +++ b/os/hal/lib/peripherals/flash/hal_jesd216_flash.c @@ -157,7 +157,7 @@ void jesd216_cmd_send(BUSDriver *busp, void jesd216_cmd_addr(BUSDriver *busp, uint32_t cmd, - flash_address_t addr) { + flash_offset_t offset) { #if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI qspi_command_t mode; @@ -176,7 +176,7 @@ void jesd216_cmd_addr(BUSDriver *busp, QSPI_CFG_ADDR_SIZE_24; #endif - mode.addr = addr; + mode.addr = offset; mode.alt = 0U; qspiCommand(busp, &mode); #else @@ -194,7 +194,7 @@ void jesd216_cmd_addr(BUSDriver *busp, void jesd216_cmd_addr_send(BUSDriver *busp, uint32_t cmd, - flash_address_t addr, + flash_offset_t offset, size_t n, const uint8_t *p) { #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.addr = addr; + mode.addr = offset; mode.alt = 0U; qspiSend(busp, &mode, n, p); #else @@ -242,7 +242,7 @@ void jesd216_cmd_addr_send(BUSDriver *busp, void jesd216_cmd_addr_receive(BUSDriver *busp, uint32_t cmd, - flash_address_t addr, + flash_offset_t offset, size_t n, uint8_t *p) { #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.addr = addr; + mode.addr = offset; mode.alt = 0U; qspiReceive(busp, &mode, n, p); #else @@ -292,7 +292,7 @@ void jesd216_cmd_addr_receive(BUSDriver *busp, #if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__) void jesd216_cmd_addr_dummy_receive(BUSDriver *busp, uint32_t cmd, - flash_address_t addr, + flash_offset_t offset, uint8_t dummy, size_t n, uint8_t *p) { @@ -324,7 +324,7 @@ void jesd216_cmd_addr_dummy_receive(BUSDriver *busp, mode .cfg |= QSPI_CFG_ADDR_SIZE_32; } - mode.addr = addr; + mode.addr = offset; mode.alt = 0U; qspiReceive(busp, &mode, n, p); } diff --git a/os/hal/lib/peripherals/flash/hal_jesd216_flash.h b/os/hal/lib/peripherals/flash/hal_jesd216_flash.h index 1cff3cc32..371892ec1 100644 --- a/os/hal/lib/peripherals/flash/hal_jesd216_flash.h +++ b/os/hal/lib/peripherals/flash/hal_jesd216_flash.h @@ -141,9 +141,10 @@ */ #define _jesd216_flash_methods_alone \ /* Read SFDP.*/ \ - flash_error_t (*read_sfdp)(void *instance, uint8_t *rp, \ - flash_address_t addr, \ - size_t n); + flash_error_t (*read_sfdp)(void *instance, \ + flash_offset_t offset, \ + size_t n, \ + uint8_t *rp); /** * @brief @p JESD215Flash specific methods with inherited ones. @@ -198,14 +199,14 @@ extern "C" { size_t n, uint8_t *p); void jesd216_cmd_send(BUSDriver *busp, uint32_t cmd, 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, - 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, - 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 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); #endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ #if JESD216_SHARED_BUS == TRUE diff --git a/testhal/STM32/STM32L4xx/QSPI-N25Q128/main.c b/testhal/STM32/STM32L4xx/QSPI-N25Q128/main.c index ffac546d2..623916957 100644 --- a/testhal/STM32/STM32L4xx/QSPI-N25Q128/main.c +++ b/testhal/STM32/STM32L4xx/QSPI-N25Q128/main.c @@ -110,7 +110,7 @@ int main(void) { m25qStart(&m25q, &m25qcfg1); /* Reading.*/ - err = flashRead(&m25q, 0, buffer, 128); + err = flashRead(&m25q, 0, 128, buffer); if (err != FLASH_NO_ERROR) chSysHalt("read error"); @@ -126,7 +126,7 @@ int main(void) { chSysHalt("verify erase error"); /* Programming a pattern.*/ - err = flashProgram(&m25q, 0, pattern, 128); + err = flashProgram(&m25q, 0, 128, pattern); if (err != FLASH_NO_ERROR) chSysHalt("program error"); @@ -143,13 +143,13 @@ int main(void) { /* Reading it back.*/ memset(buffer, 0, 128); - err = flashRead(&m25q, 16, buffer, 128); + err = flashRead(&m25q, 16, 128, buffer); if (err != FLASH_NO_ERROR) chSysHalt("read error"); /* Reading it back.*/ memset(buffer, 0, 128); - err = flashRead(&m25q, 0, buffer, 128); + err = flashRead(&m25q, 0, 128, buffer); if (err != FLASH_NO_ERROR) chSysHalt("read error");