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 file_stream.c
Pawel Zarembski 0:01f31e923fe2 3 * @brief Implementation of file_stream.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 "file_stream.h"
Pawel Zarembski 0:01f31e923fe2 25 #include "util.h"
Pawel Zarembski 0:01f31e923fe2 26 #include "intelhex.h"
Pawel Zarembski 0:01f31e923fe2 27 #include "flash_decoder.h"
Pawel Zarembski 0:01f31e923fe2 28 #include "error.h"
Pawel Zarembski 0:01f31e923fe2 29 #include "cmsis_os2.h"
Pawel Zarembski 0:01f31e923fe2 30 #include "compiler.h"
Pawel Zarembski 0:01f31e923fe2 31 #include "validation.h"
Pawel Zarembski 0:01f31e923fe2 32
Pawel Zarembski 0:01f31e923fe2 33 typedef enum {
Pawel Zarembski 0:01f31e923fe2 34 STREAM_STATE_CLOSED,
Pawel Zarembski 0:01f31e923fe2 35 STREAM_STATE_OPEN,
Pawel Zarembski 0:01f31e923fe2 36 STREAM_STATE_END,
Pawel Zarembski 0:01f31e923fe2 37 STREAM_STATE_ERROR
Pawel Zarembski 0:01f31e923fe2 38 } stream_state_t;
Pawel Zarembski 0:01f31e923fe2 39
Pawel Zarembski 0:01f31e923fe2 40 typedef bool (*stream_detect_cb_t)(const uint8_t *data, uint32_t size);
Pawel Zarembski 0:01f31e923fe2 41 typedef error_t (*stream_open_cb_t)(void *state);
Pawel Zarembski 0:01f31e923fe2 42 typedef error_t (*stream_write_cb_t)(void *state, const uint8_t *data, uint32_t size);
Pawel Zarembski 0:01f31e923fe2 43 typedef error_t (*stream_close_cb_t)(void *state);
Pawel Zarembski 0:01f31e923fe2 44
Pawel Zarembski 0:01f31e923fe2 45 typedef struct {
Pawel Zarembski 0:01f31e923fe2 46 stream_detect_cb_t detect;
Pawel Zarembski 0:01f31e923fe2 47 stream_open_cb_t open;
Pawel Zarembski 0:01f31e923fe2 48 stream_write_cb_t write;
Pawel Zarembski 0:01f31e923fe2 49 stream_close_cb_t close;
Pawel Zarembski 0:01f31e923fe2 50 } stream_t;
Pawel Zarembski 0:01f31e923fe2 51
Pawel Zarembski 0:01f31e923fe2 52 typedef struct {
Pawel Zarembski 0:01f31e923fe2 53 uint8_t vector_buf[FLASH_DECODER_MIN_SIZE];
Pawel Zarembski 0:01f31e923fe2 54 uint8_t buf_pos;
Pawel Zarembski 0:01f31e923fe2 55 uint32_t flash_addr;
Pawel Zarembski 0:01f31e923fe2 56 } bin_state_t;
Pawel Zarembski 0:01f31e923fe2 57
Pawel Zarembski 0:01f31e923fe2 58 typedef struct {
Pawel Zarembski 0:01f31e923fe2 59 bool parsing_complete;
Pawel Zarembski 0:01f31e923fe2 60 uint8_t bin_buffer[256];
Pawel Zarembski 0:01f31e923fe2 61 } hex_state_t;
Pawel Zarembski 0:01f31e923fe2 62
Pawel Zarembski 0:01f31e923fe2 63 typedef union {
Pawel Zarembski 0:01f31e923fe2 64 bin_state_t bin;
Pawel Zarembski 0:01f31e923fe2 65 hex_state_t hex;
Pawel Zarembski 0:01f31e923fe2 66 } shared_state_t;
Pawel Zarembski 0:01f31e923fe2 67
Pawel Zarembski 0:01f31e923fe2 68 static bool detect_bin(const uint8_t *data, uint32_t size);
Pawel Zarembski 0:01f31e923fe2 69 static error_t open_bin(void *state);
Pawel Zarembski 0:01f31e923fe2 70 static error_t write_bin(void *state, const uint8_t *data, uint32_t size);
Pawel Zarembski 0:01f31e923fe2 71 static error_t close_bin(void *state);
Pawel Zarembski 0:01f31e923fe2 72
Pawel Zarembski 0:01f31e923fe2 73 static bool detect_hex(const uint8_t *data, uint32_t size);
Pawel Zarembski 0:01f31e923fe2 74 static error_t open_hex(void *state);
Pawel Zarembski 0:01f31e923fe2 75 static error_t write_hex(void *state, const uint8_t *data, uint32_t size);
Pawel Zarembski 0:01f31e923fe2 76 static error_t close_hex(void *state);
Pawel Zarembski 0:01f31e923fe2 77
Pawel Zarembski 0:01f31e923fe2 78 stream_t stream[] = {
Pawel Zarembski 0:01f31e923fe2 79 {detect_bin, open_bin, write_bin, close_bin}, // STREAM_TYPE_BIN
Pawel Zarembski 0:01f31e923fe2 80 {detect_hex, open_hex, write_hex, close_hex}, // STREAM_TYPE_HEX
Pawel Zarembski 0:01f31e923fe2 81 };
Pawel Zarembski 0:01f31e923fe2 82 COMPILER_ASSERT(ARRAY_SIZE(stream) == STREAM_TYPE_COUNT);
Pawel Zarembski 0:01f31e923fe2 83 // STREAM_TYPE_NONE must not be included in count
Pawel Zarembski 0:01f31e923fe2 84 COMPILER_ASSERT(STREAM_TYPE_NONE > STREAM_TYPE_COUNT);
Pawel Zarembski 0:01f31e923fe2 85
Pawel Zarembski 0:01f31e923fe2 86 static shared_state_t shared_state;
Pawel Zarembski 0:01f31e923fe2 87 static stream_state_t state = STREAM_STATE_CLOSED;
Pawel Zarembski 0:01f31e923fe2 88 static stream_t *current_stream = 0;
Pawel Zarembski 0:01f31e923fe2 89
Pawel Zarembski 0:01f31e923fe2 90 // Thread variables (STUB these if RTX is not used)
Pawel Zarembski 0:01f31e923fe2 91 static osThreadId_t stream_thread_tid = 0;
Pawel Zarembski 0:01f31e923fe2 92 static void stream_thread_set(void)
Pawel Zarembski 0:01f31e923fe2 93 {
Pawel Zarembski 0:01f31e923fe2 94 stream_thread_tid = osThreadGetId();
Pawel Zarembski 0:01f31e923fe2 95 }
Pawel Zarembski 0:01f31e923fe2 96 static void stream_thread_assert(void)
Pawel Zarembski 0:01f31e923fe2 97 {
Pawel Zarembski 0:01f31e923fe2 98 util_assert(osThreadGetId() == stream_thread_tid);
Pawel Zarembski 0:01f31e923fe2 99 }
Pawel Zarembski 0:01f31e923fe2 100
Pawel Zarembski 0:01f31e923fe2 101 stream_type_t stream_start_identify(const uint8_t *data, uint32_t size)
Pawel Zarembski 0:01f31e923fe2 102 {
Pawel Zarembski 0:01f31e923fe2 103 stream_type_t i;
Pawel Zarembski 0:01f31e923fe2 104
Pawel Zarembski 0:01f31e923fe2 105 for (i = STREAM_TYPE_START; i < STREAM_TYPE_COUNT; i++) {
Pawel Zarembski 0:01f31e923fe2 106 if (stream[i].detect(data, size)) {
Pawel Zarembski 0:01f31e923fe2 107 return i;
Pawel Zarembski 0:01f31e923fe2 108 }
Pawel Zarembski 0:01f31e923fe2 109 }
Pawel Zarembski 0:01f31e923fe2 110
Pawel Zarembski 0:01f31e923fe2 111 return STREAM_TYPE_NONE;
Pawel Zarembski 0:01f31e923fe2 112 }
Pawel Zarembski 0:01f31e923fe2 113
Pawel Zarembski 0:01f31e923fe2 114 // Identify the file type from its extension
Pawel Zarembski 0:01f31e923fe2 115 stream_type_t stream_type_from_name(const vfs_filename_t filename)
Pawel Zarembski 0:01f31e923fe2 116 {
Pawel Zarembski 0:01f31e923fe2 117 // 8.3 file names must be in upper case
Pawel Zarembski 0:01f31e923fe2 118 if (0 == strncmp("BIN", &filename[8], 3)) {
Pawel Zarembski 0:01f31e923fe2 119 return STREAM_TYPE_BIN;
Pawel Zarembski 0:01f31e923fe2 120 } else if (0 == strncmp("HEX", &filename[8], 3)) {
Pawel Zarembski 0:01f31e923fe2 121 return STREAM_TYPE_HEX;
Pawel Zarembski 0:01f31e923fe2 122 } else {
Pawel Zarembski 0:01f31e923fe2 123 return STREAM_TYPE_NONE;
Pawel Zarembski 0:01f31e923fe2 124 }
Pawel Zarembski 0:01f31e923fe2 125 }
Pawel Zarembski 0:01f31e923fe2 126
Pawel Zarembski 0:01f31e923fe2 127 error_t stream_open(stream_type_t stream_type)
Pawel Zarembski 0:01f31e923fe2 128 {
Pawel Zarembski 0:01f31e923fe2 129 error_t status;
Pawel Zarembski 0:01f31e923fe2 130
Pawel Zarembski 0:01f31e923fe2 131 // Stream must not be open already
Pawel Zarembski 0:01f31e923fe2 132 if (state != STREAM_STATE_CLOSED) {
Pawel Zarembski 0:01f31e923fe2 133 util_assert(0);
Pawel Zarembski 0:01f31e923fe2 134 return ERROR_INTERNAL;
Pawel Zarembski 0:01f31e923fe2 135 }
Pawel Zarembski 0:01f31e923fe2 136
Pawel Zarembski 0:01f31e923fe2 137 // Stream must be of a supported type
Pawel Zarembski 0:01f31e923fe2 138 if (stream_type >= STREAM_TYPE_COUNT) {
Pawel Zarembski 0:01f31e923fe2 139 util_assert(0);
Pawel Zarembski 0:01f31e923fe2 140 return ERROR_INTERNAL;
Pawel Zarembski 0:01f31e923fe2 141 }
Pawel Zarembski 0:01f31e923fe2 142
Pawel Zarembski 0:01f31e923fe2 143 stream_thread_set();
Pawel Zarembski 0:01f31e923fe2 144 // Initialize all variables
Pawel Zarembski 0:01f31e923fe2 145 memset(&shared_state, 0, sizeof(shared_state));
Pawel Zarembski 0:01f31e923fe2 146 state = STREAM_STATE_OPEN;
Pawel Zarembski 0:01f31e923fe2 147 current_stream = &stream[stream_type];
Pawel Zarembski 0:01f31e923fe2 148 // Initialize the specified stream
Pawel Zarembski 0:01f31e923fe2 149 status = current_stream->open(&shared_state);
Pawel Zarembski 0:01f31e923fe2 150
Pawel Zarembski 0:01f31e923fe2 151 if (ERROR_SUCCESS != status) {
Pawel Zarembski 0:01f31e923fe2 152 state = STREAM_STATE_ERROR;
Pawel Zarembski 0:01f31e923fe2 153 }
Pawel Zarembski 0:01f31e923fe2 154
Pawel Zarembski 0:01f31e923fe2 155 return status;
Pawel Zarembski 0:01f31e923fe2 156 }
Pawel Zarembski 0:01f31e923fe2 157
Pawel Zarembski 0:01f31e923fe2 158 error_t stream_write(const uint8_t *data, uint32_t size)
Pawel Zarembski 0:01f31e923fe2 159 {
Pawel Zarembski 0:01f31e923fe2 160 error_t status;
Pawel Zarembski 0:01f31e923fe2 161
Pawel Zarembski 0:01f31e923fe2 162 // Stream must be open already
Pawel Zarembski 0:01f31e923fe2 163 if (state != STREAM_STATE_OPEN) {
Pawel Zarembski 0:01f31e923fe2 164 util_assert(0);
Pawel Zarembski 0:01f31e923fe2 165 return ERROR_INTERNAL;
Pawel Zarembski 0:01f31e923fe2 166 }
Pawel Zarembski 0:01f31e923fe2 167
Pawel Zarembski 0:01f31e923fe2 168 // Check thread after checking state since the stream thread is
Pawel Zarembski 0:01f31e923fe2 169 // set only if stream_open has been called
Pawel Zarembski 0:01f31e923fe2 170 stream_thread_assert();
Pawel Zarembski 0:01f31e923fe2 171 // Write to stream
Pawel Zarembski 0:01f31e923fe2 172 status = current_stream->write(&shared_state, data, size);
Pawel Zarembski 0:01f31e923fe2 173
Pawel Zarembski 0:01f31e923fe2 174 if (ERROR_SUCCESS_DONE == status) {
Pawel Zarembski 0:01f31e923fe2 175 state = STREAM_STATE_END;
Pawel Zarembski 0:01f31e923fe2 176 } else if ((ERROR_SUCCESS_DONE_OR_CONTINUE == status) || (ERROR_SUCCESS == status)) {
Pawel Zarembski 0:01f31e923fe2 177 // Stream should remain in the open state
Pawel Zarembski 0:01f31e923fe2 178 util_assert(STREAM_STATE_OPEN == state);
Pawel Zarembski 0:01f31e923fe2 179 } else {
Pawel Zarembski 0:01f31e923fe2 180 state = STREAM_STATE_ERROR;
Pawel Zarembski 0:01f31e923fe2 181 }
Pawel Zarembski 0:01f31e923fe2 182
Pawel Zarembski 0:01f31e923fe2 183 return status;
Pawel Zarembski 0:01f31e923fe2 184 }
Pawel Zarembski 0:01f31e923fe2 185
Pawel Zarembski 0:01f31e923fe2 186 error_t stream_close(void)
Pawel Zarembski 0:01f31e923fe2 187 {
Pawel Zarembski 0:01f31e923fe2 188 error_t status;
Pawel Zarembski 0:01f31e923fe2 189
Pawel Zarembski 0:01f31e923fe2 190 // Stream must not be closed already
Pawel Zarembski 0:01f31e923fe2 191 if (STREAM_STATE_CLOSED == state) {
Pawel Zarembski 0:01f31e923fe2 192 util_assert(0);
Pawel Zarembski 0:01f31e923fe2 193 return ERROR_INTERNAL;
Pawel Zarembski 0:01f31e923fe2 194 }
Pawel Zarembski 0:01f31e923fe2 195
Pawel Zarembski 0:01f31e923fe2 196 // Check thread after checking state since the stream thread is
Pawel Zarembski 0:01f31e923fe2 197 // set only if stream_open has been called
Pawel Zarembski 0:01f31e923fe2 198 stream_thread_assert();
Pawel Zarembski 0:01f31e923fe2 199 // Close stream
Pawel Zarembski 0:01f31e923fe2 200 status = current_stream->close(&shared_state);
Pawel Zarembski 0:01f31e923fe2 201 state = STREAM_STATE_CLOSED;
Pawel Zarembski 0:01f31e923fe2 202 return status;
Pawel Zarembski 0:01f31e923fe2 203 }
Pawel Zarembski 0:01f31e923fe2 204
Pawel Zarembski 0:01f31e923fe2 205 /* Binary file processing */
Pawel Zarembski 0:01f31e923fe2 206
Pawel Zarembski 0:01f31e923fe2 207 static bool detect_bin(const uint8_t *data, uint32_t size)
Pawel Zarembski 0:01f31e923fe2 208 {
Pawel Zarembski 0:01f31e923fe2 209 return FLASH_DECODER_TYPE_UNKNOWN != flash_decoder_detect_type(data, size, 0, false);
Pawel Zarembski 0:01f31e923fe2 210 }
Pawel Zarembski 0:01f31e923fe2 211
Pawel Zarembski 0:01f31e923fe2 212 static error_t open_bin(void *state)
Pawel Zarembski 0:01f31e923fe2 213 {
Pawel Zarembski 0:01f31e923fe2 214 error_t status;
Pawel Zarembski 0:01f31e923fe2 215 status = flash_decoder_open();
Pawel Zarembski 0:01f31e923fe2 216 return status;
Pawel Zarembski 0:01f31e923fe2 217 }
Pawel Zarembski 0:01f31e923fe2 218
Pawel Zarembski 0:01f31e923fe2 219 static error_t write_bin(void *state, const uint8_t *data, uint32_t size)
Pawel Zarembski 0:01f31e923fe2 220 {
Pawel Zarembski 0:01f31e923fe2 221 error_t status;
Pawel Zarembski 0:01f31e923fe2 222 bin_state_t *bin_state = (bin_state_t *)state;
Pawel Zarembski 0:01f31e923fe2 223
Pawel Zarembski 0:01f31e923fe2 224 if (bin_state->buf_pos < FLASH_DECODER_MIN_SIZE) {
Pawel Zarembski 0:01f31e923fe2 225 flash_decoder_type_t flash_type;
Pawel Zarembski 0:01f31e923fe2 226 uint32_t size_left;
Pawel Zarembski 0:01f31e923fe2 227 uint32_t copy_size;
Pawel Zarembski 0:01f31e923fe2 228 uint32_t start_addr;
Pawel Zarembski 0:01f31e923fe2 229 const flash_intf_t *flash_intf;
Pawel Zarembski 0:01f31e923fe2 230 // Buffer Data
Pawel Zarembski 0:01f31e923fe2 231 size_left = FLASH_DECODER_MIN_SIZE - bin_state->buf_pos;
Pawel Zarembski 0:01f31e923fe2 232 copy_size = MIN(size_left, size);
Pawel Zarembski 0:01f31e923fe2 233 memcpy(bin_state->vector_buf + bin_state->buf_pos, data, copy_size);
Pawel Zarembski 0:01f31e923fe2 234 bin_state->buf_pos += copy_size;
Pawel Zarembski 0:01f31e923fe2 235
Pawel Zarembski 0:01f31e923fe2 236 if (bin_state->buf_pos < FLASH_DECODER_MIN_SIZE) {
Pawel Zarembski 0:01f31e923fe2 237 // Not enough data to determine type
Pawel Zarembski 0:01f31e923fe2 238 return ERROR_SUCCESS;
Pawel Zarembski 0:01f31e923fe2 239 }
Pawel Zarembski 0:01f31e923fe2 240
Pawel Zarembski 0:01f31e923fe2 241 data += copy_size;
Pawel Zarembski 0:01f31e923fe2 242 size -= copy_size;
Pawel Zarembski 0:01f31e923fe2 243 // Determine type
Pawel Zarembski 0:01f31e923fe2 244 flash_type = flash_decoder_detect_type(bin_state->vector_buf, bin_state->buf_pos, 0, false);
Pawel Zarembski 0:01f31e923fe2 245
Pawel Zarembski 0:01f31e923fe2 246 if (FLASH_DECODER_TYPE_UNKNOWN == flash_type) {
Pawel Zarembski 0:01f31e923fe2 247 return ERROR_FD_UNSUPPORTED_UPDATE;
Pawel Zarembski 0:01f31e923fe2 248 }
Pawel Zarembski 0:01f31e923fe2 249
Pawel Zarembski 0:01f31e923fe2 250 // Determine flash addresss
Pawel Zarembski 0:01f31e923fe2 251 status = flash_decoder_get_flash(flash_type, 0, false, &start_addr, &flash_intf);
Pawel Zarembski 0:01f31e923fe2 252
Pawel Zarembski 0:01f31e923fe2 253 if (ERROR_SUCCESS != status) {
Pawel Zarembski 0:01f31e923fe2 254 return status;
Pawel Zarembski 0:01f31e923fe2 255 }
Pawel Zarembski 0:01f31e923fe2 256
Pawel Zarembski 0:01f31e923fe2 257 bin_state->flash_addr = start_addr;
Pawel Zarembski 0:01f31e923fe2 258 // Pass on data to the decoder
Pawel Zarembski 0:01f31e923fe2 259 status = flash_decoder_write(bin_state->flash_addr, bin_state->vector_buf, bin_state->buf_pos);
Pawel Zarembski 0:01f31e923fe2 260
Pawel Zarembski 0:01f31e923fe2 261 if (ERROR_SUCCESS != status) {
Pawel Zarembski 0:01f31e923fe2 262 return status;
Pawel Zarembski 0:01f31e923fe2 263 }
Pawel Zarembski 0:01f31e923fe2 264
Pawel Zarembski 0:01f31e923fe2 265 bin_state->flash_addr += bin_state->buf_pos;
Pawel Zarembski 0:01f31e923fe2 266 }
Pawel Zarembski 0:01f31e923fe2 267
Pawel Zarembski 0:01f31e923fe2 268 // Write data
Pawel Zarembski 0:01f31e923fe2 269 status = flash_decoder_write(bin_state->flash_addr, data, size);
Pawel Zarembski 0:01f31e923fe2 270
Pawel Zarembski 0:01f31e923fe2 271 if (ERROR_SUCCESS != status) {
Pawel Zarembski 0:01f31e923fe2 272 return status;
Pawel Zarembski 0:01f31e923fe2 273 }
Pawel Zarembski 0:01f31e923fe2 274
Pawel Zarembski 0:01f31e923fe2 275 bin_state->flash_addr += size;
Pawel Zarembski 0:01f31e923fe2 276 // There is no way to determine the end of a binary
Pawel Zarembski 0:01f31e923fe2 277 // file so any point could be the end
Pawel Zarembski 0:01f31e923fe2 278 return ERROR_SUCCESS_DONE_OR_CONTINUE;
Pawel Zarembski 0:01f31e923fe2 279 }
Pawel Zarembski 0:01f31e923fe2 280
Pawel Zarembski 0:01f31e923fe2 281 static error_t close_bin(void *state)
Pawel Zarembski 0:01f31e923fe2 282 {
Pawel Zarembski 0:01f31e923fe2 283 error_t status;
Pawel Zarembski 0:01f31e923fe2 284 status = flash_decoder_close();
Pawel Zarembski 0:01f31e923fe2 285 return status;
Pawel Zarembski 0:01f31e923fe2 286 }
Pawel Zarembski 0:01f31e923fe2 287
Pawel Zarembski 0:01f31e923fe2 288 /* Hex file processing */
Pawel Zarembski 0:01f31e923fe2 289
Pawel Zarembski 0:01f31e923fe2 290 static bool detect_hex(const uint8_t *data, uint32_t size)
Pawel Zarembski 0:01f31e923fe2 291 {
Pawel Zarembski 0:01f31e923fe2 292 return 1 == validate_hexfile(data);
Pawel Zarembski 0:01f31e923fe2 293 }
Pawel Zarembski 0:01f31e923fe2 294
Pawel Zarembski 0:01f31e923fe2 295 static error_t open_hex(void *state)
Pawel Zarembski 0:01f31e923fe2 296 {
Pawel Zarembski 0:01f31e923fe2 297 error_t status;
Pawel Zarembski 0:01f31e923fe2 298 hex_state_t *hex_state = (hex_state_t *)state;
Pawel Zarembski 0:01f31e923fe2 299 memset(hex_state, 0, sizeof(*hex_state));
Pawel Zarembski 0:01f31e923fe2 300 reset_hex_parser();
Pawel Zarembski 0:01f31e923fe2 301 hex_state->parsing_complete = false;
Pawel Zarembski 0:01f31e923fe2 302 status = flash_decoder_open();
Pawel Zarembski 0:01f31e923fe2 303 return status;
Pawel Zarembski 0:01f31e923fe2 304 }
Pawel Zarembski 0:01f31e923fe2 305
Pawel Zarembski 0:01f31e923fe2 306 static error_t write_hex(void *state, const uint8_t *data, uint32_t size)
Pawel Zarembski 0:01f31e923fe2 307 {
Pawel Zarembski 0:01f31e923fe2 308 error_t status = ERROR_SUCCESS;
Pawel Zarembski 0:01f31e923fe2 309 hex_state_t *hex_state = (hex_state_t *)state;
Pawel Zarembski 0:01f31e923fe2 310 hexfile_parse_status_t parse_status = HEX_PARSE_UNINIT;
Pawel Zarembski 0:01f31e923fe2 311 uint32_t bin_start_address = 0; // Decoded from the hex file, the binary buffer data starts at this address
Pawel Zarembski 0:01f31e923fe2 312 uint32_t bin_buf_written = 0; // The amount of data in the binary buffer starting at address above
Pawel Zarembski 0:01f31e923fe2 313 uint32_t block_amt_parsed = 0; // amount of data parsed in the block on the last call
Pawel Zarembski 0:01f31e923fe2 314
Pawel Zarembski 0:01f31e923fe2 315 while (1) {
Pawel Zarembski 0:01f31e923fe2 316 // try to decode a block of hex data into bin data
Pawel Zarembski 0:01f31e923fe2 317 parse_status = parse_hex_blob(data, size, &block_amt_parsed, hex_state->bin_buffer, sizeof(hex_state->bin_buffer), &bin_start_address, &bin_buf_written);
Pawel Zarembski 0:01f31e923fe2 318
Pawel Zarembski 0:01f31e923fe2 319 // the entire block of hex was decoded. This is a simple state
Pawel Zarembski 0:01f31e923fe2 320 if (HEX_PARSE_OK == parse_status) {
Pawel Zarembski 0:01f31e923fe2 321 if (bin_buf_written > 0) {
Pawel Zarembski 0:01f31e923fe2 322 status = flash_decoder_write(bin_start_address, hex_state->bin_buffer, bin_buf_written);
Pawel Zarembski 0:01f31e923fe2 323 }
Pawel Zarembski 0:01f31e923fe2 324
Pawel Zarembski 0:01f31e923fe2 325 break;
Pawel Zarembski 0:01f31e923fe2 326 } else if (HEX_PARSE_UNALIGNED == parse_status) {
Pawel Zarembski 0:01f31e923fe2 327 if (bin_buf_written > 0) {
Pawel Zarembski 0:01f31e923fe2 328 status = flash_decoder_write(bin_start_address, hex_state->bin_buffer, bin_buf_written);
Pawel Zarembski 0:01f31e923fe2 329
Pawel Zarembski 0:01f31e923fe2 330 if (ERROR_SUCCESS != status) {
Pawel Zarembski 0:01f31e923fe2 331 break;
Pawel Zarembski 0:01f31e923fe2 332 }
Pawel Zarembski 0:01f31e923fe2 333 }
Pawel Zarembski 0:01f31e923fe2 334
Pawel Zarembski 0:01f31e923fe2 335 // incrememntal offset to finish the block
Pawel Zarembski 0:01f31e923fe2 336 size -= block_amt_parsed;
Pawel Zarembski 0:01f31e923fe2 337 data += block_amt_parsed;
Pawel Zarembski 0:01f31e923fe2 338 } else if (HEX_PARSE_EOF == parse_status) {
Pawel Zarembski 0:01f31e923fe2 339 if (bin_buf_written > 0) {
Pawel Zarembski 0:01f31e923fe2 340 status = flash_decoder_write(bin_start_address, hex_state->bin_buffer, bin_buf_written);
Pawel Zarembski 0:01f31e923fe2 341 }
Pawel Zarembski 0:01f31e923fe2 342
Pawel Zarembski 0:01f31e923fe2 343 if (ERROR_SUCCESS == status) {
Pawel Zarembski 0:01f31e923fe2 344 status = ERROR_SUCCESS_DONE;
Pawel Zarembski 0:01f31e923fe2 345 }
Pawel Zarembski 0:01f31e923fe2 346
Pawel Zarembski 0:01f31e923fe2 347 break;
Pawel Zarembski 0:01f31e923fe2 348 } else if (HEX_PARSE_CKSUM_FAIL == parse_status) {
Pawel Zarembski 0:01f31e923fe2 349 status = ERROR_HEX_CKSUM;
Pawel Zarembski 0:01f31e923fe2 350 break;
Pawel Zarembski 0:01f31e923fe2 351 } else if ((HEX_PARSE_UNINIT == parse_status) || (HEX_PARSE_FAILURE == parse_status)) {
Pawel Zarembski 0:01f31e923fe2 352 util_assert(HEX_PARSE_UNINIT != parse_status);
Pawel Zarembski 0:01f31e923fe2 353 status = ERROR_HEX_PARSER;
Pawel Zarembski 0:01f31e923fe2 354 break;
Pawel Zarembski 0:01f31e923fe2 355 }
Pawel Zarembski 0:01f31e923fe2 356 }
Pawel Zarembski 0:01f31e923fe2 357
Pawel Zarembski 0:01f31e923fe2 358 return status;
Pawel Zarembski 0:01f31e923fe2 359 }
Pawel Zarembski 0:01f31e923fe2 360
Pawel Zarembski 0:01f31e923fe2 361 static error_t close_hex(void *state)
Pawel Zarembski 0:01f31e923fe2 362 {
Pawel Zarembski 0:01f31e923fe2 363 error_t status;
Pawel Zarembski 0:01f31e923fe2 364 status = flash_decoder_close();
Pawel Zarembski 0:01f31e923fe2 365 return status;
Pawel Zarembski 0:01f31e923fe2 366 }