diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/flash_api.c b/targets/TARGET_Cypress/TARGET_PSOC6/flash_api.c index 5d7cca066c..8bca121bf9 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/flash_api.c +++ b/targets/TARGET_Cypress/TARGET_PSOC6/flash_api.c @@ -47,10 +47,27 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, { (void)(obj); int32_t status = 0; - if (Cy_Flash_ProgramRow(address, (const uint32_t *)data) != CY_FLASH_DRV_SUCCESS) { - status = -1; + static uint8_t prog_buf[CY_FLASH_SIZEOF_ROW]; + while (size) { + uint32_t offset = address % CY_FLASH_SIZEOF_ROW; + uint32_t chunk_size; + if (offset + size > CY_FLASH_SIZEOF_ROW) { + chunk_size = CY_FLASH_SIZEOF_ROW - offset; + } else { + chunk_size = size; + } + uint32_t row_address = address / CY_FLASH_SIZEOF_ROW * CY_FLASH_SIZEOF_ROW; + memcpy(prog_buf, (const void *)row_address, CY_FLASH_SIZEOF_ROW); + memcpy(prog_buf + offset, data, chunk_size); + + if (Cy_Flash_ProgramRow(row_address, (const uint32_t *)prog_buf) != CY_FLASH_DRV_SUCCESS) { + status = -1; + } + address += chunk_size; + size -= chunk_size; } + Cy_SysLib_ClearFlashCacheAndBuffer(); return status; } @@ -67,7 +84,7 @@ uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) uint32_t flash_get_page_size(const flash_t *obj) { (void)(obj); - return CY_FLASH_SIZEOF_ROW; + return CY_FLASH_EFFECTIVE_PAGE_SIZE; } uint32_t flash_get_start_address(const flash_t *obj) diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/psoc6pdl/drivers/include/cy_flash.h b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6pdl/drivers/include/cy_flash.h index d6388393e5..45a01744f0 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/psoc6pdl/drivers/include/cy_flash.h +++ b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6pdl/drivers/include/cy_flash.h @@ -377,6 +377,8 @@ extern "C" { /** Flash row size */ #define CY_FLASH_SIZEOF_ROW (CPUSS_FLASHC_PA_SIZE * 4u) +/** Flash effective page size */ +#define CY_FLASH_EFFECTIVE_PAGE_SIZE 32 /** Long words flash row size */ #define CY_FLASH_SIZEOF_ROW_LONG_UNITS (CY_FLASH_SIZEOF_ROW / sizeof(uint32_t)) diff --git a/targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/device/drivers/peripheral/flash/cy_flash.h b/targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/device/drivers/peripheral/flash/cy_flash.h index cd4255a6c1..07b0b7a82f 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/device/drivers/peripheral/flash/cy_flash.h +++ b/targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/device/drivers/peripheral/flash/cy_flash.h @@ -332,6 +332,8 @@ extern "C" { /** Flash row size */ #define CY_FLASH_SIZEOF_ROW (CPUSS_FLASHC_PA_SIZE * 4u) +/** Flash effective page size */ +#define CY_FLASH_EFFECTIVE_PAGE_SIZE 32 /** Number of flash rows */ #define CY_FLASH_NUMBER_ROWS (CY_FLASH_SIZE / CY_FLASH_SIZEOF_ROW) /** Long words flash row size */ diff --git a/targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/flash_api.c b/targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/flash_api.c index 7141757bf0..b76ca6c447 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/flash_api.c +++ b/targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/flash_api.c @@ -47,10 +47,27 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, { (void)(obj); int32_t status = 0; - if (Cy_Flash_ProgramRow(address, (const uint32_t *)data) != CY_FLASH_DRV_SUCCESS) { - status = -1; + static uint8_t prog_buf[CY_FLASH_SIZEOF_ROW]; + while (size) { + uint32_t offset = address % CY_FLASH_SIZEOF_ROW; + uint32_t chunk_size; + if (offset + size > CY_FLASH_SIZEOF_ROW) { + chunk_size = CY_FLASH_SIZEOF_ROW - offset; + } else { + chunk_size = size; + } + uint32_t row_address = address / CY_FLASH_SIZEOF_ROW * CY_FLASH_SIZEOF_ROW; + memcpy(prog_buf, (const void *)row_address, CY_FLASH_SIZEOF_ROW); + memcpy(prog_buf + offset, data, chunk_size); + + if (Cy_Flash_ProgramRow(row_address, (const uint32_t *)prog_buf) != CY_FLASH_DRV_SUCCESS) { + status = -1; + } + address += chunk_size; + size -= chunk_size; } + Cy_SysLib_ClearFlashCacheAndBuffer(); return status; } @@ -67,7 +84,7 @@ uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) uint32_t flash_get_page_size(const flash_t *obj) { (void)(obj); - return CY_FLASH_SIZEOF_ROW; + return CY_FLASH_EFFECTIVE_PAGE_SIZE; } uint32_t flash_get_start_address(const flash_t *obj)