Skip to content

Commit e2c42bb

Browse files
chrissnow0xc0170
authored andcommitted
LPC1768 IAP Fix (#4993)
use IAP routines for the flash HAL implementation
1 parent 26f9144 commit e2c42bb

File tree

3 files changed

+165
-47
lines changed

3 files changed

+165
-47
lines changed

targets/TARGET_NXP/TARGET_LPC176X/device/flash_api.c

Lines changed: 157 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,55 +13,169 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16+
#if DEVICE_FLASH
17+
#include "mbed_critical.h"
1618

1719
#include "flash_api.h"
18-
#include "platform/mbed_critical.h"
20+
#include "mbed_assert.h"
21+
#include "cmsis.h"
22+
#include <stdlib.h>
23+
#include <string.h>
1924

20-
// This file is automatically generated
25+
#define MEMMAP (*((volatile unsigned long *) 0x400FC040))
2126

22-
#if DEVICE_FLASH
27+
#define PLL0CON (*((volatile unsigned long *) 0x400FC080))
28+
#define PLL0CFG (*((volatile unsigned long *) 0x400FC084))
29+
#define PLL0STAT (*((volatile unsigned long *) 0x400FC088))
30+
#define PLL0FEED (*((volatile unsigned long *) 0x400FC08C))
31+
#define CCLKSEL (*((volatile unsigned long *) 0x400FC104))
32+
#define CLKSRCSEL (*((volatile unsigned long *) 0x400FC10C))
33+
34+
#define STACK_SIZE 64 // Stack Size
35+
36+
#define SET_VALID_CODE 1 // Set Valid User Code Signature
37+
/* IAP Call */
38+
typedef void (*IAP_Entry) (unsigned long *cmd, unsigned long *stat);
39+
#define IAP_Call ((IAP_Entry) 0x1FFF1FF1)
40+
41+
typedef struct flash_s flash_t;
42+
unsigned long CCLK; // CCLK in kHz
43+
44+
struct sIAP { // IAP Structure
45+
unsigned long cmd;// Command
46+
unsigned long par[4];// Parameters
47+
unsigned long stat;// Status
48+
unsigned long res[2];// Result
49+
}IAP;
50+
51+
/*
52+
* Get Sector Number
53+
* Parameter: address: Sector Address
54+
* Return Value: Sector Number
55+
*/
56+
57+
unsigned long GetSecNum (unsigned long address)
58+
{
59+
unsigned long n;
60+
61+
n = address >> 12; // 4kB Sector
62+
if (n >= 0x10) {
63+
n = 0x0E + (n >> 3); // 32kB Sector
64+
}
65+
66+
return (n); // Sector Number
67+
}
68+
int32_t flash_init(flash_t *obj)
69+
{
70+
CCLK = SystemCoreClock / 1000; // CCLK value is in kHz, clk in Hz
71+
72+
MEMMAP = 0x01;// User Flash Mode
73+
74+
return (0);
75+
}
76+
77+
int32_t flash_free(flash_t *obj)
78+
{
79+
return 0;
80+
}
81+
82+
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
83+
{
84+
unsigned long n;
85+
86+
n = GetSecNum(address); // Get Sector Number
87+
88+
IAP.cmd = 50;// Prepare Sector for Erase
89+
IAP.par[0] = n;// Start Sector
90+
IAP.par[1] = n;// End Sector
91+
IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command
92+
if (IAP.stat) {
93+
return (1); // Command Failed
94+
}
95+
96+
IAP.cmd = 52; // Erase Sector
97+
IAP.par[0] = n;// Start Sector
98+
IAP.par[1] = n;// End Sector
99+
IAP.par[2] = CCLK;// CCLK in kHz
100+
IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command
101+
if (IAP.stat) {
102+
return (1); // Command Failed
103+
}
104+
105+
return (0); // Finished without Errors
106+
107+
}
108+
109+
/* IAP Call */
110+
typedef void (*IAP_Entry) (unsigned long *cmd, unsigned long *stat);
111+
#define IAP_Call ((IAP_Entry) 0x1FFF1FF1)
112+
113+
int32_t flash_program_page(flash_t *obj, uint32_t address,
114+
const uint8_t *data, uint32_t size)
115+
{
116+
unsigned long n;
117+
uint8_t *alignedData = 0;
118+
119+
n = GetSecNum(address); // Get Sector Number
120+
121+
IAP.cmd = 50;// Prepare Sector for Write
122+
IAP.par[0] = n;// Start Sector
123+
IAP.par[1] = n;// End Sector
124+
IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command
125+
if (IAP.stat) {
126+
return (1); // Command Failed
127+
}
128+
129+
IAP.cmd = 51; // Copy RAM to Flash
130+
IAP.par[0] = address;// Destination Flash Address
131+
132+
if ((unsigned long)data%4==0) { // Word boundary
133+
IAP.par[1] = (unsigned long)data;// Source RAM Address
134+
} else {
135+
alignedData = malloc(size);
136+
memcpy(alignedData,data,size);
137+
IAP.par[1] = (unsigned long)alignedData; // Source RAM Address
138+
}
139+
140+
IAP.par[2] = 1024; // Fixed Page Size
141+
IAP.par[3] = CCLK;// CCLK in kHz
142+
IAP_Call (&IAP.cmd, &IAP.stat);// Call IAP Command
143+
144+
if(alignedData !=0) { // We allocated our own memory
145+
free(alignedData);
146+
}
147+
148+
if (IAP.stat) {
149+
return (1); // Command Failed
150+
}
151+
return (0); // Finished without Errors
152+
}
153+
154+
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
155+
{
156+
if (address < flash_get_start_address(obj) || address >= flash_get_start_address(obj) +flash_get_size(obj)) {
157+
return MBED_FLASH_INVALID_SIZE;
158+
}
159+
if(GetSecNum(address)>=0x10) {
160+
return 0x8000;
161+
} else {
162+
return 0x1000;
163+
}
164+
}
165+
166+
uint32_t flash_get_page_size(const flash_t *obj)
167+
{
168+
return 1024;
169+
}
170+
171+
uint32_t flash_get_start_address(const flash_t *obj)
172+
{
173+
return LPC_FLASH_BASE;
174+
}
23175

24-
#include "flash_data.h"
25-
26-
// This is a flash algo binary blob. It is PIC (position independent code) that should be stored in RAM
27-
static uint32_t FLASH_ALGO[] = {
28-
0x28100b00, 0x210ed302, 0x00d0eb01, 0xf44f4770, 0xfbb1707a, 0x4933f0f0, 0x60084449, 0x20014932,
29-
0x20006408, 0x20004770, 0xe92d4770, 0xf7ff41f0, 0x4d2effe7, 0x444d4604, 0xe9c52032, 0xf1050400,
30-
0x4e2b0114, 0x4628460f, 0x47b060ac, 0xb9686968, 0xe9c52034, 0x48230400, 0x444860ac, 0x68004639,
31-
0x462860e8, 0x696847b0, 0xd0002800, 0xe8bd2001, 0xe92d81f0, 0x461441f0, 0xd10e0006, 0x0100e9d4,
32-
0xe9d44408, 0x44111202, 0x69214408, 0x69614408, 0x69a14408, 0x42404408, 0x463061e0, 0xffb0f7ff,
33-
0x21324d12, 0x4f12444d, 0x1000e9c5, 0x0114f105, 0x468860a8, 0x47b84628, 0xb9806968, 0xe9c52033,
34-
0xf44f0600, 0xe9c56080, 0x48064002, 0x44484641, 0x61286800, 0x47b84628, 0x28006968, 0x2001d0c7,
35-
0x0000e7c5, 0x00000004, 0x400fc000, 0x00000008, 0x1fff1ff1, 0x00000000, 0x00000000, 0x00000000,
36-
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
37-
};
38-
39-
static const flash_algo_t flash_algo_config = {
40-
.init = 0xf,
41-
.uninit = 0x27,
42-
.erase_sector = 0x2b,
43-
.program_page = 0x73,
44-
.static_base = 0xf4,
45-
.algo_blob = FLASH_ALGO
46-
};
47-
48-
static const sector_info_t sectors_info[] = {
49-
{0x0, 0x1000},
50-
{0x10000, 0x8000},
51-
};
52-
53-
static const flash_target_config_t flash_target_config = {
54-
.page_size = 0x400,
55-
.flash_start = 0x0,
56-
.flash_size = 0x80000,
57-
.sectors = sectors_info,
58-
.sector_info_count = sizeof(sectors_info) / sizeof(sector_info_t)
59-
};
60-
61-
void flash_set_target_config(flash_t *obj)
176+
uint32_t flash_get_size(const flash_t *obj)
62177
{
63-
obj->flash_algo = &flash_algo_config;
64-
obj->target_config = &flash_target_config;
178+
return 0x80000;
65179
}
66180

67181
#endif

targets/TARGET_NXP/TARGET_LPC176X/objects.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ struct spi_s {
7171
LPC_SSP_TypeDef *spi;
7272
};
7373

74+
struct flash_s {
75+
/* nothing to be stored for now */
76+
uint32_t dummy;
77+
};
7478
#ifdef __cplusplus
7579
}
7680
#endif

