Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.

Upstream: https://github.com/ARMmbed/DAPLink

Committer:
Pawel Zarembski
Date:
Tue Apr 07 12:55:42 2020 +0200
Revision:
0:01f31e923fe2
hani: DAPLink with reset workaround

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pawel Zarembski 0:01f31e923fe2 1 /**
Pawel Zarembski 0:01f31e923fe2 2 * @file target_flash.c
Pawel Zarembski 0:01f31e923fe2 3 * @brief Implementation of target_flash.h
Pawel Zarembski 0:01f31e923fe2 4 *
Pawel Zarembski 0:01f31e923fe2 5 * DAPLink Interface Firmware
Pawel Zarembski 0:01f31e923fe2 6 * Copyright (c) 2009-2019, ARM Limited, All Rights Reserved
Pawel Zarembski 0:01f31e923fe2 7 * Copyright 2019, Cypress Semiconductor Corporation
Pawel Zarembski 0:01f31e923fe2 8 * or a subsidiary of Cypress Semiconductor Corporation.
Pawel Zarembski 0:01f31e923fe2 9 * SPDX-License-Identifier: Apache-2.0
Pawel Zarembski 0:01f31e923fe2 10 *
Pawel Zarembski 0:01f31e923fe2 11 * Licensed under the Apache License, Version 2.0 (the "License"); you may
Pawel Zarembski 0:01f31e923fe2 12 * not use this file except in compliance with the License.
Pawel Zarembski 0:01f31e923fe2 13 * You may obtain a copy of the License at
Pawel Zarembski 0:01f31e923fe2 14 *
Pawel Zarembski 0:01f31e923fe2 15 * http://www.apache.org/licenses/LICENSE-2.0
Pawel Zarembski 0:01f31e923fe2 16 *
Pawel Zarembski 0:01f31e923fe2 17 * Unless required by applicable law or agreed to in writing, software
Pawel Zarembski 0:01f31e923fe2 18 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
Pawel Zarembski 0:01f31e923fe2 19 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Pawel Zarembski 0:01f31e923fe2 20 * See the License for the specific language governing permissions and
Pawel Zarembski 0:01f31e923fe2 21 * limitations under the License.
Pawel Zarembski 0:01f31e923fe2 22 */
Pawel Zarembski 0:01f31e923fe2 23 #ifdef DRAG_N_DROP_SUPPORT
Pawel Zarembski 0:01f31e923fe2 24 #include <string.h>
Pawel Zarembski 0:01f31e923fe2 25
Pawel Zarembski 0:01f31e923fe2 26 #include "target_config.h"
Pawel Zarembski 0:01f31e923fe2 27 #include "gpio.h"
Pawel Zarembski 0:01f31e923fe2 28 #include "target_config.h"
Pawel Zarembski 0:01f31e923fe2 29 #include "intelhex.h"
Pawel Zarembski 0:01f31e923fe2 30 #include "swd_host.h"
Pawel Zarembski 0:01f31e923fe2 31 #include "flash_intf.h"
Pawel Zarembski 0:01f31e923fe2 32 #include "util.h"
Pawel Zarembski 0:01f31e923fe2 33 #include "settings.h"
Pawel Zarembski 0:01f31e923fe2 34 #include "target_family.h"
Pawel Zarembski 0:01f31e923fe2 35 #include "target_board.h"
Pawel Zarembski 0:01f31e923fe2 36
Pawel Zarembski 0:01f31e923fe2 37 #define DEFAULT_PROGRAM_PAGE_MIN_SIZE (256u)
Pawel Zarembski 0:01f31e923fe2 38
Pawel Zarembski 0:01f31e923fe2 39 typedef enum {
Pawel Zarembski 0:01f31e923fe2 40 STATE_CLOSED,
Pawel Zarembski 0:01f31e923fe2 41 STATE_OPEN,
Pawel Zarembski 0:01f31e923fe2 42 STATE_ERROR
Pawel Zarembski 0:01f31e923fe2 43 } state_t;
Pawel Zarembski 0:01f31e923fe2 44
Pawel Zarembski 0:01f31e923fe2 45 static error_t target_flash_init(void);
Pawel Zarembski 0:01f31e923fe2 46 static error_t target_flash_uninit(void);
Pawel Zarembski 0:01f31e923fe2 47 static error_t target_flash_program_page(uint32_t adr, const uint8_t *buf, uint32_t size);
Pawel Zarembski 0:01f31e923fe2 48 static error_t target_flash_erase_sector(uint32_t addr);
Pawel Zarembski 0:01f31e923fe2 49 static error_t target_flash_erase_chip(void);
Pawel Zarembski 0:01f31e923fe2 50 static uint32_t target_flash_program_page_min_size(uint32_t addr);
Pawel Zarembski 0:01f31e923fe2 51 static uint32_t target_flash_erase_sector_size(uint32_t addr);
Pawel Zarembski 0:01f31e923fe2 52 static uint8_t target_flash_busy(void);
Pawel Zarembski 0:01f31e923fe2 53 static error_t target_flash_set(uint32_t addr);
Pawel Zarembski 0:01f31e923fe2 54
Pawel Zarembski 0:01f31e923fe2 55 static const flash_intf_t flash_intf = {
Pawel Zarembski 0:01f31e923fe2 56 target_flash_init,
Pawel Zarembski 0:01f31e923fe2 57 target_flash_uninit,
Pawel Zarembski 0:01f31e923fe2 58 target_flash_program_page,
Pawel Zarembski 0:01f31e923fe2 59 target_flash_erase_sector,
Pawel Zarembski 0:01f31e923fe2 60 target_flash_erase_chip,
Pawel Zarembski 0:01f31e923fe2 61 target_flash_program_page_min_size,
Pawel Zarembski 0:01f31e923fe2 62 target_flash_erase_sector_size,
Pawel Zarembski 0:01f31e923fe2 63 target_flash_busy,
Pawel Zarembski 0:01f31e923fe2 64 target_flash_set,
Pawel Zarembski 0:01f31e923fe2 65 };
Pawel Zarembski 0:01f31e923fe2 66
Pawel Zarembski 0:01f31e923fe2 67 static state_t state = STATE_CLOSED;
Pawel Zarembski 0:01f31e923fe2 68
Pawel Zarembski 0:01f31e923fe2 69 const flash_intf_t *const flash_intf_target = &flash_intf;
Pawel Zarembski 0:01f31e923fe2 70
Pawel Zarembski 0:01f31e923fe2 71 static flash_func_t last_flash_func = FLASH_FUNC_NOP;
Pawel Zarembski 0:01f31e923fe2 72
Pawel Zarembski 0:01f31e923fe2 73 //saved flash algo
Pawel Zarembski 0:01f31e923fe2 74 static program_target_t * current_flash_algo = NULL;
Pawel Zarembski 0:01f31e923fe2 75
Pawel Zarembski 0:01f31e923fe2 76 //saved default region for default flash algo
Pawel Zarembski 0:01f31e923fe2 77 static region_info_t * default_region = NULL;
Pawel Zarembski 0:01f31e923fe2 78
Pawel Zarembski 0:01f31e923fe2 79 //saved flash start from flash algo
Pawel Zarembski 0:01f31e923fe2 80 static uint32_t flash_start = 0;
Pawel Zarembski 0:01f31e923fe2 81
Pawel Zarembski 0:01f31e923fe2 82 static program_target_t * get_flash_algo(uint32_t addr)
Pawel Zarembski 0:01f31e923fe2 83 {
Pawel Zarembski 0:01f31e923fe2 84 region_info_t * flash_region = g_board_info.target_cfg->flash_regions;
Pawel Zarembski 0:01f31e923fe2 85
Pawel Zarembski 0:01f31e923fe2 86 for (; flash_region->start != 0 || flash_region->end != 0; ++flash_region) {
Pawel Zarembski 0:01f31e923fe2 87 if (addr >= flash_region->start && addr <= flash_region->end) {
Pawel Zarembski 0:01f31e923fe2 88 flash_start = flash_region->start; //save the flash start
Pawel Zarembski 0:01f31e923fe2 89 if (flash_region->flash_algo) {
Pawel Zarembski 0:01f31e923fe2 90 return flash_region->flash_algo;
Pawel Zarembski 0:01f31e923fe2 91 }else{
Pawel Zarembski 0:01f31e923fe2 92 return NULL;
Pawel Zarembski 0:01f31e923fe2 93 }
Pawel Zarembski 0:01f31e923fe2 94 }
Pawel Zarembski 0:01f31e923fe2 95 }
Pawel Zarembski 0:01f31e923fe2 96
Pawel Zarembski 0:01f31e923fe2 97 //could not find a flash algo for the region; use default
Pawel Zarembski 0:01f31e923fe2 98 if (default_region) {
Pawel Zarembski 0:01f31e923fe2 99 flash_start = default_region->start;
Pawel Zarembski 0:01f31e923fe2 100 return default_region->flash_algo;
Pawel Zarembski 0:01f31e923fe2 101 } else {
Pawel Zarembski 0:01f31e923fe2 102 return NULL;
Pawel Zarembski 0:01f31e923fe2 103 }
Pawel Zarembski 0:01f31e923fe2 104 }
Pawel Zarembski 0:01f31e923fe2 105
Pawel Zarembski 0:01f31e923fe2 106 static error_t flash_func_start(flash_func_t func)
Pawel Zarembski 0:01f31e923fe2 107 {
Pawel Zarembski 0:01f31e923fe2 108 program_target_t * flash = current_flash_algo;
Pawel Zarembski 0:01f31e923fe2 109
Pawel Zarembski 0:01f31e923fe2 110 if (last_flash_func != func)
Pawel Zarembski 0:01f31e923fe2 111 {
Pawel Zarembski 0:01f31e923fe2 112 // Finish the currently active function.
Pawel Zarembski 0:01f31e923fe2 113 if (FLASH_FUNC_NOP != last_flash_func &&
Pawel Zarembski 0:01f31e923fe2 114 ((flash->algo_flags & kAlgoSingleInitType) == 0 || FLASH_FUNC_NOP == func ) &&
Pawel Zarembski 0:01f31e923fe2 115 0 == swd_flash_syscall_exec(&flash->sys_call_s, flash->uninit, last_flash_func, 0, 0, 0, FLASHALGO_RETURN_BOOL)) {
Pawel Zarembski 0:01f31e923fe2 116 return ERROR_UNINIT;
Pawel Zarembski 0:01f31e923fe2 117 }
Pawel Zarembski 0:01f31e923fe2 118
Pawel Zarembski 0:01f31e923fe2 119 // Start a new function.
Pawel Zarembski 0:01f31e923fe2 120 if (FLASH_FUNC_NOP != func &&
Pawel Zarembski 0:01f31e923fe2 121 ((flash->algo_flags & kAlgoSingleInitType) == 0 || FLASH_FUNC_NOP == last_flash_func ) &&
Pawel Zarembski 0:01f31e923fe2 122 0 == swd_flash_syscall_exec(&flash->sys_call_s, flash->init, flash_start, 0, func, 0, FLASHALGO_RETURN_BOOL)) {
Pawel Zarembski 0:01f31e923fe2 123 return ERROR_INIT;
Pawel Zarembski 0:01f31e923fe2 124 }
Pawel Zarembski 0:01f31e923fe2 125
Pawel Zarembski 0:01f31e923fe2 126 last_flash_func = func;
Pawel Zarembski 0:01f31e923fe2 127 }
Pawel Zarembski 0:01f31e923fe2 128
Pawel Zarembski 0:01f31e923fe2 129 return ERROR_SUCCESS;
Pawel Zarembski 0:01f31e923fe2 130 }
Pawel Zarembski 0:01f31e923fe2 131
Pawel Zarembski 0:01f31e923fe2 132 static error_t target_flash_set(uint32_t addr)
Pawel Zarembski 0:01f31e923fe2 133 {
Pawel Zarembski 0:01f31e923fe2 134 program_target_t * new_flash_algo = get_flash_algo(addr);
Pawel Zarembski 0:01f31e923fe2 135 if (new_flash_algo == NULL) {
Pawel Zarembski 0:01f31e923fe2 136 return ERROR_ALGO_MISSING;
Pawel Zarembski 0:01f31e923fe2 137 }
Pawel Zarembski 0:01f31e923fe2 138 if(current_flash_algo != new_flash_algo){
Pawel Zarembski 0:01f31e923fe2 139 //run uninit to last func
Pawel Zarembski 0:01f31e923fe2 140 error_t status = flash_func_start(FLASH_FUNC_NOP);
Pawel Zarembski 0:01f31e923fe2 141 if (status != ERROR_SUCCESS) {
Pawel Zarembski 0:01f31e923fe2 142 return status;
Pawel Zarembski 0:01f31e923fe2 143 }
Pawel Zarembski 0:01f31e923fe2 144 // Download flash programming algorithm to target
Pawel Zarembski 0:01f31e923fe2 145 if (0 == swd_write_memory(new_flash_algo->algo_start, (uint8_t *)new_flash_algo->algo_blob, new_flash_algo->algo_size)) {
Pawel Zarembski 0:01f31e923fe2 146 return ERROR_ALGO_DL;
Pawel Zarembski 0:01f31e923fe2 147 }
Pawel Zarembski 0:01f31e923fe2 148
Pawel Zarembski 0:01f31e923fe2 149 current_flash_algo = new_flash_algo;
Pawel Zarembski 0:01f31e923fe2 150
Pawel Zarembski 0:01f31e923fe2 151 }
Pawel Zarembski 0:01f31e923fe2 152 return ERROR_SUCCESS;
Pawel Zarembski 0:01f31e923fe2 153 }
Pawel Zarembski 0:01f31e923fe2 154
Pawel Zarembski 0:01f31e923fe2 155 static error_t target_flash_init()
Pawel Zarembski 0:01f31e923fe2 156 {
Pawel Zarembski 0:01f31e923fe2 157 if (g_board_info.target_cfg) {
Pawel Zarembski 0:01f31e923fe2 158 last_flash_func = FLASH_FUNC_NOP;
Pawel Zarembski 0:01f31e923fe2 159
Pawel Zarembski 0:01f31e923fe2 160 current_flash_algo = NULL;
Pawel Zarembski 0:01f31e923fe2 161
Pawel Zarembski 0:01f31e923fe2 162 if (0 == target_set_state(RESET_PROGRAM)) {
Pawel Zarembski 0:01f31e923fe2 163 return ERROR_RESET;
Pawel Zarembski 0:01f31e923fe2 164 }
Pawel Zarembski 0:01f31e923fe2 165
Pawel Zarembski 0:01f31e923fe2 166 //get default region
Pawel Zarembski 0:01f31e923fe2 167 region_info_t * flash_region = g_board_info.target_cfg->flash_regions;
Pawel Zarembski 0:01f31e923fe2 168 for (; flash_region->start != 0 || flash_region->end != 0; ++flash_region) {
Pawel Zarembski 0:01f31e923fe2 169 if (flash_region->flags & kRegionIsDefault) {
Pawel Zarembski 0:01f31e923fe2 170 default_region = flash_region;
Pawel Zarembski 0:01f31e923fe2 171 break;
Pawel Zarembski 0:01f31e923fe2 172 }
Pawel Zarembski 0:01f31e923fe2 173 }
Pawel Zarembski 0:01f31e923fe2 174
Pawel Zarembski 0:01f31e923fe2 175 state = STATE_OPEN;
Pawel Zarembski 0:01f31e923fe2 176 return ERROR_SUCCESS;
Pawel Zarembski 0:01f31e923fe2 177 } else {
Pawel Zarembski 0:01f31e923fe2 178 return ERROR_FAILURE;
Pawel Zarembski 0:01f31e923fe2 179 }
Pawel Zarembski 0:01f31e923fe2 180
Pawel Zarembski 0:01f31e923fe2 181 }
Pawel Zarembski 0:01f31e923fe2 182
Pawel Zarembski 0:01f31e923fe2 183 static error_t target_flash_uninit(void)
Pawel Zarembski 0:01f31e923fe2 184 {
Pawel Zarembski 0:01f31e923fe2 185 if (g_board_info.target_cfg) {
Pawel Zarembski 0:01f31e923fe2 186 error_t status = flash_func_start(FLASH_FUNC_NOP);
Pawel Zarembski 0:01f31e923fe2 187 if (status != ERROR_SUCCESS) {
Pawel Zarembski 0:01f31e923fe2 188 return status;
Pawel Zarembski 0:01f31e923fe2 189 }
Pawel Zarembski 0:01f31e923fe2 190 if (config_get_auto_rst()) {
Pawel Zarembski 0:01f31e923fe2 191 // Resume the target if configured to do so
Pawel Zarembski 0:01f31e923fe2 192 target_set_state(RESET_RUN);
Pawel Zarembski 0:01f31e923fe2 193 } else {
Pawel Zarembski 0:01f31e923fe2 194 // Leave the target halted until a reset occurs
Pawel Zarembski 0:01f31e923fe2 195 target_set_state(RESET_PROGRAM);
Pawel Zarembski 0:01f31e923fe2 196 }
Pawel Zarembski 0:01f31e923fe2 197 // Check to see if anything needs to be done after programming.
Pawel Zarembski 0:01f31e923fe2 198 // This is usually a no-op for most targets.
Pawel Zarembski 0:01f31e923fe2 199 target_set_state(POST_FLASH_RESET);
Pawel Zarembski 0:01f31e923fe2 200
Pawel Zarembski 0:01f31e923fe2 201 state = STATE_CLOSED;
Pawel Zarembski 0:01f31e923fe2 202 swd_off();
Pawel Zarembski 0:01f31e923fe2 203 return ERROR_SUCCESS;
Pawel Zarembski 0:01f31e923fe2 204 } else {
Pawel Zarembski 0:01f31e923fe2 205 return ERROR_FAILURE;
Pawel Zarembski 0:01f31e923fe2 206 }
Pawel Zarembski 0:01f31e923fe2 207 }
Pawel Zarembski 0:01f31e923fe2 208
Pawel Zarembski 0:01f31e923fe2 209 static error_t target_flash_program_page(uint32_t addr, const uint8_t *buf, uint32_t size)
Pawel Zarembski 0:01f31e923fe2 210 {
Pawel Zarembski 0:01f31e923fe2 211 if (g_board_info.target_cfg) {
Pawel Zarembski 0:01f31e923fe2 212 error_t status = ERROR_SUCCESS;
Pawel Zarembski 0:01f31e923fe2 213 program_target_t * flash = current_flash_algo;
Pawel Zarembski 0:01f31e923fe2 214
Pawel Zarembski 0:01f31e923fe2 215 if (!flash) {
Pawel Zarembski 0:01f31e923fe2 216 return ERROR_INTERNAL;
Pawel Zarembski 0:01f31e923fe2 217 }
Pawel Zarembski 0:01f31e923fe2 218
Pawel Zarembski 0:01f31e923fe2 219 // check if security bits were set
Pawel Zarembski 0:01f31e923fe2 220 if (g_target_family && g_target_family->security_bits_set){
Pawel Zarembski 0:01f31e923fe2 221 if (1 == g_target_family->security_bits_set(addr, (uint8_t *)buf, size)) {
Pawel Zarembski 0:01f31e923fe2 222 return ERROR_SECURITY_BITS;
Pawel Zarembski 0:01f31e923fe2 223 }
Pawel Zarembski 0:01f31e923fe2 224 }
Pawel Zarembski 0:01f31e923fe2 225
Pawel Zarembski 0:01f31e923fe2 226 status = flash_func_start(FLASH_FUNC_PROGRAM);
Pawel Zarembski 0:01f31e923fe2 227
Pawel Zarembski 0:01f31e923fe2 228 if (status != ERROR_SUCCESS) {
Pawel Zarembski 0:01f31e923fe2 229 return status;
Pawel Zarembski 0:01f31e923fe2 230 }
Pawel Zarembski 0:01f31e923fe2 231
Pawel Zarembski 0:01f31e923fe2 232 while (size > 0) {
Pawel Zarembski 0:01f31e923fe2 233 uint32_t write_size = MIN(size, flash->program_buffer_size);
Pawel Zarembski 0:01f31e923fe2 234
Pawel Zarembski 0:01f31e923fe2 235 // Write page to buffer
Pawel Zarembski 0:01f31e923fe2 236 if (!swd_write_memory(flash->program_buffer, (uint8_t *)buf, write_size)) {
Pawel Zarembski 0:01f31e923fe2 237 return ERROR_ALGO_DATA_SEQ;
Pawel Zarembski 0:01f31e923fe2 238 }
Pawel Zarembski 0:01f31e923fe2 239
Pawel Zarembski 0:01f31e923fe2 240 // Run flash programming
Pawel Zarembski 0:01f31e923fe2 241 if (!swd_flash_syscall_exec(&flash->sys_call_s,
Pawel Zarembski 0:01f31e923fe2 242 flash->program_page,
Pawel Zarembski 0:01f31e923fe2 243 addr,
Pawel Zarembski 0:01f31e923fe2 244 write_size,
Pawel Zarembski 0:01f31e923fe2 245 flash->program_buffer,
Pawel Zarembski 0:01f31e923fe2 246 0,
Pawel Zarembski 0:01f31e923fe2 247 FLASHALGO_RETURN_BOOL)) {
Pawel Zarembski 0:01f31e923fe2 248 return ERROR_WRITE;
Pawel Zarembski 0:01f31e923fe2 249 }
Pawel Zarembski 0:01f31e923fe2 250
Pawel Zarembski 0:01f31e923fe2 251 if (config_get_automation_allowed()) {
Pawel Zarembski 0:01f31e923fe2 252 // Verify data flashed if in automation mode
Pawel Zarembski 0:01f31e923fe2 253 if (flash->verify != 0) {
Pawel Zarembski 0:01f31e923fe2 254 status = flash_func_start(FLASH_FUNC_VERIFY);
Pawel Zarembski 0:01f31e923fe2 255 if (status != ERROR_SUCCESS) {
Pawel Zarembski 0:01f31e923fe2 256 return status;
Pawel Zarembski 0:01f31e923fe2 257 }
Pawel Zarembski 0:01f31e923fe2 258 flash_algo_return_t return_type;
Pawel Zarembski 0:01f31e923fe2 259 if ((flash->algo_flags & kAlgoVerifyReturnsAddress) != 0) {
Pawel Zarembski 0:01f31e923fe2 260 return_type = FLASHALGO_RETURN_POINTER;
Pawel Zarembski 0:01f31e923fe2 261 } else {
Pawel Zarembski 0:01f31e923fe2 262 return_type = FLASHALGO_RETURN_BOOL;
Pawel Zarembski 0:01f31e923fe2 263 }
Pawel Zarembski 0:01f31e923fe2 264 if (!swd_flash_syscall_exec(&flash->sys_call_s,
Pawel Zarembski 0:01f31e923fe2 265 flash->verify,
Pawel Zarembski 0:01f31e923fe2 266 addr,
Pawel Zarembski 0:01f31e923fe2 267 write_size,
Pawel Zarembski 0:01f31e923fe2 268 flash->program_buffer,
Pawel Zarembski 0:01f31e923fe2 269 0,
Pawel Zarembski 0:01f31e923fe2 270 return_type)) {
Pawel Zarembski 0:01f31e923fe2 271 return ERROR_WRITE_VERIFY;
Pawel Zarembski 0:01f31e923fe2 272 }
Pawel Zarembski 0:01f31e923fe2 273 } else {
Pawel Zarembski 0:01f31e923fe2 274 while (write_size > 0) {
Pawel Zarembski 0:01f31e923fe2 275 uint8_t rb_buf[16];
Pawel Zarembski 0:01f31e923fe2 276 uint32_t verify_size = MIN(write_size, sizeof(rb_buf));
Pawel Zarembski 0:01f31e923fe2 277 if (!swd_read_memory(addr, rb_buf, verify_size)) {
Pawel Zarembski 0:01f31e923fe2 278 return ERROR_ALGO_DATA_SEQ;
Pawel Zarembski 0:01f31e923fe2 279 }
Pawel Zarembski 0:01f31e923fe2 280 if (memcmp(buf, rb_buf, verify_size) != 0) {
Pawel Zarembski 0:01f31e923fe2 281 return ERROR_WRITE_VERIFY;
Pawel Zarembski 0:01f31e923fe2 282 }
Pawel Zarembski 0:01f31e923fe2 283 addr += verify_size;
Pawel Zarembski 0:01f31e923fe2 284 buf += verify_size;
Pawel Zarembski 0:01f31e923fe2 285 size -= verify_size;
Pawel Zarembski 0:01f31e923fe2 286 write_size -= verify_size;
Pawel Zarembski 0:01f31e923fe2 287 }
Pawel Zarembski 0:01f31e923fe2 288 continue;
Pawel Zarembski 0:01f31e923fe2 289 }
Pawel Zarembski 0:01f31e923fe2 290 }
Pawel Zarembski 0:01f31e923fe2 291 addr += write_size;
Pawel Zarembski 0:01f31e923fe2 292 buf += write_size;
Pawel Zarembski 0:01f31e923fe2 293 size -= write_size;
Pawel Zarembski 0:01f31e923fe2 294
Pawel Zarembski 0:01f31e923fe2 295 }
Pawel Zarembski 0:01f31e923fe2 296
Pawel Zarembski 0:01f31e923fe2 297 return ERROR_SUCCESS;
Pawel Zarembski 0:01f31e923fe2 298
Pawel Zarembski 0:01f31e923fe2 299 } else {
Pawel Zarembski 0:01f31e923fe2 300 return ERROR_FAILURE;
Pawel Zarembski 0:01f31e923fe2 301 }
Pawel Zarembski 0:01f31e923fe2 302 }
Pawel Zarembski 0:01f31e923fe2 303
Pawel Zarembski 0:01f31e923fe2 304 static error_t target_flash_erase_sector(uint32_t addr)
Pawel Zarembski 0:01f31e923fe2 305 {
Pawel Zarembski 0:01f31e923fe2 306 if (g_board_info.target_cfg) {
Pawel Zarembski 0:01f31e923fe2 307 error_t status = ERROR_SUCCESS;
Pawel Zarembski 0:01f31e923fe2 308 program_target_t * flash = current_flash_algo;
Pawel Zarembski 0:01f31e923fe2 309
Pawel Zarembski 0:01f31e923fe2 310 if (!flash) {
Pawel Zarembski 0:01f31e923fe2 311 return ERROR_INTERNAL;
Pawel Zarembski 0:01f31e923fe2 312 }
Pawel Zarembski 0:01f31e923fe2 313
Pawel Zarembski 0:01f31e923fe2 314 // Check to make sure the address is on a sector boundary
Pawel Zarembski 0:01f31e923fe2 315 if ((addr % target_flash_erase_sector_size(addr)) != 0) {
Pawel Zarembski 0:01f31e923fe2 316 return ERROR_ERASE_SECTOR;
Pawel Zarembski 0:01f31e923fe2 317 }
Pawel Zarembski 0:01f31e923fe2 318
Pawel Zarembski 0:01f31e923fe2 319 status = flash_func_start(FLASH_FUNC_ERASE);
Pawel Zarembski 0:01f31e923fe2 320
Pawel Zarembski 0:01f31e923fe2 321 if (status != ERROR_SUCCESS) {
Pawel Zarembski 0:01f31e923fe2 322 return status;
Pawel Zarembski 0:01f31e923fe2 323 }
Pawel Zarembski 0:01f31e923fe2 324
Pawel Zarembski 0:01f31e923fe2 325 if (0 == swd_flash_syscall_exec(&flash->sys_call_s, flash->erase_sector, addr, 0, 0, 0, FLASHALGO_RETURN_BOOL)) {
Pawel Zarembski 0:01f31e923fe2 326 return ERROR_ERASE_SECTOR;
Pawel Zarembski 0:01f31e923fe2 327 }
Pawel Zarembski 0:01f31e923fe2 328
Pawel Zarembski 0:01f31e923fe2 329 return ERROR_SUCCESS;
Pawel Zarembski 0:01f31e923fe2 330 } else {
Pawel Zarembski 0:01f31e923fe2 331 return ERROR_FAILURE;
Pawel Zarembski 0:01f31e923fe2 332 }
Pawel Zarembski 0:01f31e923fe2 333 }
Pawel Zarembski 0:01f31e923fe2 334
Pawel Zarembski 0:01f31e923fe2 335 static error_t target_flash_erase_chip(void)
Pawel Zarembski 0:01f31e923fe2 336 {
Pawel Zarembski 0:01f31e923fe2 337 if (g_board_info.target_cfg){
Pawel Zarembski 0:01f31e923fe2 338 error_t status = ERROR_SUCCESS;
Pawel Zarembski 0:01f31e923fe2 339 region_info_t * flash_region = g_board_info.target_cfg->flash_regions;
Pawel Zarembski 0:01f31e923fe2 340
Pawel Zarembski 0:01f31e923fe2 341 for (; flash_region->start != 0 || flash_region->end != 0; ++flash_region) {
Pawel Zarembski 0:01f31e923fe2 342 program_target_t *new_flash_algo = get_flash_algo(flash_region->start);
Pawel Zarembski 0:01f31e923fe2 343 if ((new_flash_algo != NULL) && ((new_flash_algo->algo_flags & kAlgoSkipChipErase) != 0)) {
Pawel Zarembski 0:01f31e923fe2 344 // skip flash region
Pawel Zarembski 0:01f31e923fe2 345 continue;
Pawel Zarembski 0:01f31e923fe2 346 }
Pawel Zarembski 0:01f31e923fe2 347 status = target_flash_set(flash_region->start);
Pawel Zarembski 0:01f31e923fe2 348 if (status != ERROR_SUCCESS) {
Pawel Zarembski 0:01f31e923fe2 349 return status;
Pawel Zarembski 0:01f31e923fe2 350 }
Pawel Zarembski 0:01f31e923fe2 351 status = flash_func_start(FLASH_FUNC_ERASE);
Pawel Zarembski 0:01f31e923fe2 352 if (status != ERROR_SUCCESS) {
Pawel Zarembski 0:01f31e923fe2 353 return status;
Pawel Zarembski 0:01f31e923fe2 354 }
Pawel Zarembski 0:01f31e923fe2 355 if (0 == swd_flash_syscall_exec(&current_flash_algo->sys_call_s, current_flash_algo->erase_chip, 0, 0, 0, 0, FLASHALGO_RETURN_BOOL)) {
Pawel Zarembski 0:01f31e923fe2 356 return ERROR_ERASE_ALL;
Pawel Zarembski 0:01f31e923fe2 357 }
Pawel Zarembski 0:01f31e923fe2 358 }
Pawel Zarembski 0:01f31e923fe2 359
Pawel Zarembski 0:01f31e923fe2 360 // Reset and re-initialize the target after the erase if required
Pawel Zarembski 0:01f31e923fe2 361 if (g_board_info.target_cfg->erase_reset) {
Pawel Zarembski 0:01f31e923fe2 362 status = target_flash_init();
Pawel Zarembski 0:01f31e923fe2 363 }
Pawel Zarembski 0:01f31e923fe2 364
Pawel Zarembski 0:01f31e923fe2 365 return status;
Pawel Zarembski 0:01f31e923fe2 366 } else {
Pawel Zarembski 0:01f31e923fe2 367 return ERROR_FAILURE;
Pawel Zarembski 0:01f31e923fe2 368 }
Pawel Zarembski 0:01f31e923fe2 369 }
Pawel Zarembski 0:01f31e923fe2 370
Pawel Zarembski 0:01f31e923fe2 371 static uint32_t target_flash_program_page_min_size(uint32_t addr)
Pawel Zarembski 0:01f31e923fe2 372 {
Pawel Zarembski 0:01f31e923fe2 373 if (g_board_info.target_cfg){
Pawel Zarembski 0:01f31e923fe2 374 uint32_t size = DEFAULT_PROGRAM_PAGE_MIN_SIZE;
Pawel Zarembski 0:01f31e923fe2 375 if (size > target_flash_erase_sector_size(addr)) {
Pawel Zarembski 0:01f31e923fe2 376 size = target_flash_erase_sector_size(addr);
Pawel Zarembski 0:01f31e923fe2 377 }
Pawel Zarembski 0:01f31e923fe2 378 return size;
Pawel Zarembski 0:01f31e923fe2 379 } else {
Pawel Zarembski 0:01f31e923fe2 380 return 0;
Pawel Zarembski 0:01f31e923fe2 381 }
Pawel Zarembski 0:01f31e923fe2 382 }
Pawel Zarembski 0:01f31e923fe2 383
Pawel Zarembski 0:01f31e923fe2 384 static uint32_t target_flash_erase_sector_size(uint32_t addr)
Pawel Zarembski 0:01f31e923fe2 385 {
Pawel Zarembski 0:01f31e923fe2 386 if (g_board_info.target_cfg){
Pawel Zarembski 0:01f31e923fe2 387 if(g_board_info.target_cfg->sector_info_length > 0) {
Pawel Zarembski 0:01f31e923fe2 388 int sector_index = g_board_info.target_cfg->sector_info_length - 1;
Pawel Zarembski 0:01f31e923fe2 389 for (; sector_index >= 0; sector_index--) {
Pawel Zarembski 0:01f31e923fe2 390 if (addr >= g_board_info.target_cfg->sectors_info[sector_index].start) {
Pawel Zarembski 0:01f31e923fe2 391 return g_board_info.target_cfg->sectors_info[sector_index].size;
Pawel Zarembski 0:01f31e923fe2 392 }
Pawel Zarembski 0:01f31e923fe2 393 }
Pawel Zarembski 0:01f31e923fe2 394 }
Pawel Zarembski 0:01f31e923fe2 395 //sector information should be in sector_info
Pawel Zarembski 0:01f31e923fe2 396 util_assert(0);
Pawel Zarembski 0:01f31e923fe2 397 return 0;
Pawel Zarembski 0:01f31e923fe2 398 } else {
Pawel Zarembski 0:01f31e923fe2 399 return 0;
Pawel Zarembski 0:01f31e923fe2 400 }
Pawel Zarembski 0:01f31e923fe2 401 }
Pawel Zarembski 0:01f31e923fe2 402
Pawel Zarembski 0:01f31e923fe2 403 static uint8_t target_flash_busy(void){
Pawel Zarembski 0:01f31e923fe2 404 return (state == STATE_OPEN);
Pawel Zarembski 0:01f31e923fe2 405 }
Pawel Zarembski 0:01f31e923fe2 406 #endif