Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers flash.c Source File

flash.c

00001 /**
00002  * @file    flash_hal_stub.c
00003  * @brief
00004  *
00005  * DAPLink Interface Firmware
00006  * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
00007  * SPDX-License-Identifier: Apache-2.0
00008  *
00009  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00010  * not use this file except in compliance with the License.
00011  * You may obtain a copy of the License at
00012  *
00013  * http://www.apache.org/licenses/LICENSE-2.0
00014  *
00015  * Unless required by applicable law or agreed to in writing, software
00016  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00017  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00018  * See the License for the specific language governing permissions and
00019  * limitations under the License.
00020  */
00021 
00022 #include "flash_hal.h"
00023 #include "system_LPC43xx.h"
00024 #include "daplink_addr.h"
00025 #include "cortex_m.h"
00026 
00027 #define END_SECTOR     14  /* 15 sectors per bank */
00028 #define FLASH_BANK_A    0
00029 #define FLASH_BANK_B    1
00030 
00031 /* IAP Structure */
00032 struct sIAP {
00033     uint32_t cmd;           // Command
00034     uint32_t par[4];        // Parameters
00035     uint32_t stat;          // Status
00036     uint32_t res[2];        // Result
00037 } IAP;
00038 
00039 /* IAP Call */
00040 typedef void (*IAP_Entry) (uint32_t *cmd, uint32_t *stat);
00041 #define IAP_Call ((IAP_Entry) (*(volatile unsigned int *)(0x10400100)))
00042 
00043 uint32_t GetSecNum (uint32_t adr) {
00044     uint32_t n;
00045     uint32_t flashadr = (adr & 0xFFFFFF);
00046 
00047     if (flashadr < 0x10000) {
00048         n = flashadr >> 13;          //  8kB Sector
00049     } else {
00050         n = (flashadr >> 16) + 7;    // 64kB Sector
00051     }
00052 
00053     return n;                        // Sector Number
00054 }
00055 
00056 
00057 uint32_t Init(uint32_t adr, uint32_t clk, uint32_t fnc)
00058 {
00059     cortex_int_state_t local_state = cortex_int_get_and_disable();
00060 
00061     IAP.cmd    = 49;                            // Initialize
00062     IAP.par[0] = 0;
00063     IAP_Call(&IAP.cmd, &IAP.stat);              // Call IAP Command
00064 
00065     cortex_int_restore(local_state);
00066 
00067     return 0;
00068 }
00069 
00070 uint32_t UnInit(uint32_t fnc)
00071 {
00072     return 0;
00073 }
00074 
00075 uint32_t EraseChip(void)
00076 {
00077     cortex_int_state_t local_state = cortex_int_get_and_disable();
00078 
00079     IAP.cmd    = 50;                            // Prepare Sector for Erase
00080     IAP.par[0] = 0;                             // Start Sector
00081     IAP.par[1] = END_SECTOR;                    // End Sector
00082     IAP.par[2] = FLASH_BANK_A;                  // Flash Bank
00083     IAP_Call(&IAP.cmd, &IAP.stat);              // Call IAP Command
00084     if (IAP.stat) {
00085         cortex_int_restore(local_state);
00086         return 1;  // Command Failed
00087     }
00088 
00089     IAP.cmd    = 52;                            // Erase Sector
00090     IAP.par[0] = 0;                             // Start Sector
00091     IAP.par[1] = END_SECTOR;                    // End Sector
00092     IAP.par[2] = SystemCoreClock / 1000;        // CCLK in kHz
00093     IAP.par[3] = FLASH_BANK_A;                  // Flash Bank
00094     IAP_Call(&IAP.cmd, &IAP.stat);              // Call IAP Command
00095     if (IAP.stat) {
00096         cortex_int_restore(local_state);
00097         return 1;  // Command Failed
00098     }
00099 
00100     cortex_int_restore(local_state);
00101 
00102     return 0;
00103 }
00104 
00105 uint32_t EraseSector(uint32_t adr)
00106 {
00107     uint32_t n;
00108 
00109     n = GetSecNum(adr);                         // Get Sector Number
00110 
00111     cortex_int_state_t local_state = cortex_int_get_and_disable();
00112 
00113     IAP.cmd    = 50;                            // Prepare Sector for Erase
00114     IAP.par[0] = n;                             // Start Sector
00115     IAP.par[1] = n;                             // End Sector
00116     IAP.par[2] = FLASH_BANK_A;                  // Flash Bank
00117     IAP_Call(&IAP.cmd, &IAP.stat);              // Call IAP Command
00118     if (IAP.stat) {
00119         cortex_int_restore(local_state);
00120         return 1;  // Command Failed
00121     }
00122 
00123     IAP.cmd    = 52;                            // Erase Sector
00124     IAP.par[0] = n;                             // Start Sector
00125     IAP.par[1] = n;                             // End Sector
00126     IAP.par[2] = SystemCoreClock / 1000;        // CCLK in kHz
00127     IAP.par[3] = FLASH_BANK_A;                  // Flash Bank
00128     IAP_Call(&IAP.cmd, &IAP.stat);              // Call IAP Command
00129     if (IAP.stat) {
00130         cortex_int_restore(local_state);
00131         return 1;  // Command Failed
00132     }
00133 
00134     cortex_int_restore(local_state);
00135 
00136     return 0;
00137 }
00138 
00139 uint32_t ProgramPage(uint32_t adr, uint32_t sz, uint32_t *buf)
00140 {
00141     uint32_t n;
00142 
00143     if (adr == DAPLINK_ROM_START) {                              // Check for Vector Table
00144         n = *((unsigned long *)(buf + 0)) +
00145             *((unsigned long *)(buf + 1)) +
00146             *((unsigned long *)(buf + 2)) +
00147             *((unsigned long *)(buf + 3)) +
00148             *((unsigned long *)(buf + 4)) +
00149             *((unsigned long *)(buf + 5)) +
00150             *((unsigned long *)(buf + 6));
00151             *((unsigned long *)(buf + 7)) = 0 - n;  // Signature at Reserved Vector
00152     }
00153     n = GetSecNum(adr);                         // Get Sector Number
00154 
00155     cortex_int_state_t local_state = cortex_int_get_and_disable();
00156 
00157     IAP.cmd    = 50;                            // Prepare Sector for Write
00158     IAP.par[0] = n;                             // Start Sector
00159     IAP.par[1] = n;                             // End Sector
00160     IAP.par[2] = FLASH_BANK_A;                  // Flash Bank
00161     IAP_Call(&IAP.cmd, &IAP.stat);              // Call IAP Command
00162     if (IAP.stat) {
00163         cortex_int_restore(local_state);
00164         return 1;  // Command Failed
00165     }
00166 
00167     IAP.cmd    = 51;                            // Copy RAM to Flash
00168     IAP.par[0] = adr;                           // Destination Flash Address
00169     IAP.par[1] = (unsigned long)buf;            // Source RAM Address
00170     IAP.par[2] = 0x400;                         // Fixed Page Size
00171     IAP.par[3] = SystemCoreClock / 1000;        // CCLK in kHz
00172     IAP_Call(&IAP.cmd, &IAP.stat);              // Call IAP Command
00173     if (IAP.stat) {
00174         cortex_int_restore(local_state);
00175         return 1;  // Command Failed
00176     }
00177 
00178     cortex_int_restore(local_state);
00179 
00180     return 0;
00181 }