targets/targets.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@
238238
"extra_labels": ["NXP", "LPC176X", "MBED_LPC1768"],
239239
"supported_toolchains": ["ARM", "uARM", "GCC_ARM", "GCC_CR", "IAR"],
240240
"detect_code": ["1010"],
241-
"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"],
241+
"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"],
242242
"release_versions": ["2", "5"],
243243
"features": ["LWIP"],
244244
"device_name": "LPC1768"
@@ -250,7 +250,7 @@
250250
"extra_labels": ["NXP", "LPC176X"],
251251
"macros": ["TARGET_LPC1768"],
252252
"inherits": ["LPCTarget"],
253-
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "DEBUG_AWARENESS", "ETHERNET", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
253+
"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"],
254254
"release_versions": ["2", "5"],
255255
"features": ["LWIP"],
256256
"device_name": "LPC1768"
@@ -259,7 +259,7 @@
259259
"supported_form_factors": ["ARDUINO"],
260260
"core": "Cortex-M3",
261261
"supported_toolchains": ["ARM", "uARM", "GCC_ARM", "GCC_CR", "IAR"],
262-
"extra_labels": ["NXP", "LPC176X", "FLASH_CMSIS_ALGO"],
262+
"extra_labels": ["NXP", "LPC176X"],
263263
"config": {
264264
"modem_is_on_board": {
265265
"help": "Value: Tells the build system that the modem is on-board as oppose to a plug-in shield/module.",
@@ -283,7 +283,7 @@
283283
"inherits": ["LPCTarget"],
284284
"core": "Cortex-M3",
285285
"supported_toolchains": ["ARM", "uARM", "GCC_ARM", "GCC_CR", "IAR"],
286-
"extra_labels": ["NXP", "LPC176X", "XBED_LPC1768", "FLASH_CMSIS_ALGO"],
286+
"extra_labels": ["NXP", "LPC176X", "XBED_LPC1768"],
287287
"macros": ["TARGET_LPC1768"],
288288
"detect_code": ["1010"],
289289
"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"],

0 commit comments

Comments
 (0)