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.c
00003  * @brief
00004  *
00005  * DAPLink Interface Firmware
00006  * Copyright (c) 2017-2017, 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 <string.h>
00023 #include "flash_hal.h"
00024 #include "iap.h"
00025 #include "util.h"
00026 #include "LPC11Uxx.h"
00027 
00028 // page buffer must be 4 byte algined and must reside in ram bank 1
00029 static __attribute__((section("RAM1"))) uint32_t page_buf[64];
00030 
00031 static uint32_t get_sector_num(uint32_t addr);
00032 
00033 uint32_t Init(uint32_t adr, uint32_t clk, uint32_t fnc)
00034 {
00035     return 0; // No init needed
00036 }
00037 
00038 uint32_t UnInit(uint32_t fnc)
00039 {
00040     return 0; // No init needed
00041 }
00042 
00043 uint32_t EraseChip(void)
00044 {
00045     return (1); // IAP not supported
00046 }
00047 
00048 uint32_t EraseSector(uint32_t adr)
00049 {
00050     uint32_t num = get_sector_num(adr);
00051 
00052     iap_lock();
00053 
00054     iap_op.cmd = 50;        // Prepare Sector for Erase
00055     iap_op.par[0] = num;    // Start Sector
00056     iap_op.par[1] = num;    // End Sector
00057     iap_call(&iap_op);
00058     if (iap_op.stat != CMD_SUCCESS) {
00059         iap_unlock();
00060         return (1);
00061     }
00062 
00063     iap_op.cmd = 52;                        // Erase Sector
00064     iap_op.par[0] = num;                    // Start Sector
00065     iap_op.par[1] = num;                    // End Sector
00066     iap_op.par[2] = SystemCoreClock / 1000; // Core Clock in kHz
00067     iap_call(&iap_op);
00068     if (iap_op.stat != CMD_SUCCESS) {
00069         iap_unlock();
00070         return (1);
00071     }
00072 
00073     iap_unlock();
00074 
00075     return 0; // Success
00076 }
00077 
00078 uint32_t ProgramPage(uint32_t adr, uint32_t sz, uint32_t *buf)
00079 {
00080     uint32_t num = get_sector_num(adr);
00081 
00082     iap_lock();
00083 
00084     iap_op.cmd = 50;        // Prepare Sector for Program
00085     iap_op.par[0] = num;    // Start Sector
00086     iap_op.par[1] = num;    // End Sector
00087     iap_call(&iap_op);
00088     if (iap_op.stat != CMD_SUCCESS) {
00089         iap_unlock();
00090         return (1);
00091     }
00092 
00093     while (sz > 0) {
00094         uint32_t copy_size = MIN(sz, sizeof(page_buf));
00095         memset(page_buf, 0xFF, sizeof(page_buf));
00096         memcpy(page_buf, buf, copy_size);
00097         iap_op.cmd = 51;                        // Erase Sector
00098         iap_op.par[0] = adr;                    // Destination
00099         iap_op.par[1] = (uint32_t)page_buf;     // Source
00100         iap_op.par[2] = 256;                    // Write size
00101         iap_op.par[3] = SystemCoreClock / 1000; // Core Clock in kHz
00102         iap_call(&iap_op);
00103         if (iap_op.stat != CMD_SUCCESS) {
00104             iap_unlock();
00105             return (1);
00106         }
00107         sz -= copy_size;
00108         adr += copy_size;
00109         buf += copy_size / 4;
00110     }
00111 
00112     iap_unlock();
00113 
00114     return 0; // Success
00115 }
00116 
00117 static uint32_t get_sector_num(uint32_t addr)
00118 {
00119     return addr / 0x1000;
00120 }