bsp_cpu_flash.c
6.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
/*
*********************************************************************************************************
*
* 模块名称 : cpu内部falsh操作模块(for F4)
* 文件名称 : bsp_cpu_flash.c
* 版 本 : V1.0
* 说 明 : 提供读写CPU内部Flash的函数
*
*********************************************************************************************************
*/
#include "bsp.h"
#include "bsp_cpu_flash.h"
/*
*********************************************************************************************************
* 函 数 名: bsp_GetSector
* 功能说明: 根据地址计算扇区首地址
* 形 参: 无
* 返 回 值: 扇区首地址
*********************************************************************************************************
*/
uint32_t bsp_GetSector(uint32_t Address)
{
uint32_t sector = 0;
if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
{
sector = FLASH_Sector_0;
}
else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
{
sector = FLASH_Sector_1;
}
else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
{
sector = FLASH_Sector_2;
}
else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
{
sector = FLASH_Sector_3;
}
else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
{
sector = FLASH_Sector_4;
}
else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
{
sector = FLASH_Sector_5;
}
else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
{
sector = FLASH_Sector_6;
}
else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
{
sector = FLASH_Sector_7;
}
else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
{
sector = FLASH_Sector_8;
}
else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
{
sector = FLASH_Sector_9;
}
else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
{
sector = FLASH_Sector_10;
}
else /*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_11))*/
{
sector = FLASH_Sector_11;
}
return sector;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_ReadCpuFlash
* 功能说明: 读取CPU Flash的内容
* 形 参: _ucpDst : 目标缓冲区
* _ulFlashAddr : 起始地址
* _ulSize : 数据大小(单位是字节)
* 返 回 值: 0=成功,1=失败
*********************************************************************************************************
*/
uint8_t bsp_ReadCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpDst, uint32_t _ulSize)
{
uint32_t i;
/* 如果偏移地址超过芯片容量,则不改写输出缓冲区 */
if (_ulFlashAddr + _ulSize > FLASH_BASE_ADDR + FLASH_SIZE)
{
return 1;
}
/* 长度为0时不继续操作,否则起始地址为奇地址会出错 */
if (_ulSize == 0)
{
return 1;
}
for (i = 0; i < _ulSize; i++)
{
*_ucpDst++ = *(uint8_t *)_ulFlashAddr++;
}
return 0;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_CmpCpuFlash
* 功能说明: 比较Flash指定地址的数据.
* 形 参: _ulFlashAddr : Flash地址
* _ucpBuf : 数据缓冲区
* _ulSize : 数据大小(单位是字节)
* 返 回 值:
* FLASH_IS_EQU 0 Flash内容和待写入的数据相等,不需要擦除和写操作
* FLASH_REQ_WRITE 1 Flash不需要擦除,直接写
* FLASH_REQ_ERASE 2 Flash需要先擦除,再写
* FLASH_PARAM_ERR 3 函数参数错误
*********************************************************************************************************
*/
uint8_t bsp_CmpCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpBuf, uint32_t _ulSize)
{
uint32_t i;
uint8_t ucIsEqu; /* 相等标志 */
uint8_t ucByte;
/* 如果偏移地址超过芯片容量,则不改写输出缓冲区 */
if (_ulFlashAddr + _ulSize > FLASH_BASE_ADDR + FLASH_SIZE)
{
return FLASH_PARAM_ERR; /* 函数参数错误 */
}
/* 长度为0时返回正确 */
if (_ulSize == 0)
{
return FLASH_IS_EQU; /* Flash内容和待写入的数据相等 */
}
ucIsEqu = 1; /* 先假设所有字节和待写入的数据相等,如果遇到任何一个不相等,则设置为 0 */
for (i = 0; i < _ulSize; i++)
{
ucByte = *(uint8_t *)_ulFlashAddr;
if (ucByte != *_ucpBuf)
{
if (ucByte != 0xFF)
{
return FLASH_REQ_ERASE; /* 需要擦除后再写 */
}
else
{
ucIsEqu = 0; /* 不相等,需要写 */
}
}
_ulFlashAddr++;
_ucpBuf++;
}
if (ucIsEqu == 1)
{
return FLASH_IS_EQU; /* Flash内容和待写入的数据相等,不需要擦除和写操作 */
}
else
{
return FLASH_REQ_WRITE; /* Flash不需要擦除,直接写 */
}
}
/*
*********************************************************************************************************
* 函 数 名: bsp_WriteCpuFlash
* 功能说明: 写数据到CPU 内部Flash。
* 形 参: _ulFlashAddr : Flash地址
* _ucpSrc : 数据缓冲区
* _ulSize : 数据大小(单位是字节)
* 返 回 值: 0-成功,1-数据长度或地址溢出,2-写Flash出错(估计Flash寿命到)
*********************************************************************************************************
*/
uint8_t bsp_WriteCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpSrc, uint32_t _ulSize)
{
uint32_t i;
uint8_t ucRet;
/* 如果偏移地址超过芯片容量,则不改写输出缓冲区 */
if (_ulFlashAddr + _ulSize > FLASH_BASE_ADDR + FLASH_SIZE)
{
return 1;
}
/* 长度为0时不继续操作 */
if (_ulSize == 0)
{
return 0;
}
ucRet = bsp_CmpCpuFlash(_ulFlashAddr, _ucpSrc, _ulSize);
if (ucRet == FLASH_IS_EQU)
{
return 0;
}
__set_PRIMASK(1); /* 关中断 */
/* FLASH 解锁 */
FLASH_Unlock();
/* Clear pending flags (if any) */
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
/* 需要擦除 */
if (ucRet == FLASH_REQ_ERASE)
{
FLASH_EraseSector(bsp_GetSector(_ulFlashAddr), VoltageRange_3);
}
/* 按字节模式编程(为提高效率,可以按字编程,一次写入4字节) */
// TIM_SetCounter(TIM3, 0);
for (i = 0; i < _ulSize; i++)
{
FLASH_ProgramByte(_ulFlashAddr++, *_ucpSrc++);
}
// printf(" Write = %d \r\n",TIM_GetCounter(TIM3));
/* Flash 加锁,禁止写Flash控制寄存器 */
FLASH_Lock();
__set_PRIMASK(0); /* 开中断 */
return 0;
}
/*
* 函数功能:擦除FLASH
*
*/
void bsp_FLASH_EraseSector(uint32_t _ulFlashAddr)
{
__set_PRIMASK(1); /* 关中断 */
/* FLASH 解锁 */
FLASH_Unlock();
//擦除FLASH
FLASH_EraseSector(bsp_GetSector(_ulFlashAddr), VoltageRange_3);
FLASH_Lock();
__set_PRIMASK(0); /* 开中断 */
}
/*
* 函数功能:写FLASH
*/
void bsp_FLASH_Write(uint32_t _ulFlashAddr, uint8_t *_ucpSrc, uint32_t _ulSize)
{
u8 i = 0;
__set_PRIMASK(1); /* 关中断 */
/* FLASH 解锁 */
FLASH_Unlock();
//擦除FLASH
for (i = 0; i < _ulSize; i++)
{
FLASH_ProgramByte(_ulFlashAddr++, *_ucpSrc++);
}
FLASH_Lock();
__set_PRIMASK(0);
}