mbed-os/targets/TARGET_NXP/TARGET_LPC176X/device/flash_api.c

68 lines
2.4 KiB
C
Raw Normal View History

LPC176X flash_api.h implementation For LPC176X (LPC1768/LPC1769) the flash driver has been implemented according to the CMSIS-PACK Keil.LPC1700_DFP.2.3.0 driver with the following changes in FlashPrg.c: 1. EraseChip() function removed (not used by flash_api) 2. Clock reconfiguration removed and clock value taken from function parameter to avoid unexpected behavior. Full patch of FlashPrg.c: --- Keil.LPC1700_DFP.2.3.0\Flash\LPC_IAP\FlashPrg_orig.c 2016-12-08 13:10:10.000000000 +0200 +++ Keil.LPC1700_DFP.2.3.0\Flash\LPC_IAP\FlashPrg.c 2017-04-11 20:02:37.000000000 +0200 @@ -191,90 +191,15 @@ * fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify) * Return Value: 0 - OK, 1 - Failed */ int Init (unsigned long adr, unsigned long clk, unsigned long fnc) { -#if defined LPC1XXX || defined LPC11U6X - CCLK = 12000; // 12MHz Internal RC Oscillator + CCLK = clk / 1000; // CCLK value is in kHz, clk in Hz - MAINCLKSEL = 0; // Select Internal RC Oscillator - MAINCLKUEN = 1; // Update Main Clock Source - MAINCLKUEN = 0; // Toggle Update Register - MAINCLKUEN = 1; -// while (!(MAINCLKUEN & 1)); // Wait until updated - MAINCLKDIV = 1; // Set Main Clock divider to 1 - - MEMMAP = 0x02; // User Flash Mode -#endif - -#ifdef LPC17XX - IAP.stat = 0; // Note: Some Bootloader versions don't set the status if this command is executed - IAP.cmd = 54; // Read Part ID - IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command - if (IAP.stat) return (1); // Command Failed - - switch ((IAP.res[0] >> 24) & 0xFF) { - case 0x25: - // Part ID LPC1759 = 0x25113737 - // Part ID LPC1758 = 0x25013F37 - // Part ID LPC1756 = 0x25011723 - // Part ID LPC1754 = 0x25011722 - // Part ID LPC1752 = 0x25001121 - // Part ID LPC1751 = 0x25001118 / 0x25001110 - case 0x26: - // Part ID LPC1769 = 0x26113F37 - // Part ID LPC1768 = 0x26013F37 - // Part ID LPC1767 = 0x26012837 - // Part ID LPC1766 = 0x26013F33 - // Part ID LPC1765 = 0x26013733 - // Part ID LPC1764 = 0x26011922 - CCLK = 4000; // 4MHz Internal RC Oscillator - break; - case 0x27: - // Part ID LPC1778 = 0x27193F47 - // Part ID LPC1777 = 0x27193747 - // Part ID LPC1776 = 0x27191F43 - // Part ID LPC1774 = 0x27011132 - // Part ID LPC1772 = 0x27011121 - case 0x20: // found out during test - case 0x28: - // Part ID LPC1788 = 0x281D3F47 - // Part ID LPC1787 = 0x281D3747 - // Part ID LPC1786 = 0x281D1F43 - // Part ID LPC1785 = 0x281D1743 - case 0x48: // Part ID LPC4088 = 0x481D3F47 - case 0x47: // Part ID LPC4078 = 0x47193F47 - // Part ID LPC4076 = 0x47191F43 - // Part ID LPC4074 = 0x47011132 - CCLK = 12000; // 12MHz Internal RC Oscillator - break; - default: - CCLK = 4000; // 4MHz Internal RC Oscillator - } - - CLKSRCSEL = 0x00; // sysclk = IRC - - PLL0CON = 0x00; // Disable PLL (use Oscillator) - PLL0FEED = 0xAA; // Feed Sequence Part #1 - PLL0FEED = 0x55; // Feed Sequence Part #2 - - switch ((IAP.res[0] >> 24) & 0xFF) { - case 0x27: // LPC177x - case 0x20: // LPC178x - case 0x28: // LPC178x - case 0x48: // LPC407x - case 0x47: // LPC408x - CCLKSEL = 0x01; // use Sysclk devided by 1 for CPU - break; - default: - CCLKSEL = 0x00; // CPU clk divider is 1 - } - MEMMAP = 0x01; // User Flash Mode -#endif return (0); } /* @@ -283,37 +208,12 @@ * Return Value: 0 - OK, 1 - Failed */ int UnInit (unsigned long fnc) { return (0); } - - -/* - * Erase complete Flash Memory - * Return Value: 0 - OK, 1 - Failed - */ - -int EraseChip (void) { - - IAP.cmd = 50; // Prepare Sector for Erase - IAP.par[0] = 0; // Start Sector - IAP.par[1] = END_SECTOR; // End Sector - IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command - if (IAP.stat) return (1); // Command Failed - - IAP.cmd = 52; // Erase Sector - IAP.par[0] = 0; // Start Sector - IAP.par[1] = END_SECTOR; // End Sector - IAP.par[2] = CCLK; // CCLK in kHz - IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command - if (IAP.stat) return (1); // Command Failed - - return (0); // Finished without Errors -} - /* * Erase Sector in Flash Memory * Parameter: adr: Sector Address * Return Value: 0 - OK, 1 - Failed */
2017-04-11 19:03:45 +00:00
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "flash_api.h"
#include "platform/mbed_critical.h"
// This file is automatically generated
#if DEVICE_FLASH
#include "flash_data.h"
LPC176X flash_api.h implementation For LPC176X (LPC1768/LPC1769) the flash driver has been implemented according to the CMSIS-PACK Keil.LPC1700_DFP.2.3.0 driver with the following changes in FlashPrg.c: 1. EraseChip() function removed (not used by flash_api) 2. Clock reconfiguration removed and clock value taken from function parameter to avoid unexpected behavior. Full patch of FlashPrg.c: --- Keil.LPC1700_DFP.2.3.0\Flash\LPC_IAP\FlashPrg_orig.c 2016-12-08 13:10:10.000000000 +0200 +++ Keil.LPC1700_DFP.2.3.0\Flash\LPC_IAP\FlashPrg.c 2017-04-11 20:02:37.000000000 +0200 @@ -191,90 +191,15 @@ * fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify) * Return Value: 0 - OK, 1 - Failed */ int Init (unsigned long adr, unsigned long clk, unsigned long fnc) { -#if defined LPC1XXX || defined LPC11U6X - CCLK = 12000; // 12MHz Internal RC Oscillator + CCLK = clk / 1000; // CCLK value is in kHz, clk in Hz - MAINCLKSEL = 0; // Select Internal RC Oscillator - MAINCLKUEN = 1; // Update Main Clock Source - MAINCLKUEN = 0; // Toggle Update Register - MAINCLKUEN = 1; -// while (!(MAINCLKUEN & 1)); // Wait until updated - MAINCLKDIV = 1; // Set Main Clock divider to 1 - - MEMMAP = 0x02; // User Flash Mode -#endif - -#ifdef LPC17XX - IAP.stat = 0; // Note: Some Bootloader versions don't set the status if this command is executed - IAP.cmd = 54; // Read Part ID - IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command - if (IAP.stat) return (1); // Command Failed - - switch ((IAP.res[0] >> 24) & 0xFF) { - case 0x25: - // Part ID LPC1759 = 0x25113737 - // Part ID LPC1758 = 0x25013F37 - // Part ID LPC1756 = 0x25011723 - // Part ID LPC1754 = 0x25011722 - // Part ID LPC1752 = 0x25001121 - // Part ID LPC1751 = 0x25001118 / 0x25001110 - case 0x26: - // Part ID LPC1769 = 0x26113F37 - // Part ID LPC1768 = 0x26013F37 - // Part ID LPC1767 = 0x26012837 - // Part ID LPC1766 = 0x26013F33 - // Part ID LPC1765 = 0x26013733 - // Part ID LPC1764 = 0x26011922 - CCLK = 4000; // 4MHz Internal RC Oscillator - break; - case 0x27: - // Part ID LPC1778 = 0x27193F47 - // Part ID LPC1777 = 0x27193747 - // Part ID LPC1776 = 0x27191F43 - // Part ID LPC1774 = 0x27011132 - // Part ID LPC1772 = 0x27011121 - case 0x20: // found out during test - case 0x28: - // Part ID LPC1788 = 0x281D3F47 - // Part ID LPC1787 = 0x281D3747 - // Part ID LPC1786 = 0x281D1F43 - // Part ID LPC1785 = 0x281D1743 - case 0x48: // Part ID LPC4088 = 0x481D3F47 - case 0x47: // Part ID LPC4078 = 0x47193F47 - // Part ID LPC4076 = 0x47191F43 - // Part ID LPC4074 = 0x47011132 - CCLK = 12000; // 12MHz Internal RC Oscillator - break; - default: - CCLK = 4000; // 4MHz Internal RC Oscillator - } - - CLKSRCSEL = 0x00; // sysclk = IRC - - PLL0CON = 0x00; // Disable PLL (use Oscillator) - PLL0FEED = 0xAA; // Feed Sequence Part #1 - PLL0FEED = 0x55; // Feed Sequence Part #2 - - switch ((IAP.res[0] >> 24) & 0xFF) { - case 0x27: // LPC177x - case 0x20: // LPC178x - case 0x28: // LPC178x - case 0x48: // LPC407x - case 0x47: // LPC408x - CCLKSEL = 0x01; // use Sysclk devided by 1 for CPU - break; - default: - CCLKSEL = 0x00; // CPU clk divider is 1 - } - MEMMAP = 0x01; // User Flash Mode -#endif return (0); } /* @@ -283,37 +208,12 @@ * Return Value: 0 - OK, 1 - Failed */ int UnInit (unsigned long fnc) { return (0); } - - -/* - * Erase complete Flash Memory - * Return Value: 0 - OK, 1 - Failed - */ - -int EraseChip (void) { - - IAP.cmd = 50; // Prepare Sector for Erase - IAP.par[0] = 0; // Start Sector - IAP.par[1] = END_SECTOR; // End Sector - IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command - if (IAP.stat) return (1); // Command Failed - - IAP.cmd = 52; // Erase Sector - IAP.par[0] = 0; // Start Sector - IAP.par[1] = END_SECTOR; // End Sector - IAP.par[2] = CCLK; // CCLK in kHz - IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command - if (IAP.stat) return (1); // Command Failed - - return (0); // Finished without Errors -} - /* * Erase Sector in Flash Memory * Parameter: adr: Sector Address * Return Value: 0 - OK, 1 - Failed */
2017-04-11 19:03:45 +00:00
// This is a flash algo binary blob. It is PIC (position independent code) that should be stored in RAM
static uint32_t FLASH_ALGO[] = {
0x28100b00, 0x210ed302, 0x00d0eb01, 0xf44f4770, 0xfbb1707a, 0x4933f0f0, 0x60084449, 0x20014932,
0x20006408, 0x20004770, 0xe92d4770, 0xf7ff41f0, 0x4d2effe7, 0x444d4604, 0xe9c52032, 0xf1050400,
0x4e2b0114, 0x4628460f, 0x47b060ac, 0xb9686968, 0xe9c52034, 0x48230400, 0x444860ac, 0x68004639,
0x462860e8, 0x696847b0, 0xd0002800, 0xe8bd2001, 0xe92d81f0, 0x461441f0, 0xd10e0006, 0x0100e9d4,
0xe9d44408, 0x44111202, 0x69214408, 0x69614408, 0x69a14408, 0x42404408, 0x463061e0, 0xffb0f7ff,
0x21324d12, 0x4f12444d, 0x1000e9c5, 0x0114f105, 0x468860a8, 0x47b84628, 0xb9806968, 0xe9c52033,
0xf44f0600, 0xe9c56080, 0x48064002, 0x44484641, 0x61286800, 0x47b84628, 0x28006968, 0x2001d0c7,
0x0000e7c5, 0x00000004, 0x400fc000, 0x00000008, 0x1fff1ff1, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
};
static const flash_algo_t flash_algo_config = {
.init = 0xf,
.uninit = 0x27,
.erase_sector = 0x2b,
.program_page = 0x73,
.static_base = 0xf4,
.algo_blob = FLASH_ALGO
};
static const sector_info_t sectors_info[] = {
{0x0, 0x1000},
{0x10000, 0x8000},
};
static const flash_target_config_t flash_target_config = {
.page_size = 0x400,
.flash_start = 0x0,
.flash_size = 0x80000,
.sectors = sectors_info,
.sector_info_count = sizeof(sectors_info) / sizeof(sector_info_t)
};
void flash_set_target_config(flash_t *obj)
{
obj->flash_algo = &flash_algo_config;
obj->target_config = &flash_target_config;
}
#endif