- /*
- * Kinetis uses different terms for the granularity of
- * sector writes, e.g. "phrase" or "128 bits". We use
- * the generic term "chunk". The largest possible
- * Kinetis "chunk" is 16 bytes (128 bits).
- */
- unsigned prog_section_chunk_bytes = kinfo->sector_size >> 8;
- unsigned prog_size_bytes = kinfo->max_flash_prog_size;
- for (i = 0; i < count; i += prog_size_bytes) {
- uint8_t residual_buffer[16];
- uint8_t ftfx_fstat;
- uint32_t section_count = prog_size_bytes / prog_section_chunk_bytes;
- uint32_t residual_wc = 0;
-
- /*
- * Assume the word count covers an entire
- * sector.
- */
- wc = prog_size_bytes / 4;
-
- /*
- * If bytes to be programmed are less than the
- * full sector, then determine the number of
- * full-words to program, and put together the
- * residual buffer so that a full "section"
- * may always be programmed.
- */
- if ((count - i) < prog_size_bytes) {
- /* number of bytes to program beyond full section */
- unsigned residual_bc = (count-i) % prog_section_chunk_bytes;
-
- /* number of complete words to copy directly from buffer */
- wc = (count - i - residual_bc) / 4;
-
- /* number of total sections to write, including residual */
- section_count = DIV_ROUND_UP((count-i), prog_section_chunk_bytes);
-
- /* any residual bytes delivers a whole residual section */
- residual_wc = (residual_bc ? prog_section_chunk_bytes : 0)/4;
-
- /* clear residual buffer then populate residual bytes */
- (void) memset(residual_buffer, 0xff, prog_section_chunk_bytes);
- (void) memcpy(residual_buffer, &buffer[i+4*wc], residual_bc);
- }
-
- LOG_DEBUG("write section @ %08" PRIX32 " with length %" PRIu32 " bytes",
- offset + i, (uint32_t)wc*4);
-
- /* write data to flexram as whole-words */
- result = target_write_memory(bank->target, FLEXRAM, 4, wc,
- buffer + i);
-
- if (result != ERROR_OK) {
- LOG_ERROR("target_write_memory failed");
- return result;
- }
-
- /* write the residual words to the flexram */
- if (residual_wc) {
- result = target_write_memory(bank->target,
- FLEXRAM+4*wc,
- 4, residual_wc,
- residual_buffer);
-
- if (result != ERROR_OK) {
- LOG_ERROR("target_write_memory failed");
- return result;
- }
- }
-
- /* execute section-write command */
- result = kinetis_ftfx_command(bank->target, FTFx_CMD_SECTWRITE, kinfo->prog_base + offset + i,
- section_count>>8, section_count, 0, 0,
- 0, 0, 0, 0, &ftfx_fstat);
-
- if (result != ERROR_OK)
- return ERROR_FLASH_OPERATION_FAILED;
- }