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 settings_rom.c
Pawel Zarembski 0:01f31e923fe2 3 * @brief Implementation of settings.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 "settings.h"
Pawel Zarembski 0:01f31e923fe2 25 #include "target_config.h"
Pawel Zarembski 0:01f31e923fe2 26 #include "compiler.h"
Pawel Zarembski 0:01f31e923fe2 27 #include "cortex_m.h"
Pawel Zarembski 0:01f31e923fe2 28 #include "FlashPrg.h"
Pawel Zarembski 0:01f31e923fe2 29
Pawel Zarembski 0:01f31e923fe2 30 // 'kvld' in hex - key valid
Pawel Zarembski 0:01f31e923fe2 31 #define CFG_KEY 0x6b766c64
Pawel Zarembski 0:01f31e923fe2 32 #define SECTOR_BUFFER_SIZE 16
Pawel Zarembski 0:01f31e923fe2 33
Pawel Zarembski 0:01f31e923fe2 34 // WARNING - THIS STRUCTURE RESIDES IN NON-VOLATILE STORAGE!
Pawel Zarembski 0:01f31e923fe2 35 // Be careful with changes:
Pawel Zarembski 0:01f31e923fe2 36 // -Only add new members to end end of this structure
Pawel Zarembski 0:01f31e923fe2 37 // -Do not change the order of members in this structure
Pawel Zarembski 0:01f31e923fe2 38 // -Structure must remain packed so no padding bytes are added
Pawel Zarembski 0:01f31e923fe2 39 typedef struct __attribute__((__packed__)) cfg_setting {
Pawel Zarembski 0:01f31e923fe2 40 uint32_t key; // Magic key to indicate a valid record
Pawel Zarembski 0:01f31e923fe2 41 uint16_t size; // Size of cfg_setting_t
Pawel Zarembski 0:01f31e923fe2 42
Pawel Zarembski 0:01f31e923fe2 43 // Configurable values
Pawel Zarembski 0:01f31e923fe2 44 uint8_t auto_rst;
Pawel Zarembski 0:01f31e923fe2 45 uint8_t automation_allowed;
Pawel Zarembski 0:01f31e923fe2 46 uint8_t overflow_detect;
Pawel Zarembski 0:01f31e923fe2 47
Pawel Zarembski 0:01f31e923fe2 48 // Add new members here
Pawel Zarembski 0:01f31e923fe2 49
Pawel Zarembski 0:01f31e923fe2 50 } cfg_setting_t;
Pawel Zarembski 0:01f31e923fe2 51
Pawel Zarembski 0:01f31e923fe2 52 // Make sure FORMAT in generate_config.py is updated if size changes
Pawel Zarembski 0:01f31e923fe2 53 COMPILER_ASSERT(sizeof(cfg_setting_t) == 9);
Pawel Zarembski 0:01f31e923fe2 54
Pawel Zarembski 0:01f31e923fe2 55 // Sector buffer must be as big or bigger than settings
Pawel Zarembski 0:01f31e923fe2 56 COMPILER_ASSERT(sizeof(cfg_setting_t) < SECTOR_BUFFER_SIZE);
Pawel Zarembski 0:01f31e923fe2 57 // Sector buffer must be a multiple of 4 bytes at least.
Pawel Zarembski 0:01f31e923fe2 58 // ProgramPage for some interfaces, like the k20dx, require that
Pawel Zarembski 0:01f31e923fe2 59 // the data is a multiple of 4 bytes, otherwise programming will
Pawel Zarembski 0:01f31e923fe2 60 // fail. Assert 8 byte alignement just to be safe.
Pawel Zarembski 0:01f31e923fe2 61 COMPILER_ASSERT(SECTOR_BUFFER_SIZE % 8 == 0);
Pawel Zarembski 0:01f31e923fe2 62
Pawel Zarembski 0:01f31e923fe2 63 // Configuration ROM
Pawel Zarembski 0:01f31e923fe2 64 static volatile const cfg_setting_t config_rom __attribute__((section("cfgrom"), zero_init));
Pawel Zarembski 0:01f31e923fe2 65 // Ram copy of ROM config
Pawel Zarembski 0:01f31e923fe2 66 static cfg_setting_t config_rom_copy;
Pawel Zarembski 0:01f31e923fe2 67
Pawel Zarembski 0:01f31e923fe2 68 // Configuration defaults in flash
Pawel Zarembski 0:01f31e923fe2 69 static const cfg_setting_t config_default = {
Pawel Zarembski 0:01f31e923fe2 70 .auto_rst = 1,
Pawel Zarembski 0:01f31e923fe2 71 .automation_allowed = 1,
Pawel Zarembski 0:01f31e923fe2 72 .overflow_detect = 1,
Pawel Zarembski 0:01f31e923fe2 73 };
Pawel Zarembski 0:01f31e923fe2 74
Pawel Zarembski 0:01f31e923fe2 75 // Buffer for data to flash
Pawel Zarembski 0:01f31e923fe2 76 static uint32_t write_buffer[SECTOR_BUFFER_SIZE / 4];
Pawel Zarembski 0:01f31e923fe2 77
Pawel Zarembski 0:01f31e923fe2 78 // Check if the configuration in flash needs to be updated
Pawel Zarembski 0:01f31e923fe2 79 static bool config_needs_update()
Pawel Zarembski 0:01f31e923fe2 80 {
Pawel Zarembski 0:01f31e923fe2 81 // Update if the key is invalid
Pawel Zarembski 0:01f31e923fe2 82 if (CFG_KEY != config_rom.key) {
Pawel Zarembski 0:01f31e923fe2 83 return true;
Pawel Zarembski 0:01f31e923fe2 84 }
Pawel Zarembski 0:01f31e923fe2 85
Pawel Zarembski 0:01f31e923fe2 86 // Update if the config key is valid but
Pawel Zarembski 0:01f31e923fe2 87 // has a smaller size.
Pawel Zarembski 0:01f31e923fe2 88 if (config_rom.size < sizeof(config_rom)) {
Pawel Zarembski 0:01f31e923fe2 89 return true;
Pawel Zarembski 0:01f31e923fe2 90 }
Pawel Zarembski 0:01f31e923fe2 91
Pawel Zarembski 0:01f31e923fe2 92 // The config is valid and has the right
Pawel Zarembski 0:01f31e923fe2 93 // size so it does not need to be updated
Pawel Zarembski 0:01f31e923fe2 94 return false;
Pawel Zarembski 0:01f31e923fe2 95 }
Pawel Zarembski 0:01f31e923fe2 96
Pawel Zarembski 0:01f31e923fe2 97 // Reprogram the new settings if flash writing is allowed
Pawel Zarembski 0:01f31e923fe2 98 static void program_cfg(cfg_setting_t *new_cfg)
Pawel Zarembski 0:01f31e923fe2 99 {
Pawel Zarembski 0:01f31e923fe2 100 uint32_t status;
Pawel Zarembski 0:01f31e923fe2 101 uint32_t addr;
Pawel Zarembski 0:01f31e923fe2 102 cortex_int_state_t state;
Pawel Zarembski 0:01f31e923fe2 103 addr = (uint32_t)&config_rom;
Pawel Zarembski 0:01f31e923fe2 104 state = cortex_int_get_and_disable();
Pawel Zarembski 0:01f31e923fe2 105 status = EraseSector(addr);
Pawel Zarembski 0:01f31e923fe2 106 cortex_int_restore(state);
Pawel Zarembski 0:01f31e923fe2 107
Pawel Zarembski 0:01f31e923fe2 108 if (status != 0) {
Pawel Zarembski 0:01f31e923fe2 109 return;
Pawel Zarembski 0:01f31e923fe2 110 }
Pawel Zarembski 0:01f31e923fe2 111
Pawel Zarembski 0:01f31e923fe2 112 memset(write_buffer, 0xFF, sizeof(write_buffer));
Pawel Zarembski 0:01f31e923fe2 113 memcpy(write_buffer, new_cfg, sizeof(cfg_setting_t));
Pawel Zarembski 0:01f31e923fe2 114 state = cortex_int_get_and_disable();
Pawel Zarembski 0:01f31e923fe2 115 status = ProgramPage(addr, sizeof(write_buffer), write_buffer);
Pawel Zarembski 0:01f31e923fe2 116 cortex_int_restore(state);
Pawel Zarembski 0:01f31e923fe2 117
Pawel Zarembski 0:01f31e923fe2 118 if (0 != status) {
Pawel Zarembski 0:01f31e923fe2 119 return;
Pawel Zarembski 0:01f31e923fe2 120 }
Pawel Zarembski 0:01f31e923fe2 121 }
Pawel Zarembski 0:01f31e923fe2 122
Pawel Zarembski 0:01f31e923fe2 123 void config_rom_init()
Pawel Zarembski 0:01f31e923fe2 124 {
Pawel Zarembski 0:01f31e923fe2 125 Init(0, 0, 0);
Pawel Zarembski 0:01f31e923fe2 126 // Fill in the ram copy with the defaults
Pawel Zarembski 0:01f31e923fe2 127 memcpy(&config_rom_copy, &config_default, sizeof(config_rom_copy));
Pawel Zarembski 0:01f31e923fe2 128
Pawel Zarembski 0:01f31e923fe2 129 // Read settings from flash if the key is valid
Pawel Zarembski 0:01f31e923fe2 130 if (CFG_KEY == config_rom.key) {
Pawel Zarembski 0:01f31e923fe2 131 uint32_t size = MIN(config_rom.size, sizeof(config_rom));
Pawel Zarembski 0:01f31e923fe2 132 memcpy(&config_rom_copy, (void *)&config_rom, size);
Pawel Zarembski 0:01f31e923fe2 133 }
Pawel Zarembski 0:01f31e923fe2 134
Pawel Zarembski 0:01f31e923fe2 135 // Fill in special values
Pawel Zarembski 0:01f31e923fe2 136 config_rom_copy.key = CFG_KEY;
Pawel Zarembski 0:01f31e923fe2 137 config_rom_copy.size = sizeof(config_rom);
Pawel Zarembski 0:01f31e923fe2 138
Pawel Zarembski 0:01f31e923fe2 139 // Write settings back to flash if they are out of date
Pawel Zarembski 0:01f31e923fe2 140 // Note - program_cfg only programs data in bootloader mode
Pawel Zarembski 0:01f31e923fe2 141 if (config_needs_update()) {
Pawel Zarembski 0:01f31e923fe2 142 // Program with defaults if none are set
Pawel Zarembski 0:01f31e923fe2 143 program_cfg(&config_rom_copy);
Pawel Zarembski 0:01f31e923fe2 144 }
Pawel Zarembski 0:01f31e923fe2 145 }
Pawel Zarembski 0:01f31e923fe2 146
Pawel Zarembski 0:01f31e923fe2 147
Pawel Zarembski 0:01f31e923fe2 148 void config_set_auto_rst(bool on)
Pawel Zarembski 0:01f31e923fe2 149 {
Pawel Zarembski 0:01f31e923fe2 150 config_rom_copy.auto_rst = on;
Pawel Zarembski 0:01f31e923fe2 151 program_cfg(&config_rom_copy);
Pawel Zarembski 0:01f31e923fe2 152 }
Pawel Zarembski 0:01f31e923fe2 153
Pawel Zarembski 0:01f31e923fe2 154 void config_set_automation_allowed(bool on)
Pawel Zarembski 0:01f31e923fe2 155 {
Pawel Zarembski 0:01f31e923fe2 156 config_rom_copy.automation_allowed = on;
Pawel Zarembski 0:01f31e923fe2 157 program_cfg(&config_rom_copy);
Pawel Zarembski 0:01f31e923fe2 158 }
Pawel Zarembski 0:01f31e923fe2 159
Pawel Zarembski 0:01f31e923fe2 160 void config_set_overflow_detect(bool on)
Pawel Zarembski 0:01f31e923fe2 161 {
Pawel Zarembski 0:01f31e923fe2 162 config_rom_copy.overflow_detect = on;
Pawel Zarembski 0:01f31e923fe2 163 program_cfg(&config_rom_copy);
Pawel Zarembski 0:01f31e923fe2 164 }
Pawel Zarembski 0:01f31e923fe2 165
Pawel Zarembski 0:01f31e923fe2 166 bool config_get_auto_rst()
Pawel Zarembski 0:01f31e923fe2 167 {
Pawel Zarembski 0:01f31e923fe2 168 return config_rom_copy.auto_rst;
Pawel Zarembski 0:01f31e923fe2 169 }
Pawel Zarembski 0:01f31e923fe2 170
Pawel Zarembski 0:01f31e923fe2 171 bool config_get_automation_allowed(void)
Pawel Zarembski 0:01f31e923fe2 172 {
Pawel Zarembski 0:01f31e923fe2 173 return config_rom_copy.automation_allowed;
Pawel Zarembski 0:01f31e923fe2 174 }
Pawel Zarembski 0:01f31e923fe2 175
Pawel Zarembski 0:01f31e923fe2 176 bool config_get_overflow_detect()
Pawel Zarembski 0:01f31e923fe2 177 {
Pawel Zarembski 0:01f31e923fe2 178 return config_rom_copy.overflow_detect;
Pawel Zarembski 0:01f31e923fe2 179 }