Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.
Upstream: https://github.com/ARMmbed/DAPLink
source/daplink/settings/settings_rom.c@0:01f31e923fe2, 2020-04-07 (annotated)
- 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?
User | Revision | Line number | New 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 | } |