Skip to content

Commit e5bc908

Browse files
chrissnowadbridge
authored andcommitted
initial IAP routine
1 parent a658230 commit e5bc908

File tree

2 files changed

+160
-46
lines changed

2 files changed

+160
-46
lines changed

targets/TARGET_NXP/TARGET_LPC176X/device/flash_api.c

Lines changed: 156 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,54 +14,165 @@
1414
* limitations under the License.
1515
*/
1616

17-
#include "flash_api.h"
18-
#include "platform/mbed_critical.h"
19-
20-
// This file is automatically generated
17+
#include "mbed_critical.h"
2118

2219
#if DEVICE_FLASH
20+
#include "mbed_assert.h"
21+
#include "cmsis.h"
22+
23+
24+
#define MEMMAP (*((volatile unsigned long *) 0x400FC040))
25+
26+
#define PLL0CON (*((volatile unsigned long *) 0x400FC080))
27+
#define PLL0CFG (*((volatile unsigned long *) 0x400FC084))
28+
#define PLL0STAT (*((volatile unsigned long *) 0x400FC088))
29+
#define PLL0FEED (*((volatile unsigned long *) 0x400FC08C))
30+
#define CCLKSEL (*((volatile unsigned long *) 0x400FC104))
31+
#define CLKSRCSEL (*((volatile unsigned long *) 0x400FC10C))
32+
33+
#define STACK_SIZE 64 // Stack Size
34+
35+
#define SET_VALID_CODE 1 // Set Valid User Code Signature
36+
/* IAP Call */
37+
typedef void (*IAP_Entry) (unsigned long *cmd, unsigned long *stat);
38+
#define IAP_Call ((IAP_Entry) 0x1FFF1FF1)
39+
40+
typedef struct flash_s flash_t;
41+
unsigned long CCLK; // CCLK in kHz
42+
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+
unsigned long n;
59+
60+
61+
n = address >> 12; // 4kB Sector
62+
if (n >= 0x10) {
63+
n = 0x0E + (n >> 3); // 32kB Sector
64+
}
65+
66+
67+
return (n); // Sector Number
68+
}
69+
int32_t flash_init(flash_t *obj)
70+
{
71+
CCLK = SystemCoreClock / 1000; // CCLK value is in kHz, clk in Hz
72+
73+
MEMMAP = 0x01; // User Flash Mode
74+
75+
return (0);
76+
}
77+
78+
int32_t flash_free(flash_t *obj)
79+
{
80+
return 0;
81+
}
82+
83+
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
84+
{
85+
unsigned long n;
86+
87+
n = GetSecNum(address); // Get Sector Number
88+
89+
IAP.cmd = 50; // Prepare Sector for Erase
90+
IAP.par[0] = n; // Start Sector
91+
IAP.par[1] = n; // End Sector
92+
IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
93+
if (IAP.stat) return (1); // Command Failed
94+
95+
IAP.cmd = 52; // Erase Sector
96+
IAP.par[0] = n; // Start Sector
97+
IAP.par[1] = n; // End Sector
98+
IAP.par[2] = CCLK; // CCLK in kHz
99+
IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
100+
if (IAP.stat) return (1); // Command Failed
101+
102+
return (0); // Finished without Errors
103+
104+
}
105+
106+
/* IAP Call */
107+
typedef void (*IAP_Entry) (unsigned long *cmd, unsigned long *stat);
108+
#define IAP_Call ((IAP_Entry) 0x1FFF1FF1)
109+
110+
111+
int32_t flash_program_page(flash_t *obj, uint32_t address,
112+
const uint8_t *data, uint32_t size)
113+
{
114+
unsigned long n;
115+
116+
#if SET_VALID_CODE != 0 // Set valid User Code Signature
117+
if (address == 0) { // Check for Vector Table
118+
n = *((unsigned long *)(data + 0x00)) +
119+
*((unsigned long *)(data + 0x04)) +
120+
*((unsigned long *)(data + 0x08)) +
121+
*((unsigned long *)(data + 0x0C)) +
122+
*((unsigned long *)(data + 0x10)) +
123+
*((unsigned long *)(data + 0x14)) +
124+
*((unsigned long *)(data + 0x18));
125+
*((unsigned long *)(data + 0x1C)) = 0 - n; // Signature at Reserved Vector
126+
}
127+
#endif
128+
129+
n = GetSecNum(address); // Get Sector Number
130+
131+
IAP.cmd = 50; // Prepare Sector for Write
132+
IAP.par[0] = n; // Start Sector
133+
IAP.par[1] = n; // End Sector
134+
IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
135+
if (IAP.stat) return (1); // Command Failed
136+
137+
IAP.cmd = 51; // Copy RAM to Flash
138+
IAP.par[0] = address; // Destination Flash Address
139+
IAP.par[1] = (unsigned long)data; // Source RAM Address
140+
141+
IAP.par[2] = 1024; // Fixed Page Size
142+
IAP.par[3] = CCLK; // CCLK in kHz
143+
IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
144+
if (IAP.stat) return (1); // Command Failed
145+
146+
return (0); // Finished without Errors
147+
}
148+
149+
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
150+
{
151+
152+
if(GetSecNum(address)>=0x10)
153+
{
154+
return 0x8000;
155+
}
156+
else
157+
{
158+
return 0x1000;
159+
}
160+
}
161+
162+
163+
uint32_t flash_get_page_size(const flash_t *obj)
164+
{
165+
return 1024;
166+
}
167+
168+
uint32_t flash_get_start_address(const flash_t *obj)
169+
{
170+
return LPC_FLASH_BASE;
171+
}
23172

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)
173+
uint32_t flash_get_size(const flash_t *obj)
62174
{
63-
obj->flash_algo = &flash_algo_config;
64-
obj->target_config = &flash_target_config;
175+
return 0x80000;
65176
}
66177

67178
#endif

targets/TARGET_NXP/TARGET_LPC176X/objects.h

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

74-
#ifdef __cplusplus
74+
struct flash_s {
75+
/* nothing to be stored for now */
76+
uint32_t dummy;
77+
};#ifdef __cplusplus
7578
}
7679
#endif
7780

0 commit comments

Comments
 (0)