mirror of https://github.com/ARMmbed/mbed-os.git
parent
26f9144c45
commit
e2c42bb0a0
|
@ -13,55 +13,169 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#if DEVICE_FLASH
|
||||
#include "mbed_critical.h"
|
||||
|
||||
#include "flash_api.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
#include "mbed_assert.h"
|
||||
#include "cmsis.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// This file is automatically generated
|
||||
#define MEMMAP (*((volatile unsigned long *) 0x400FC040))
|
||||
|
||||
#if DEVICE_FLASH
|
||||
#define PLL0CON (*((volatile unsigned long *) 0x400FC080))
|
||||
#define PLL0CFG (*((volatile unsigned long *) 0x400FC084))
|
||||
#define PLL0STAT (*((volatile unsigned long *) 0x400FC088))
|
||||
#define PLL0FEED (*((volatile unsigned long *) 0x400FC08C))
|
||||
#define CCLKSEL (*((volatile unsigned long *) 0x400FC104))
|
||||
#define CLKSRCSEL (*((volatile unsigned long *) 0x400FC10C))
|
||||
|
||||
#include "flash_data.h"
|
||||
#define STACK_SIZE 64 // Stack Size
|
||||
|
||||
// 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
|
||||
};
|
||||
#define SET_VALID_CODE 1 // Set Valid User Code Signature
|
||||
/* IAP Call */
|
||||
typedef void (*IAP_Entry) (unsigned long *cmd, unsigned long *stat);
|
||||
#define IAP_Call ((IAP_Entry) 0x1FFF1FF1)
|
||||
|
||||
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
|
||||
};
|
||||
typedef struct flash_s flash_t;
|
||||
unsigned long CCLK; // CCLK in kHz
|
||||
|
||||
static const sector_info_t sectors_info[] = {
|
||||
{0x0, 0x1000},
|
||||
{0x10000, 0x8000},
|
||||
};
|
||||
struct sIAP { // IAP Structure
|
||||
unsigned long cmd;// Command
|
||||
unsigned long par[4];// Parameters
|
||||
unsigned long stat;// Status
|
||||
unsigned long res[2];// Result
|
||||
}IAP;
|
||||
|
||||
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)
|
||||
};
|
||||
/*
|
||||
* Get Sector Number
|
||||
* Parameter: address: Sector Address
|
||||
* Return Value: Sector Number
|
||||
*/
|
||||
|
||||
void flash_set_target_config(flash_t *obj)
|
||||
unsigned long GetSecNum (unsigned long address)
|
||||
{
|
||||
obj->flash_algo = &flash_algo_config;
|
||||
obj->target_config = &flash_target_config;
|
||||
unsigned long n;
|
||||
|
||||
n = address >> 12; // 4kB Sector
|
||||
if (n >= 0x10) {
|
||||
n = 0x0E + (n >> 3); // 32kB Sector
|
||||
}
|
||||
|
||||
return (n); // Sector Number
|
||||
}
|
||||
int32_t flash_init(flash_t *obj)
|
||||
{
|
||||
CCLK = SystemCoreClock / 1000; // CCLK value is in kHz, clk in Hz
|
||||
|
||||
MEMMAP = 0x01;// User Flash Mode
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int32_t flash_free(flash_t *obj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
||||
{
|
||||
unsigned long n;
|
||||
|
||||
n = GetSecNum(address); // Get Sector Number
|
||||
|
||||
IAP.cmd = 50;// Prepare Sector for Erase
|
||||
IAP.par[0] = n;// Start Sector
|
||||
IAP.par[1] = n;// 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] = n;// Start Sector
|
||||
IAP.par[1] = n;// 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
|
||||
|
||||
}
|
||||
|
||||
/* IAP Call */
|
||||
typedef void (*IAP_Entry) (unsigned long *cmd, unsigned long *stat);
|
||||
#define IAP_Call ((IAP_Entry) 0x1FFF1FF1)
|
||||
|
||||
int32_t flash_program_page(flash_t *obj, uint32_t address,
|
||||
const uint8_t *data, uint32_t size)
|
||||
{
|
||||
unsigned long n;
|
||||
uint8_t *alignedData = 0;
|
||||
|
||||
n = GetSecNum(address); // Get Sector Number
|
||||
|
||||
IAP.cmd = 50;// Prepare Sector for Write
|
||||
IAP.par[0] = n;// Start Sector
|
||||
IAP.par[1] = n;// End Sector
|
||||
IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command
|
||||
if (IAP.stat) {
|
||||
return (1); // Command Failed
|
||||
}
|
||||
|
||||
IAP.cmd = 51; // Copy RAM to Flash
|
||||
IAP.par[0] = address;// Destination Flash Address
|
||||
|
||||
if ((unsigned long)data%4==0) { // Word boundary
|
||||
IAP.par[1] = (unsigned long)data;// Source RAM Address
|
||||
} else {
|
||||
alignedData = malloc(size);
|
||||
memcpy(alignedData,data,size);
|
||||
IAP.par[1] = (unsigned long)alignedData; // Source RAM Address
|
||||
}
|
||||
|
||||
IAP.par[2] = 1024; // Fixed Page Size
|
||||
IAP.par[3] = CCLK;// CCLK in kHz
|
||||
IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command
|
||||
|
||||
if(alignedData !=0) { // We allocated our own memory
|
||||
free(alignedData);
|
||||
}
|
||||
|
||||
if (IAP.stat) {
|
||||
return (1); // Command Failed
|
||||
}
|
||||
return (0); // Finished without Errors
|
||||
}
|
||||
|
||||
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
|
||||
{
|
||||
if (address < flash_get_start_address(obj) || address >= flash_get_start_address(obj) +flash_get_size(obj)) {
|
||||
return MBED_FLASH_INVALID_SIZE;
|
||||
}
|
||||
if(GetSecNum(address)>=0x10) {
|
||||
return 0x8000;
|
||||
} else {
|
||||
return 0x1000;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t flash_get_page_size(const flash_t *obj)
|
||||
{
|
||||
return 1024;
|
||||
}
|
||||
|
||||
uint32_t flash_get_start_address(const flash_t *obj)
|
||||
{
|
||||
return LPC_FLASH_BASE;
|
||||
}
|
||||
|
||||
uint32_t flash_get_size(const flash_t *obj)
|
||||
{
|
||||
return 0x80000;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -71,6 +71,10 @@ struct spi_s {
|
|||
LPC_SSP_TypeDef *spi;
|
||||
};
|
||||
|
||||
struct flash_s {
|
||||
/* nothing to be stored for now */
|
||||
uint32_t dummy;
|
||||
};
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -238,7 +238,7 @@
|
|||
"extra_labels": ["NXP", "LPC176X", "MBED_LPC1768"],
|
||||
"supported_toolchains": ["ARM", "uARM", "GCC_ARM", "GCC_CR", "IAR"],
|
||||
"detect_code": ["1010"],
|
||||
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "DEBUG_AWARENESS", "ETHERNET", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOCALFILESYSTEM", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SEMIHOST", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
|
||||
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "DEBUG_AWARENESS", "ETHERNET", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOCALFILESYSTEM", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SEMIHOST", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "FLASH"],
|
||||
"release_versions": ["2", "5"],
|
||||
"features": ["LWIP"],
|
||||
"device_name": "LPC1768"
|
||||
|
@ -250,7 +250,7 @@
|
|||
"extra_labels": ["NXP", "LPC176X"],
|
||||
"macros": ["TARGET_LPC1768"],
|
||||
"inherits": ["LPCTarget"],
|
||||
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "DEBUG_AWARENESS", "ETHERNET", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
|
||||
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "DEBUG_AWARENESS", "ETHERNET", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "FLASH"],
|
||||
"release_versions": ["2", "5"],
|
||||
"features": ["LWIP"],
|
||||
"device_name": "LPC1768"
|
||||
|
@ -259,7 +259,7 @@
|
|||
"supported_form_factors": ["ARDUINO"],
|
||||
"core": "Cortex-M3",
|
||||
"supported_toolchains": ["ARM", "uARM", "GCC_ARM", "GCC_CR", "IAR"],
|
||||
"extra_labels": ["NXP", "LPC176X", "FLASH_CMSIS_ALGO"],
|
||||
"extra_labels": ["NXP", "LPC176X"],
|
||||
"config": {
|
||||
"modem_is_on_board": {
|
||||
"help": "Value: Tells the build system that the modem is on-board as oppose to a plug-in shield/module.",
|
||||
|
@ -283,7 +283,7 @@
|
|||
"inherits": ["LPCTarget"],
|
||||
"core": "Cortex-M3",
|
||||
"supported_toolchains": ["ARM", "uARM", "GCC_ARM", "GCC_CR", "IAR"],
|
||||
"extra_labels": ["NXP", "LPC176X", "XBED_LPC1768", "FLASH_CMSIS_ALGO"],
|
||||
"extra_labels": ["NXP", "LPC176X", "XBED_LPC1768"],
|
||||
"macros": ["TARGET_LPC1768"],
|
||||
"detect_code": ["1010"],
|
||||
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "DEBUG_AWARENESS", "ETHERNET", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOCALFILESYSTEM", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SEMIHOST", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "FLASH"],
|
||||
|
|
Loading…
Reference in New Issue