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 flash_decoder.c
Pawel Zarembski 0:01f31e923fe2 3 * @brief Implementation of flash_decoder.h
Pawel Zarembski 0:01f31e923fe2 4 *
Pawel Zarembski 0:01f31e923fe2 5 * DAPLink Interface Firmware
Pawel Zarembski 0:01f31e923fe2 6 * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
Pawel Zarembski 0:01f31e923fe2 7 * SPDX-License-Identifier: Apache-2.0
Pawel Zarembski 0:01f31e923fe2 8 *
Pawel Zarembski 0:01f31e923fe2 9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
Pawel Zarembski 0:01f31e923fe2 10 * not use this file except in compliance with the License.
Pawel Zarembski 0:01f31e923fe2 11 * You may obtain a copy of the License at
Pawel Zarembski 0:01f31e923fe2 12 *
Pawel Zarembski 0:01f31e923fe2 13 * http://www.apache.org/licenses/LICENSE-2.0
Pawel Zarembski 0:01f31e923fe2 14 *
Pawel Zarembski 0:01f31e923fe2 15 * Unless required by applicable law or agreed to in writing, software
Pawel Zarembski 0:01f31e923fe2 16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
Pawel Zarembski 0:01f31e923fe2 17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Pawel Zarembski 0:01f31e923fe2 18 * See the License for the specific language governing permissions and
Pawel Zarembski 0:01f31e923fe2 19 * limitations under the License.
Pawel Zarembski 0:01f31e923fe2 20 */
Pawel Zarembski 0:01f31e923fe2 21
Pawel Zarembski 0:01f31e923fe2 22 #include <string.h>
Pawel Zarembski 0:01f31e923fe2 23
Pawel Zarembski 0:01f31e923fe2 24 #include "flash_decoder.h"
Pawel Zarembski 0:01f31e923fe2 25 #include "util.h"
Pawel Zarembski 0:01f31e923fe2 26 #include "daplink.h"
Pawel Zarembski 0:01f31e923fe2 27 #include "flash_manager.h"
Pawel Zarembski 0:01f31e923fe2 28 #include "target_config.h" // for target_device
Pawel Zarembski 0:01f31e923fe2 29 #include "settings.h" // for config_get_automation_allowed
Pawel Zarembski 0:01f31e923fe2 30 #include "validation.h"
Pawel Zarembski 0:01f31e923fe2 31 #include "target_board.h"
Pawel Zarembski 0:01f31e923fe2 32
Pawel Zarembski 0:01f31e923fe2 33 // Set to 1 to enable debugging
Pawel Zarembski 0:01f31e923fe2 34 #define DEBUG_FLASH_DECODER 0
Pawel Zarembski 0:01f31e923fe2 35
Pawel Zarembski 0:01f31e923fe2 36 #if DEBUG_FLASH_DECODER
Pawel Zarembski 0:01f31e923fe2 37 #include "daplink_debug.h"
Pawel Zarembski 0:01f31e923fe2 38 #define flash_decoder_printf debug_msg
Pawel Zarembski 0:01f31e923fe2 39 #else
Pawel Zarembski 0:01f31e923fe2 40 #define flash_decoder_printf(...)
Pawel Zarembski 0:01f31e923fe2 41 #endif
Pawel Zarembski 0:01f31e923fe2 42
Pawel Zarembski 0:01f31e923fe2 43 typedef enum {
Pawel Zarembski 0:01f31e923fe2 44 DECODER_STATE_CLOSED,
Pawel Zarembski 0:01f31e923fe2 45 DECODER_STATE_OPEN,
Pawel Zarembski 0:01f31e923fe2 46 DECODER_STATE_DONE,
Pawel Zarembski 0:01f31e923fe2 47 DECODER_STATE_ERROR
Pawel Zarembski 0:01f31e923fe2 48 } decoder_state_t;
Pawel Zarembski 0:01f31e923fe2 49
Pawel Zarembski 0:01f31e923fe2 50 static uint8_t flash_buf[FLASH_DECODER_MIN_SIZE];
Pawel Zarembski 0:01f31e923fe2 51 static decoder_state_t state = DECODER_STATE_CLOSED;
Pawel Zarembski 0:01f31e923fe2 52 static flash_decoder_type_t flash_type;
Pawel Zarembski 0:01f31e923fe2 53 static uint32_t flash_buf_pos;
Pawel Zarembski 0:01f31e923fe2 54 static uint32_t initial_addr;
Pawel Zarembski 0:01f31e923fe2 55 static uint32_t current_addr;
Pawel Zarembski 0:01f31e923fe2 56 static bool flash_initialized;
Pawel Zarembski 0:01f31e923fe2 57 static bool initial_addr_set;
Pawel Zarembski 0:01f31e923fe2 58 static bool flash_type_target_bin;
Pawel Zarembski 0:01f31e923fe2 59
Pawel Zarembski 0:01f31e923fe2 60 static bool flash_decoder_is_at_end(uint32_t addr, const uint8_t *data, uint32_t size);
Pawel Zarembski 0:01f31e923fe2 61
Pawel Zarembski 0:01f31e923fe2 62 flash_decoder_type_t flash_decoder_detect_type(const uint8_t *data, uint32_t size, uint32_t addr, bool addr_valid)
Pawel Zarembski 0:01f31e923fe2 63 {
Pawel Zarembski 0:01f31e923fe2 64 daplink_info_t info;
Pawel Zarembski 0:01f31e923fe2 65 util_assert(size >= FLASH_DECODER_MIN_SIZE);
Pawel Zarembski 0:01f31e923fe2 66 // Check if this is a daplink image
Pawel Zarembski 0:01f31e923fe2 67 memcpy(&info, data + DAPLINK_INFO_OFFSET, sizeof(info));
Pawel Zarembski 0:01f31e923fe2 68 if(!addr_valid){ //reset until we know the binary type
Pawel Zarembski 0:01f31e923fe2 69 flash_type_target_bin = false;
Pawel Zarembski 0:01f31e923fe2 70 }
Pawel Zarembski 0:01f31e923fe2 71 if (DAPLINK_HIC_ID == info.hic_id) {
Pawel Zarembski 0:01f31e923fe2 72 if (DAPLINK_BUILD_KEY_IF == info.build_key) {
Pawel Zarembski 0:01f31e923fe2 73 // Interface update
Pawel Zarembski 0:01f31e923fe2 74 return FLASH_DECODER_TYPE_INTERFACE;
Pawel Zarembski 0:01f31e923fe2 75 } else if (DAPLINK_BUILD_KEY_BL == info.build_key) {
Pawel Zarembski 0:01f31e923fe2 76 // Bootloader update
Pawel Zarembski 0:01f31e923fe2 77 return FLASH_DECODER_TYPE_BOOTLOADER;
Pawel Zarembski 0:01f31e923fe2 78 } else {
Pawel Zarembski 0:01f31e923fe2 79 return FLASH_DECODER_TYPE_UNKNOWN;
Pawel Zarembski 0:01f31e923fe2 80 }
Pawel Zarembski 0:01f31e923fe2 81 }
Pawel Zarembski 0:01f31e923fe2 82
Pawel Zarembski 0:01f31e923fe2 83 // Check if a valid vector table for the target can be found
Pawel Zarembski 0:01f31e923fe2 84 if (validate_bin_nvic(data)) {
Pawel Zarembski 0:01f31e923fe2 85 if(!addr_valid){ //binary is a bin type
Pawel Zarembski 0:01f31e923fe2 86 flash_type_target_bin = true;
Pawel Zarembski 0:01f31e923fe2 87 }
Pawel Zarembski 0:01f31e923fe2 88 return FLASH_DECODER_TYPE_TARGET;
Pawel Zarembski 0:01f31e923fe2 89 }
Pawel Zarembski 0:01f31e923fe2 90
Pawel Zarembski 0:01f31e923fe2 91 // If an address is specified then the data can be decoded
Pawel Zarembski 0:01f31e923fe2 92 if (addr_valid) {
Pawel Zarembski 0:01f31e923fe2 93 // TODO - future improvement - make sure address is within target's flash
Pawel Zarembski 0:01f31e923fe2 94 return FLASH_DECODER_TYPE_TARGET;
Pawel Zarembski 0:01f31e923fe2 95 }
Pawel Zarembski 0:01f31e923fe2 96
Pawel Zarembski 0:01f31e923fe2 97 return FLASH_DECODER_TYPE_UNKNOWN;
Pawel Zarembski 0:01f31e923fe2 98 }
Pawel Zarembski 0:01f31e923fe2 99
Pawel Zarembski 0:01f31e923fe2 100 error_t flash_decoder_get_flash(flash_decoder_type_t type, uint32_t addr, bool addr_valid, uint32_t *start_addr, const flash_intf_t **flash_intf)
Pawel Zarembski 0:01f31e923fe2 101 {
Pawel Zarembski 0:01f31e923fe2 102 error_t status = ERROR_SUCCESS;
Pawel Zarembski 0:01f31e923fe2 103 uint32_t flash_start_local;
Pawel Zarembski 0:01f31e923fe2 104 const flash_intf_t *flash_intf_local = 0;
Pawel Zarembski 0:01f31e923fe2 105
Pawel Zarembski 0:01f31e923fe2 106 if ((0 == start_addr) || (0 == flash_intf)) {
Pawel Zarembski 0:01f31e923fe2 107 util_assert(0);
Pawel Zarembski 0:01f31e923fe2 108 return ERROR_INTERNAL;
Pawel Zarembski 0:01f31e923fe2 109 }
Pawel Zarembski 0:01f31e923fe2 110
Pawel Zarembski 0:01f31e923fe2 111 *start_addr = 0;
Pawel Zarembski 0:01f31e923fe2 112 *flash_intf = 0;
Pawel Zarembski 0:01f31e923fe2 113 flash_start_local = 0;
Pawel Zarembski 0:01f31e923fe2 114 flash_intf_local = 0;
Pawel Zarembski 0:01f31e923fe2 115
Pawel Zarembski 0:01f31e923fe2 116 if (daplink_is_bootloader()) {
Pawel Zarembski 0:01f31e923fe2 117 if (FLASH_DECODER_TYPE_INTERFACE == type) {
Pawel Zarembski 0:01f31e923fe2 118 if (addr_valid && (DAPLINK_ROM_IF_START != addr)) {
Pawel Zarembski 0:01f31e923fe2 119 // Address is wrong so display error message
Pawel Zarembski 0:01f31e923fe2 120 status = ERROR_FD_INTF_UPDT_ADDR_WRONG;
Pawel Zarembski 0:01f31e923fe2 121 } else {
Pawel Zarembski 0:01f31e923fe2 122 // Setup for update
Pawel Zarembski 0:01f31e923fe2 123 flash_start_local = DAPLINK_ROM_IF_START;
Pawel Zarembski 0:01f31e923fe2 124 flash_intf_local = flash_intf_iap_protected;
Pawel Zarembski 0:01f31e923fe2 125 }
Pawel Zarembski 0:01f31e923fe2 126 } else if (FLASH_DECODER_TYPE_TARGET == type) {
Pawel Zarembski 0:01f31e923fe2 127 // "Target" update in this case would be a 3rd party interface application
Pawel Zarembski 0:01f31e923fe2 128 flash_start_local = DAPLINK_ROM_IF_START;
Pawel Zarembski 0:01f31e923fe2 129 flash_intf_local = flash_intf_iap_protected;
Pawel Zarembski 0:01f31e923fe2 130 } else {
Pawel Zarembski 0:01f31e923fe2 131 status = ERROR_FD_UNSUPPORTED_UPDATE;
Pawel Zarembski 0:01f31e923fe2 132 }
Pawel Zarembski 0:01f31e923fe2 133 } else if (daplink_is_interface()) {
Pawel Zarembski 0:01f31e923fe2 134 if (FLASH_DECODER_TYPE_BOOTLOADER == type) {
Pawel Zarembski 0:01f31e923fe2 135 if (addr_valid && (DAPLINK_ROM_BL_START != addr)) {
Pawel Zarembski 0:01f31e923fe2 136 // Address is wrong so display error message
Pawel Zarembski 0:01f31e923fe2 137 status = ERROR_FD_BL_UPDT_ADDR_WRONG;
Pawel Zarembski 0:01f31e923fe2 138 } else {
Pawel Zarembski 0:01f31e923fe2 139 // Setup for update
Pawel Zarembski 0:01f31e923fe2 140 flash_start_local = DAPLINK_ROM_BL_START;
Pawel Zarembski 0:01f31e923fe2 141 flash_intf_local = flash_intf_iap_protected;
Pawel Zarembski 0:01f31e923fe2 142 }
Pawel Zarembski 0:01f31e923fe2 143 } else if (FLASH_DECODER_TYPE_TARGET == type) {
Pawel Zarembski 0:01f31e923fe2 144 if (g_board_info.target_cfg) {
Pawel Zarembski 0:01f31e923fe2 145 region_info_t * region = g_board_info.target_cfg->flash_regions;
Pawel Zarembski 0:01f31e923fe2 146 for (; region->start != 0 || region->end != 0; ++region) {
Pawel Zarembski 0:01f31e923fe2 147 if (kRegionIsDefault == region->flags) {
Pawel Zarembski 0:01f31e923fe2 148 flash_start_local = region->start;
Pawel Zarembski 0:01f31e923fe2 149 break;
Pawel Zarembski 0:01f31e923fe2 150 }
Pawel Zarembski 0:01f31e923fe2 151 }
Pawel Zarembski 0:01f31e923fe2 152 flash_intf_local = flash_intf_target;
Pawel Zarembski 0:01f31e923fe2 153 } else {
Pawel Zarembski 0:01f31e923fe2 154 status = ERROR_FD_UNSUPPORTED_UPDATE;
Pawel Zarembski 0:01f31e923fe2 155 }
Pawel Zarembski 0:01f31e923fe2 156 } else {
Pawel Zarembski 0:01f31e923fe2 157 status = ERROR_FD_UNSUPPORTED_UPDATE;
Pawel Zarembski 0:01f31e923fe2 158 }
Pawel Zarembski 0:01f31e923fe2 159 } else {
Pawel Zarembski 0:01f31e923fe2 160 status = ERROR_FD_UNSUPPORTED_UPDATE;
Pawel Zarembski 0:01f31e923fe2 161 }
Pawel Zarembski 0:01f31e923fe2 162
Pawel Zarembski 0:01f31e923fe2 163 // Don't allow bootloader updates unless automation is allowed
Pawel Zarembski 0:01f31e923fe2 164 if (!config_get_automation_allowed() && (FLASH_DECODER_TYPE_BOOTLOADER == type)) {
Pawel Zarembski 0:01f31e923fe2 165 status = ERROR_FD_UNSUPPORTED_UPDATE;
Pawel Zarembski 0:01f31e923fe2 166 }
Pawel Zarembski 0:01f31e923fe2 167
Pawel Zarembski 0:01f31e923fe2 168 if (ERROR_SUCCESS != status) {
Pawel Zarembski 0:01f31e923fe2 169 return status;
Pawel Zarembski 0:01f31e923fe2 170 }
Pawel Zarembski 0:01f31e923fe2 171
Pawel Zarembski 0:01f31e923fe2 172 if (0 == flash_intf_local) {
Pawel Zarembski 0:01f31e923fe2 173 util_assert(0);
Pawel Zarembski 0:01f31e923fe2 174 return ERROR_INTERNAL;
Pawel Zarembski 0:01f31e923fe2 175 }
Pawel Zarembski 0:01f31e923fe2 176
Pawel Zarembski 0:01f31e923fe2 177 *start_addr = flash_start_local;
Pawel Zarembski 0:01f31e923fe2 178 *flash_intf = flash_intf_local;
Pawel Zarembski 0:01f31e923fe2 179 return status;
Pawel Zarembski 0:01f31e923fe2 180 }
Pawel Zarembski 0:01f31e923fe2 181
Pawel Zarembski 0:01f31e923fe2 182 error_t flash_decoder_open(void)
Pawel Zarembski 0:01f31e923fe2 183 {
Pawel Zarembski 0:01f31e923fe2 184 flash_decoder_printf("flash_decoder_open()\r\n");
Pawel Zarembski 0:01f31e923fe2 185
Pawel Zarembski 0:01f31e923fe2 186 // Stream must not be open already
Pawel Zarembski 0:01f31e923fe2 187 if (state != DECODER_STATE_CLOSED) {
Pawel Zarembski 0:01f31e923fe2 188 util_assert(0);
Pawel Zarembski 0:01f31e923fe2 189 return ERROR_INTERNAL;
Pawel Zarembski 0:01f31e923fe2 190 }
Pawel Zarembski 0:01f31e923fe2 191
Pawel Zarembski 0:01f31e923fe2 192 memset(flash_buf, 0xff, sizeof(flash_buf));
Pawel Zarembski 0:01f31e923fe2 193 state = DECODER_STATE_OPEN;
Pawel Zarembski 0:01f31e923fe2 194 flash_type = FLASH_DECODER_TYPE_UNKNOWN;
Pawel Zarembski 0:01f31e923fe2 195 flash_buf_pos = 0;
Pawel Zarembski 0:01f31e923fe2 196 initial_addr = 0;
Pawel Zarembski 0:01f31e923fe2 197 current_addr = 0;
Pawel Zarembski 0:01f31e923fe2 198 flash_initialized = false;
Pawel Zarembski 0:01f31e923fe2 199 initial_addr_set = false;
Pawel Zarembski 0:01f31e923fe2 200 return ERROR_SUCCESS;
Pawel Zarembski 0:01f31e923fe2 201 }
Pawel Zarembski 0:01f31e923fe2 202
Pawel Zarembski 0:01f31e923fe2 203 error_t flash_decoder_write(uint32_t addr, const uint8_t *data, uint32_t size)
Pawel Zarembski 0:01f31e923fe2 204 {
Pawel Zarembski 0:01f31e923fe2 205 error_t status;
Pawel Zarembski 0:01f31e923fe2 206 flash_decoder_printf("flash_decoder_write(addr=0x%x, size=0x%x)\r\n", addr, size);
Pawel Zarembski 0:01f31e923fe2 207
Pawel Zarembski 0:01f31e923fe2 208 if (DECODER_STATE_OPEN != state) {
Pawel Zarembski 0:01f31e923fe2 209 util_assert(0);
Pawel Zarembski 0:01f31e923fe2 210 return ERROR_INTERNAL;
Pawel Zarembski 0:01f31e923fe2 211 }
Pawel Zarembski 0:01f31e923fe2 212
Pawel Zarembski 0:01f31e923fe2 213 // Set the initial address the first time through
Pawel Zarembski 0:01f31e923fe2 214 if (!initial_addr_set) {
Pawel Zarembski 0:01f31e923fe2 215 initial_addr = addr;
Pawel Zarembski 0:01f31e923fe2 216 current_addr = initial_addr;
Pawel Zarembski 0:01f31e923fe2 217 flash_decoder_printf(" initial_addr=0x%x\r\n", initial_addr);
Pawel Zarembski 0:01f31e923fe2 218 initial_addr_set = true;
Pawel Zarembski 0:01f31e923fe2 219 }
Pawel Zarembski 0:01f31e923fe2 220
Pawel Zarembski 0:01f31e923fe2 221 if (!flash_initialized) {
Pawel Zarembski 0:01f31e923fe2 222 uint32_t copy_size;
Pawel Zarembski 0:01f31e923fe2 223 bool flash_type_known = false;
Pawel Zarembski 0:01f31e923fe2 224 bool sequential;
Pawel Zarembski 0:01f31e923fe2 225 // Check if the data is sequential
Pawel Zarembski 0:01f31e923fe2 226 sequential = addr == current_addr;
Pawel Zarembski 0:01f31e923fe2 227 current_addr += size;
Pawel Zarembski 0:01f31e923fe2 228
Pawel Zarembski 0:01f31e923fe2 229 // Buffer data until the flash type is known
Pawel Zarembski 0:01f31e923fe2 230 if (sequential) {
Pawel Zarembski 0:01f31e923fe2 231 // Copy data into buffer
Pawel Zarembski 0:01f31e923fe2 232 copy_size = MIN(size, sizeof(flash_buf) - flash_buf_pos);
Pawel Zarembski 0:01f31e923fe2 233 memcpy(&flash_buf[flash_buf_pos], data, copy_size);
Pawel Zarembski 0:01f31e923fe2 234 flash_buf_pos += copy_size;
Pawel Zarembski 0:01f31e923fe2 235 flash_decoder_printf(" buffering %i bytes\r\n", copy_size);
Pawel Zarembski 0:01f31e923fe2 236 // Update vars so they no longer include the buffered data
Pawel Zarembski 0:01f31e923fe2 237 data += copy_size;
Pawel Zarembski 0:01f31e923fe2 238 size -= copy_size;
Pawel Zarembski 0:01f31e923fe2 239 addr += copy_size;
Pawel Zarembski 0:01f31e923fe2 240
Pawel Zarembski 0:01f31e923fe2 241 // If enough data has been buffered then determine the type
Pawel Zarembski 0:01f31e923fe2 242 if (flash_buf_pos >= sizeof(flash_buf)) {
Pawel Zarembski 0:01f31e923fe2 243 util_assert(sizeof(flash_buf) == flash_buf_pos);
Pawel Zarembski 0:01f31e923fe2 244 // Determine flash type and get info for it
Pawel Zarembski 0:01f31e923fe2 245 flash_type = flash_decoder_detect_type(flash_buf, flash_buf_pos, initial_addr, true);
Pawel Zarembski 0:01f31e923fe2 246 flash_decoder_printf(" Buffering complete, setting flash_type=%i\r\n", flash_type);
Pawel Zarembski 0:01f31e923fe2 247 flash_type_known = true;
Pawel Zarembski 0:01f31e923fe2 248 }
Pawel Zarembski 0:01f31e923fe2 249 } else {
Pawel Zarembski 0:01f31e923fe2 250 flash_type = FLASH_DECODER_TYPE_TARGET;
Pawel Zarembski 0:01f31e923fe2 251 flash_decoder_printf(" Non sequential addr, setting flash_type=%i\r\n", flash_type);
Pawel Zarembski 0:01f31e923fe2 252 flash_type_known = true;
Pawel Zarembski 0:01f31e923fe2 253 }
Pawel Zarembski 0:01f31e923fe2 254
Pawel Zarembski 0:01f31e923fe2 255 // If flash type is known initialize the flash manager
Pawel Zarembski 0:01f31e923fe2 256 if (flash_type_known) {
Pawel Zarembski 0:01f31e923fe2 257 const flash_intf_t *flash_intf;
Pawel Zarembski 0:01f31e923fe2 258 uint32_t flash_start_addr;
Pawel Zarembski 0:01f31e923fe2 259 status = flash_decoder_get_flash(flash_type, initial_addr, true, &flash_start_addr, &flash_intf);
Pawel Zarembski 0:01f31e923fe2 260
Pawel Zarembski 0:01f31e923fe2 261 if (ERROR_SUCCESS != status) {
Pawel Zarembski 0:01f31e923fe2 262 state = DECODER_STATE_ERROR;
Pawel Zarembski 0:01f31e923fe2 263 return status;
Pawel Zarembski 0:01f31e923fe2 264 }
Pawel Zarembski 0:01f31e923fe2 265
Pawel Zarembski 0:01f31e923fe2 266 flash_decoder_printf(" flash_start_addr=0x%x\r\n", flash_start_addr);
Pawel Zarembski 0:01f31e923fe2 267 // Initialize flash manager
Pawel Zarembski 0:01f31e923fe2 268 util_assert(!flash_initialized);
Pawel Zarembski 0:01f31e923fe2 269 status = flash_manager_init(flash_intf);
Pawel Zarembski 0:01f31e923fe2 270 flash_decoder_printf(" flash_manager_init ret %i\r\n", status);
Pawel Zarembski 0:01f31e923fe2 271
Pawel Zarembski 0:01f31e923fe2 272 if (ERROR_SUCCESS != status) {
Pawel Zarembski 0:01f31e923fe2 273 state = DECODER_STATE_ERROR;
Pawel Zarembski 0:01f31e923fe2 274 return status;
Pawel Zarembski 0:01f31e923fe2 275 }
Pawel Zarembski 0:01f31e923fe2 276
Pawel Zarembski 0:01f31e923fe2 277 flash_initialized = true;
Pawel Zarembski 0:01f31e923fe2 278 }
Pawel Zarembski 0:01f31e923fe2 279
Pawel Zarembski 0:01f31e923fe2 280 // If flash has been initalized then write out buffered data
Pawel Zarembski 0:01f31e923fe2 281 if (flash_initialized) {
Pawel Zarembski 0:01f31e923fe2 282 status = flash_manager_data(initial_addr, flash_buf, flash_buf_pos);
Pawel Zarembski 0:01f31e923fe2 283 flash_decoder_printf(" Flushing buffer initial_addr=0x%x, flash_buf_pos=%i, flash_manager_data ret=%i\r\n",
Pawel Zarembski 0:01f31e923fe2 284 initial_addr, flash_buf_pos, status);
Pawel Zarembski 0:01f31e923fe2 285
Pawel Zarembski 0:01f31e923fe2 286 if (ERROR_SUCCESS != status) {
Pawel Zarembski 0:01f31e923fe2 287 state = DECODER_STATE_ERROR;
Pawel Zarembski 0:01f31e923fe2 288 return status;
Pawel Zarembski 0:01f31e923fe2 289 }
Pawel Zarembski 0:01f31e923fe2 290 }
Pawel Zarembski 0:01f31e923fe2 291 }
Pawel Zarembski 0:01f31e923fe2 292
Pawel Zarembski 0:01f31e923fe2 293 // Write data as normal if flash has been initialized
Pawel Zarembski 0:01f31e923fe2 294 if (flash_initialized) {
Pawel Zarembski 0:01f31e923fe2 295 status = flash_manager_data(addr, data, size);
Pawel Zarembski 0:01f31e923fe2 296 flash_decoder_printf(" Writing data, addr=0x%x, size=0x%x, flash_manager_data ret %i\r\n",
Pawel Zarembski 0:01f31e923fe2 297 addr, size, status);
Pawel Zarembski 0:01f31e923fe2 298
Pawel Zarembski 0:01f31e923fe2 299 if (ERROR_SUCCESS != status) {
Pawel Zarembski 0:01f31e923fe2 300 state = DECODER_STATE_ERROR;
Pawel Zarembski 0:01f31e923fe2 301 return status;
Pawel Zarembski 0:01f31e923fe2 302 }
Pawel Zarembski 0:01f31e923fe2 303 }
Pawel Zarembski 0:01f31e923fe2 304
Pawel Zarembski 0:01f31e923fe2 305 // Check if this is the end of data
Pawel Zarembski 0:01f31e923fe2 306 if (flash_decoder_is_at_end(addr, data, size)) {
Pawel Zarembski 0:01f31e923fe2 307 flash_decoder_printf(" End of transfer detected - addr 0x%08x, size 0x%08x\r\n",
Pawel Zarembski 0:01f31e923fe2 308 addr, size);
Pawel Zarembski 0:01f31e923fe2 309 state = DECODER_STATE_DONE;
Pawel Zarembski 0:01f31e923fe2 310 return ERROR_SUCCESS_DONE;
Pawel Zarembski 0:01f31e923fe2 311 }
Pawel Zarembski 0:01f31e923fe2 312
Pawel Zarembski 0:01f31e923fe2 313 return ERROR_SUCCESS;
Pawel Zarembski 0:01f31e923fe2 314 }
Pawel Zarembski 0:01f31e923fe2 315
Pawel Zarembski 0:01f31e923fe2 316 error_t flash_decoder_close(void)
Pawel Zarembski 0:01f31e923fe2 317 {
Pawel Zarembski 0:01f31e923fe2 318 error_t status = ERROR_SUCCESS;
Pawel Zarembski 0:01f31e923fe2 319 decoder_state_t prev_state = state;
Pawel Zarembski 0:01f31e923fe2 320 flash_decoder_printf("flash_decoder_close()\r\n");
Pawel Zarembski 0:01f31e923fe2 321
Pawel Zarembski 0:01f31e923fe2 322 if (DECODER_STATE_CLOSED == state) {
Pawel Zarembski 0:01f31e923fe2 323 util_assert(0);
Pawel Zarembski 0:01f31e923fe2 324 return ERROR_INTERNAL;
Pawel Zarembski 0:01f31e923fe2 325 }
Pawel Zarembski 0:01f31e923fe2 326
Pawel Zarembski 0:01f31e923fe2 327 state = DECODER_STATE_CLOSED;
Pawel Zarembski 0:01f31e923fe2 328
Pawel Zarembski 0:01f31e923fe2 329 if (flash_initialized) {
Pawel Zarembski 0:01f31e923fe2 330 status = flash_manager_uninit();
Pawel Zarembski 0:01f31e923fe2 331 flash_decoder_printf(" flash_manager_uninit ret %i\r\n", status);
Pawel Zarembski 0:01f31e923fe2 332 }
Pawel Zarembski 0:01f31e923fe2 333
Pawel Zarembski 0:01f31e923fe2 334 if ((DECODER_STATE_DONE != prev_state) &&
Pawel Zarembski 0:01f31e923fe2 335 (flash_type != FLASH_DECODER_TYPE_TARGET) &&
Pawel Zarembski 0:01f31e923fe2 336 (status == ERROR_SUCCESS)) {
Pawel Zarembski 0:01f31e923fe2 337 status = ERROR_IAP_UPDT_INCOMPLETE;
Pawel Zarembski 0:01f31e923fe2 338 }
Pawel Zarembski 0:01f31e923fe2 339
Pawel Zarembski 0:01f31e923fe2 340 return status;
Pawel Zarembski 0:01f31e923fe2 341 }
Pawel Zarembski 0:01f31e923fe2 342
Pawel Zarembski 0:01f31e923fe2 343 static bool flash_decoder_is_at_end(uint32_t addr, const uint8_t *data, uint32_t size)
Pawel Zarembski 0:01f31e923fe2 344 {
Pawel Zarembski 0:01f31e923fe2 345 uint32_t end_addr=0;
Pawel Zarembski 0:01f31e923fe2 346
Pawel Zarembski 0:01f31e923fe2 347 switch (flash_type) {
Pawel Zarembski 0:01f31e923fe2 348 case FLASH_DECODER_TYPE_BOOTLOADER:
Pawel Zarembski 0:01f31e923fe2 349 end_addr = DAPLINK_ROM_BL_START + DAPLINK_ROM_BL_SIZE;
Pawel Zarembski 0:01f31e923fe2 350 break;
Pawel Zarembski 0:01f31e923fe2 351
Pawel Zarembski 0:01f31e923fe2 352 case FLASH_DECODER_TYPE_INTERFACE:
Pawel Zarembski 0:01f31e923fe2 353 end_addr = DAPLINK_ROM_IF_START + DAPLINK_ROM_IF_SIZE;
Pawel Zarembski 0:01f31e923fe2 354 break;
Pawel Zarembski 0:01f31e923fe2 355
Pawel Zarembski 0:01f31e923fe2 356 case FLASH_DECODER_TYPE_TARGET:
Pawel Zarembski 0:01f31e923fe2 357 //only if we are sure it is a bin for the target; without check unordered hex files will cause to terminate flashing
Pawel Zarembski 0:01f31e923fe2 358 if (flash_type_target_bin && g_board_info.target_cfg) {
Pawel Zarembski 0:01f31e923fe2 359 region_info_t * region = g_board_info.target_cfg->flash_regions;
Pawel Zarembski 0:01f31e923fe2 360 for (; region->start != 0 || region->end != 0; ++region) {
Pawel Zarembski 0:01f31e923fe2 361 if (addr >= region->start && addr<=region->end) {
Pawel Zarembski 0:01f31e923fe2 362 end_addr = region->end;
Pawel Zarembski 0:01f31e923fe2 363 break;
Pawel Zarembski 0:01f31e923fe2 364 }
Pawel Zarembski 0:01f31e923fe2 365 }
Pawel Zarembski 0:01f31e923fe2 366 if(end_addr == 0){ //invalid end_addr
Pawel Zarembski 0:01f31e923fe2 367 return false;
Pawel Zarembski 0:01f31e923fe2 368 }
Pawel Zarembski 0:01f31e923fe2 369
Pawel Zarembski 0:01f31e923fe2 370 }
Pawel Zarembski 0:01f31e923fe2 371 else {
Pawel Zarembski 0:01f31e923fe2 372 return false;
Pawel Zarembski 0:01f31e923fe2 373 }
Pawel Zarembski 0:01f31e923fe2 374 break;
Pawel Zarembski 0:01f31e923fe2 375
Pawel Zarembski 0:01f31e923fe2 376 default:
Pawel Zarembski 0:01f31e923fe2 377 return false;
Pawel Zarembski 0:01f31e923fe2 378 }
Pawel Zarembski 0:01f31e923fe2 379
Pawel Zarembski 0:01f31e923fe2 380 if (addr + size >= end_addr) {
Pawel Zarembski 0:01f31e923fe2 381 return true;
Pawel Zarembski 0:01f31e923fe2 382 } else {
Pawel Zarembski 0:01f31e923fe2 383 return false;
Pawel Zarembski 0:01f31e923fe2 384 }
Pawel Zarembski 0:01f31e923fe2 385 }