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_hal_stub.c
Pawel Zarembski 0:01f31e923fe2 3 * @brief
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 "flash_hal.h"
Pawel Zarembski 0:01f31e923fe2 23 #include "system_LPC43xx.h"
Pawel Zarembski 0:01f31e923fe2 24 #include "daplink_addr.h"
Pawel Zarembski 0:01f31e923fe2 25 #include "cortex_m.h"
Pawel Zarembski 0:01f31e923fe2 26
Pawel Zarembski 0:01f31e923fe2 27 #define END_SECTOR 14 /* 15 sectors per bank */
Pawel Zarembski 0:01f31e923fe2 28 #define FLASH_BANK_A 0
Pawel Zarembski 0:01f31e923fe2 29 #define FLASH_BANK_B 1
Pawel Zarembski 0:01f31e923fe2 30
Pawel Zarembski 0:01f31e923fe2 31 /* IAP Structure */
Pawel Zarembski 0:01f31e923fe2 32 struct sIAP {
Pawel Zarembski 0:01f31e923fe2 33 uint32_t cmd; // Command
Pawel Zarembski 0:01f31e923fe2 34 uint32_t par[4]; // Parameters
Pawel Zarembski 0:01f31e923fe2 35 uint32_t stat; // Status
Pawel Zarembski 0:01f31e923fe2 36 uint32_t res[2]; // Result
Pawel Zarembski 0:01f31e923fe2 37 } IAP;
Pawel Zarembski 0:01f31e923fe2 38
Pawel Zarembski 0:01f31e923fe2 39 /* IAP Call */
Pawel Zarembski 0:01f31e923fe2 40 typedef void (*IAP_Entry) (uint32_t *cmd, uint32_t *stat);
Pawel Zarembski 0:01f31e923fe2 41 #define IAP_Call ((IAP_Entry) (*(volatile unsigned int *)(0x10400100)))
Pawel Zarembski 0:01f31e923fe2 42
Pawel Zarembski 0:01f31e923fe2 43 uint32_t GetSecNum (uint32_t adr) {
Pawel Zarembski 0:01f31e923fe2 44 uint32_t n;
Pawel Zarembski 0:01f31e923fe2 45 uint32_t flashadr = (adr & 0xFFFFFF);
Pawel Zarembski 0:01f31e923fe2 46
Pawel Zarembski 0:01f31e923fe2 47 if (flashadr < 0x10000) {
Pawel Zarembski 0:01f31e923fe2 48 n = flashadr >> 13; // 8kB Sector
Pawel Zarembski 0:01f31e923fe2 49 } else {
Pawel Zarembski 0:01f31e923fe2 50 n = (flashadr >> 16) + 7; // 64kB Sector
Pawel Zarembski 0:01f31e923fe2 51 }
Pawel Zarembski 0:01f31e923fe2 52
Pawel Zarembski 0:01f31e923fe2 53 return n; // Sector Number
Pawel Zarembski 0:01f31e923fe2 54 }
Pawel Zarembski 0:01f31e923fe2 55
Pawel Zarembski 0:01f31e923fe2 56
Pawel Zarembski 0:01f31e923fe2 57 uint32_t Init(uint32_t adr, uint32_t clk, uint32_t fnc)
Pawel Zarembski 0:01f31e923fe2 58 {
Pawel Zarembski 0:01f31e923fe2 59 cortex_int_state_t local_state = cortex_int_get_and_disable();
Pawel Zarembski 0:01f31e923fe2 60
Pawel Zarembski 0:01f31e923fe2 61 IAP.cmd = 49; // Initialize
Pawel Zarembski 0:01f31e923fe2 62 IAP.par[0] = 0;
Pawel Zarembski 0:01f31e923fe2 63 IAP_Call(&IAP.cmd, &IAP.stat); // Call IAP Command
Pawel Zarembski 0:01f31e923fe2 64
Pawel Zarembski 0:01f31e923fe2 65 cortex_int_restore(local_state);
Pawel Zarembski 0:01f31e923fe2 66
Pawel Zarembski 0:01f31e923fe2 67 return 0;
Pawel Zarembski 0:01f31e923fe2 68 }
Pawel Zarembski 0:01f31e923fe2 69
Pawel Zarembski 0:01f31e923fe2 70 uint32_t UnInit(uint32_t fnc)
Pawel Zarembski 0:01f31e923fe2 71 {
Pawel Zarembski 0:01f31e923fe2 72 return 0;
Pawel Zarembski 0:01f31e923fe2 73 }
Pawel Zarembski 0:01f31e923fe2 74
Pawel Zarembski 0:01f31e923fe2 75 uint32_t EraseChip(void)
Pawel Zarembski 0:01f31e923fe2 76 {
Pawel Zarembski 0:01f31e923fe2 77 cortex_int_state_t local_state = cortex_int_get_and_disable();
Pawel Zarembski 0:01f31e923fe2 78
Pawel Zarembski 0:01f31e923fe2 79 IAP.cmd = 50; // Prepare Sector for Erase
Pawel Zarembski 0:01f31e923fe2 80 IAP.par[0] = 0; // Start Sector
Pawel Zarembski 0:01f31e923fe2 81 IAP.par[1] = END_SECTOR; // End Sector
Pawel Zarembski 0:01f31e923fe2 82 IAP.par[2] = FLASH_BANK_A; // Flash Bank
Pawel Zarembski 0:01f31e923fe2 83 IAP_Call(&IAP.cmd, &IAP.stat); // Call IAP Command
Pawel Zarembski 0:01f31e923fe2 84 if (IAP.stat) {
Pawel Zarembski 0:01f31e923fe2 85 cortex_int_restore(local_state);
Pawel Zarembski 0:01f31e923fe2 86 return 1; // Command Failed
Pawel Zarembski 0:01f31e923fe2 87 }
Pawel Zarembski 0:01f31e923fe2 88
Pawel Zarembski 0:01f31e923fe2 89 IAP.cmd = 52; // Erase Sector
Pawel Zarembski 0:01f31e923fe2 90 IAP.par[0] = 0; // Start Sector
Pawel Zarembski 0:01f31e923fe2 91 IAP.par[1] = END_SECTOR; // End Sector
Pawel Zarembski 0:01f31e923fe2 92 IAP.par[2] = SystemCoreClock / 1000; // CCLK in kHz
Pawel Zarembski 0:01f31e923fe2 93 IAP.par[3] = FLASH_BANK_A; // Flash Bank
Pawel Zarembski 0:01f31e923fe2 94 IAP_Call(&IAP.cmd, &IAP.stat); // Call IAP Command
Pawel Zarembski 0:01f31e923fe2 95 if (IAP.stat) {
Pawel Zarembski 0:01f31e923fe2 96 cortex_int_restore(local_state);
Pawel Zarembski 0:01f31e923fe2 97 return 1; // Command Failed
Pawel Zarembski 0:01f31e923fe2 98 }
Pawel Zarembski 0:01f31e923fe2 99
Pawel Zarembski 0:01f31e923fe2 100 cortex_int_restore(local_state);
Pawel Zarembski 0:01f31e923fe2 101
Pawel Zarembski 0:01f31e923fe2 102 return 0;
Pawel Zarembski 0:01f31e923fe2 103 }
Pawel Zarembski 0:01f31e923fe2 104
Pawel Zarembski 0:01f31e923fe2 105 uint32_t EraseSector(uint32_t adr)
Pawel Zarembski 0:01f31e923fe2 106 {
Pawel Zarembski 0:01f31e923fe2 107 uint32_t n;
Pawel Zarembski 0:01f31e923fe2 108
Pawel Zarembski 0:01f31e923fe2 109 n = GetSecNum(adr); // Get Sector Number
Pawel Zarembski 0:01f31e923fe2 110
Pawel Zarembski 0:01f31e923fe2 111 cortex_int_state_t local_state = cortex_int_get_and_disable();
Pawel Zarembski 0:01f31e923fe2 112
Pawel Zarembski 0:01f31e923fe2 113 IAP.cmd = 50; // Prepare Sector for Erase
Pawel Zarembski 0:01f31e923fe2 114 IAP.par[0] = n; // Start Sector
Pawel Zarembski 0:01f31e923fe2 115 IAP.par[1] = n; // End Sector
Pawel Zarembski 0:01f31e923fe2 116 IAP.par[2] = FLASH_BANK_A; // Flash Bank
Pawel Zarembski 0:01f31e923fe2 117 IAP_Call(&IAP.cmd, &IAP.stat); // Call IAP Command
Pawel Zarembski 0:01f31e923fe2 118 if (IAP.stat) {
Pawel Zarembski 0:01f31e923fe2 119 cortex_int_restore(local_state);
Pawel Zarembski 0:01f31e923fe2 120 return 1; // Command Failed
Pawel Zarembski 0:01f31e923fe2 121 }
Pawel Zarembski 0:01f31e923fe2 122
Pawel Zarembski 0:01f31e923fe2 123 IAP.cmd = 52; // Erase Sector
Pawel Zarembski 0:01f31e923fe2 124 IAP.par[0] = n; // Start Sector
Pawel Zarembski 0:01f31e923fe2 125 IAP.par[1] = n; // End Sector
Pawel Zarembski 0:01f31e923fe2 126 IAP.par[2] = SystemCoreClock / 1000; // CCLK in kHz
Pawel Zarembski 0:01f31e923fe2 127 IAP.par[3] = FLASH_BANK_A; // Flash Bank
Pawel Zarembski 0:01f31e923fe2 128 IAP_Call(&IAP.cmd, &IAP.stat); // Call IAP Command
Pawel Zarembski 0:01f31e923fe2 129 if (IAP.stat) {
Pawel Zarembski 0:01f31e923fe2 130 cortex_int_restore(local_state);
Pawel Zarembski 0:01f31e923fe2 131 return 1; // Command Failed
Pawel Zarembski 0:01f31e923fe2 132 }
Pawel Zarembski 0:01f31e923fe2 133
Pawel Zarembski 0:01f31e923fe2 134 cortex_int_restore(local_state);
Pawel Zarembski 0:01f31e923fe2 135
Pawel Zarembski 0:01f31e923fe2 136 return 0;
Pawel Zarembski 0:01f31e923fe2 137 }
Pawel Zarembski 0:01f31e923fe2 138
Pawel Zarembski 0:01f31e923fe2 139 uint32_t ProgramPage(uint32_t adr, uint32_t sz, uint32_t *buf)
Pawel Zarembski 0:01f31e923fe2 140 {
Pawel Zarembski 0:01f31e923fe2 141 uint32_t n;
Pawel Zarembski 0:01f31e923fe2 142
Pawel Zarembski 0:01f31e923fe2 143 if (adr == DAPLINK_ROM_START) { // Check for Vector Table
Pawel Zarembski 0:01f31e923fe2 144 n = *((unsigned long *)(buf + 0)) +
Pawel Zarembski 0:01f31e923fe2 145 *((unsigned long *)(buf + 1)) +
Pawel Zarembski 0:01f31e923fe2 146 *((unsigned long *)(buf + 2)) +
Pawel Zarembski 0:01f31e923fe2 147 *((unsigned long *)(buf + 3)) +
Pawel Zarembski 0:01f31e923fe2 148 *((unsigned long *)(buf + 4)) +
Pawel Zarembski 0:01f31e923fe2 149 *((unsigned long *)(buf + 5)) +
Pawel Zarembski 0:01f31e923fe2 150 *((unsigned long *)(buf + 6));
Pawel Zarembski 0:01f31e923fe2 151 *((unsigned long *)(buf + 7)) = 0 - n; // Signature at Reserved Vector
Pawel Zarembski 0:01f31e923fe2 152 }
Pawel Zarembski 0:01f31e923fe2 153 n = GetSecNum(adr); // Get Sector Number
Pawel Zarembski 0:01f31e923fe2 154
Pawel Zarembski 0:01f31e923fe2 155 cortex_int_state_t local_state = cortex_int_get_and_disable();
Pawel Zarembski 0:01f31e923fe2 156
Pawel Zarembski 0:01f31e923fe2 157 IAP.cmd = 50; // Prepare Sector for Write
Pawel Zarembski 0:01f31e923fe2 158 IAP.par[0] = n; // Start Sector
Pawel Zarembski 0:01f31e923fe2 159 IAP.par[1] = n; // End Sector
Pawel Zarembski 0:01f31e923fe2 160 IAP.par[2] = FLASH_BANK_A; // Flash Bank
Pawel Zarembski 0:01f31e923fe2 161 IAP_Call(&IAP.cmd, &IAP.stat); // Call IAP Command
Pawel Zarembski 0:01f31e923fe2 162 if (IAP.stat) {
Pawel Zarembski 0:01f31e923fe2 163 cortex_int_restore(local_state);
Pawel Zarembski 0:01f31e923fe2 164 return 1; // Command Failed
Pawel Zarembski 0:01f31e923fe2 165 }
Pawel Zarembski 0:01f31e923fe2 166
Pawel Zarembski 0:01f31e923fe2 167 IAP.cmd = 51; // Copy RAM to Flash
Pawel Zarembski 0:01f31e923fe2 168 IAP.par[0] = adr; // Destination Flash Address
Pawel Zarembski 0:01f31e923fe2 169 IAP.par[1] = (unsigned long)buf; // Source RAM Address
Pawel Zarembski 0:01f31e923fe2 170 IAP.par[2] = 0x400; // Fixed Page Size
Pawel Zarembski 0:01f31e923fe2 171 IAP.par[3] = SystemCoreClock / 1000; // CCLK in kHz
Pawel Zarembski 0:01f31e923fe2 172 IAP_Call(&IAP.cmd, &IAP.stat); // Call IAP Command
Pawel Zarembski 0:01f31e923fe2 173 if (IAP.stat) {
Pawel Zarembski 0:01f31e923fe2 174 cortex_int_restore(local_state);
Pawel Zarembski 0:01f31e923fe2 175 return 1; // Command Failed
Pawel Zarembski 0:01f31e923fe2 176 }
Pawel Zarembski 0:01f31e923fe2 177
Pawel Zarembski 0:01f31e923fe2 178 cortex_int_restore(local_state);
Pawel Zarembski 0:01f31e923fe2 179
Pawel Zarembski 0:01f31e923fe2 180 return 0;
Pawel Zarembski 0:01f31e923fe2 181 }