Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
target_flash.c
00001 /** 00002 * @file target_flash.c 00003 * @brief Implementation of target_flash.h 00004 * 00005 * DAPLink Interface Firmware 00006 * Copyright (c) 2009-2019, ARM Limited, All Rights Reserved 00007 * Copyright 2019, Cypress Semiconductor Corporation 00008 * or a subsidiary of Cypress Semiconductor Corporation. 00009 * SPDX-License-Identifier: Apache-2.0 00010 * 00011 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00012 * not use this file except in compliance with the License. 00013 * You may obtain a copy of the License at 00014 * 00015 * http://www.apache.org/licenses/LICENSE-2.0 00016 * 00017 * Unless required by applicable law or agreed to in writing, software 00018 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00019 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00020 * See the License for the specific language governing permissions and 00021 * limitations under the License. 00022 */ 00023 #ifdef DRAG_N_DROP_SUPPORT 00024 #include <string.h> 00025 00026 #include "target_config.h" 00027 #include "gpio.h" 00028 #include "target_config.h" 00029 #include "intelhex.h" 00030 #include "swd_host.h" 00031 #include "flash_intf.h" 00032 #include "util.h" 00033 #include "settings.h" 00034 #include "target_family.h" 00035 #include "target_board.h" 00036 00037 #define DEFAULT_PROGRAM_PAGE_MIN_SIZE (256u) 00038 00039 typedef enum { 00040 STATE_CLOSED, 00041 STATE_OPEN, 00042 STATE_ERROR 00043 } state_t; 00044 00045 static error_t target_flash_init(void); 00046 static error_t target_flash_uninit(void); 00047 static error_t target_flash_program_page(uint32_t adr, const uint8_t *buf, uint32_t size); 00048 static error_t target_flash_erase_sector(uint32_t addr); 00049 static error_t target_flash_erase_chip(void); 00050 static uint32_t target_flash_program_page_min_size(uint32_t addr); 00051 static uint32_t target_flash_erase_sector_size(uint32_t addr); 00052 static uint8_t target_flash_busy(void); 00053 static error_t target_flash_set(uint32_t addr); 00054 00055 static const flash_intf_t flash_intf = { 00056 target_flash_init, 00057 target_flash_uninit, 00058 target_flash_program_page, 00059 target_flash_erase_sector, 00060 target_flash_erase_chip, 00061 target_flash_program_page_min_size, 00062 target_flash_erase_sector_size, 00063 target_flash_busy, 00064 target_flash_set, 00065 }; 00066 00067 static state_t state = STATE_CLOSED; 00068 00069 const flash_intf_t *const flash_intf_target = &flash_intf; 00070 00071 static flash_func_t last_flash_func = FLASH_FUNC_NOP; 00072 00073 //saved flash algo 00074 static program_target_t * current_flash_algo = NULL; 00075 00076 //saved default region for default flash algo 00077 static region_info_t * default_region = NULL; 00078 00079 //saved flash start from flash algo 00080 static uint32_t flash_start = 0; 00081 00082 static program_target_t * get_flash_algo(uint32_t addr) 00083 { 00084 region_info_t * flash_region = g_board_info.target_cfg->flash_regions; 00085 00086 for (; flash_region->start != 0 || flash_region->end != 0; ++flash_region) { 00087 if (addr >= flash_region->start && addr <= flash_region->end) { 00088 flash_start = flash_region->start; //save the flash start 00089 if (flash_region->flash_algo) { 00090 return flash_region->flash_algo; 00091 }else{ 00092 return NULL; 00093 } 00094 } 00095 } 00096 00097 //could not find a flash algo for the region; use default 00098 if (default_region) { 00099 flash_start = default_region->start; 00100 return default_region->flash_algo; 00101 } else { 00102 return NULL; 00103 } 00104 } 00105 00106 static error_t flash_func_start(flash_func_t func) 00107 { 00108 program_target_t * flash = current_flash_algo; 00109 00110 if (last_flash_func != func) 00111 { 00112 // Finish the currently active function. 00113 if (FLASH_FUNC_NOP != last_flash_func && 00114 ((flash->algo_flags & kAlgoSingleInitType ) == 0 || FLASH_FUNC_NOP == func ) && 00115 0 == swd_flash_syscall_exec(&flash->sys_call_s, flash->uninit, last_flash_func, 0, 0, 0, FLASHALGO_RETURN_BOOL)) { 00116 return ERROR_UNINIT; 00117 } 00118 00119 // Start a new function. 00120 if (FLASH_FUNC_NOP != func && 00121 ((flash->algo_flags & kAlgoSingleInitType ) == 0 || FLASH_FUNC_NOP == last_flash_func ) && 00122 0 == swd_flash_syscall_exec(&flash->sys_call_s, flash->init, flash_start, 0, func, 0, FLASHALGO_RETURN_BOOL)) { 00123 return ERROR_INIT; 00124 } 00125 00126 last_flash_func = func; 00127 } 00128 00129 return ERROR_SUCCESS; 00130 } 00131 00132 static error_t target_flash_set(uint32_t addr) 00133 { 00134 program_target_t * new_flash_algo = get_flash_algo(addr); 00135 if (new_flash_algo == NULL) { 00136 return ERROR_ALGO_MISSING; 00137 } 00138 if(current_flash_algo != new_flash_algo){ 00139 //run uninit to last func 00140 error_t status = flash_func_start(FLASH_FUNC_NOP); 00141 if (status != ERROR_SUCCESS) { 00142 return status; 00143 } 00144 // Download flash programming algorithm to target 00145 if (0 == swd_write_memory(new_flash_algo->algo_start, (uint8_t *)new_flash_algo->algo_blob, new_flash_algo->algo_size)) { 00146 return ERROR_ALGO_DL; 00147 } 00148 00149 current_flash_algo = new_flash_algo; 00150 00151 } 00152 return ERROR_SUCCESS; 00153 } 00154 00155 static error_t target_flash_init() 00156 { 00157 if (g_board_info.target_cfg) { 00158 last_flash_func = FLASH_FUNC_NOP; 00159 00160 current_flash_algo = NULL; 00161 00162 if (0 == target_set_state(RESET_PROGRAM)) { 00163 return ERROR_RESET; 00164 } 00165 00166 //get default region 00167 region_info_t * flash_region = g_board_info.target_cfg->flash_regions; 00168 for (; flash_region->start != 0 || flash_region->end != 0; ++flash_region) { 00169 if (flash_region->flags & kRegionIsDefault ) { 00170 default_region = flash_region; 00171 break; 00172 } 00173 } 00174 00175 state = STATE_OPEN; 00176 return ERROR_SUCCESS; 00177 } else { 00178 return ERROR_FAILURE; 00179 } 00180 00181 } 00182 00183 static error_t target_flash_uninit(void) 00184 { 00185 if (g_board_info.target_cfg) { 00186 error_t status = flash_func_start(FLASH_FUNC_NOP); 00187 if (status != ERROR_SUCCESS) { 00188 return status; 00189 } 00190 if (config_get_auto_rst()) { 00191 // Resume the target if configured to do so 00192 target_set_state(RESET_RUN); 00193 } else { 00194 // Leave the target halted until a reset occurs 00195 target_set_state(RESET_PROGRAM); 00196 } 00197 // Check to see if anything needs to be done after programming. 00198 // This is usually a no-op for most targets. 00199 target_set_state(POST_FLASH_RESET); 00200 00201 state = STATE_CLOSED; 00202 swd_off(); 00203 return ERROR_SUCCESS; 00204 } else { 00205 return ERROR_FAILURE; 00206 } 00207 } 00208 00209 static error_t target_flash_program_page(uint32_t addr, const uint8_t *buf, uint32_t size) 00210 { 00211 if (g_board_info.target_cfg) { 00212 error_t status = ERROR_SUCCESS; 00213 program_target_t * flash = current_flash_algo; 00214 00215 if (!flash) { 00216 return ERROR_INTERNAL; 00217 } 00218 00219 // check if security bits were set 00220 if (g_target_family && g_target_family->security_bits_set ){ 00221 if (1 == g_target_family->security_bits_set (addr, (uint8_t *)buf, size)) { 00222 return ERROR_SECURITY_BITS; 00223 } 00224 } 00225 00226 status = flash_func_start(FLASH_FUNC_PROGRAM); 00227 00228 if (status != ERROR_SUCCESS) { 00229 return status; 00230 } 00231 00232 while (size > 0) { 00233 uint32_t write_size = MIN(size, flash->program_buffer_size); 00234 00235 // Write page to buffer 00236 if (!swd_write_memory(flash->program_buffer, (uint8_t *)buf, write_size)) { 00237 return ERROR_ALGO_DATA_SEQ; 00238 } 00239 00240 // Run flash programming 00241 if (!swd_flash_syscall_exec(&flash->sys_call_s, 00242 flash->program_page, 00243 addr, 00244 write_size, 00245 flash->program_buffer, 00246 0, 00247 FLASHALGO_RETURN_BOOL)) { 00248 return ERROR_WRITE; 00249 } 00250 00251 if (config_get_automation_allowed()) { 00252 // Verify data flashed if in automation mode 00253 if (flash->verify != 0) { 00254 status = flash_func_start(FLASH_FUNC_VERIFY); 00255 if (status != ERROR_SUCCESS) { 00256 return status; 00257 } 00258 flash_algo_return_t return_type; 00259 if ((flash->algo_flags & kAlgoVerifyReturnsAddress ) != 0) { 00260 return_type = FLASHALGO_RETURN_POINTER; 00261 } else { 00262 return_type = FLASHALGO_RETURN_BOOL; 00263 } 00264 if (!swd_flash_syscall_exec(&flash->sys_call_s, 00265 flash->verify, 00266 addr, 00267 write_size, 00268 flash->program_buffer, 00269 0, 00270 return_type)) { 00271 return ERROR_WRITE_VERIFY; 00272 } 00273 } else { 00274 while (write_size > 0) { 00275 uint8_t rb_buf[16]; 00276 uint32_t verify_size = MIN(write_size, sizeof(rb_buf)); 00277 if (!swd_read_memory(addr, rb_buf, verify_size)) { 00278 return ERROR_ALGO_DATA_SEQ; 00279 } 00280 if (memcmp(buf, rb_buf, verify_size) != 0) { 00281 return ERROR_WRITE_VERIFY; 00282 } 00283 addr += verify_size; 00284 buf += verify_size; 00285 size -= verify_size; 00286 write_size -= verify_size; 00287 } 00288 continue; 00289 } 00290 } 00291 addr += write_size; 00292 buf += write_size; 00293 size -= write_size; 00294 00295 } 00296 00297 return ERROR_SUCCESS; 00298 00299 } else { 00300 return ERROR_FAILURE; 00301 } 00302 } 00303 00304 static error_t target_flash_erase_sector(uint32_t addr) 00305 { 00306 if (g_board_info.target_cfg) { 00307 error_t status = ERROR_SUCCESS; 00308 program_target_t * flash = current_flash_algo; 00309 00310 if (!flash) { 00311 return ERROR_INTERNAL; 00312 } 00313 00314 // Check to make sure the address is on a sector boundary 00315 if ((addr % target_flash_erase_sector_size(addr)) != 0) { 00316 return ERROR_ERASE_SECTOR; 00317 } 00318 00319 status = flash_func_start(FLASH_FUNC_ERASE); 00320 00321 if (status != ERROR_SUCCESS) { 00322 return status; 00323 } 00324 00325 if (0 == swd_flash_syscall_exec(&flash->sys_call_s, flash->erase_sector, addr, 0, 0, 0, FLASHALGO_RETURN_BOOL)) { 00326 return ERROR_ERASE_SECTOR; 00327 } 00328 00329 return ERROR_SUCCESS; 00330 } else { 00331 return ERROR_FAILURE; 00332 } 00333 } 00334 00335 static error_t target_flash_erase_chip(void) 00336 { 00337 if (g_board_info.target_cfg){ 00338 error_t status = ERROR_SUCCESS; 00339 region_info_t * flash_region = g_board_info.target_cfg->flash_regions; 00340 00341 for (; flash_region->start != 0 || flash_region->end != 0; ++flash_region) { 00342 program_target_t *new_flash_algo = get_flash_algo(flash_region->start); 00343 if ((new_flash_algo != NULL) && ((new_flash_algo->algo_flags & kAlgoSkipChipErase ) != 0)) { 00344 // skip flash region 00345 continue; 00346 } 00347 status = target_flash_set(flash_region->start); 00348 if (status != ERROR_SUCCESS) { 00349 return status; 00350 } 00351 status = flash_func_start(FLASH_FUNC_ERASE); 00352 if (status != ERROR_SUCCESS) { 00353 return status; 00354 } 00355 if (0 == swd_flash_syscall_exec(¤t_flash_algo->sys_call_s, current_flash_algo->erase_chip, 0, 0, 0, 0, FLASHALGO_RETURN_BOOL)) { 00356 return ERROR_ERASE_ALL; 00357 } 00358 } 00359 00360 // Reset and re-initialize the target after the erase if required 00361 if (g_board_info.target_cfg->erase_reset) { 00362 status = target_flash_init(); 00363 } 00364 00365 return status; 00366 } else { 00367 return ERROR_FAILURE; 00368 } 00369 } 00370 00371 static uint32_t target_flash_program_page_min_size(uint32_t addr) 00372 { 00373 if (g_board_info.target_cfg){ 00374 uint32_t size = DEFAULT_PROGRAM_PAGE_MIN_SIZE; 00375 if (size > target_flash_erase_sector_size(addr)) { 00376 size = target_flash_erase_sector_size(addr); 00377 } 00378 return size; 00379 } else { 00380 return 0; 00381 } 00382 } 00383 00384 static uint32_t target_flash_erase_sector_size(uint32_t addr) 00385 { 00386 if (g_board_info.target_cfg){ 00387 if(g_board_info.target_cfg->sector_info_length > 0) { 00388 int sector_index = g_board_info.target_cfg->sector_info_length - 1; 00389 for (; sector_index >= 0; sector_index--) { 00390 if (addr >= g_board_info.target_cfg->sectors_info[sector_index].start) { 00391 return g_board_info.target_cfg->sectors_info[sector_index].size; 00392 } 00393 } 00394 } 00395 //sector information should be in sector_info 00396 util_assert(0); 00397 return 0; 00398 } else { 00399 return 0; 00400 } 00401 } 00402 00403 static uint8_t target_flash_busy(void){ 00404 return (state == STATE_OPEN); 00405 } 00406 #endif
Generated on Tue Jul 12 2022 15:37:25 by
1.7.2