source: uKadecot/trunk/src/ukadecot/data_flash.c@ 101

Last change on this file since 101 was 101, checked in by coas-nagasima, 9 years ago

TOPPERS/uKadecotのソースコードを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/plain
File size: 11.3 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2014 Cores Co., Ltd. Japan
5 *
6 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
7 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
8 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
9 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
10 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
11 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
12 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
13 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
14ƒƒ“ƒgi—˜—p
15 * ŽÒƒ}ƒjƒ…
16ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
17 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
18 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
19 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
20 * ‚ƁD
21 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
22ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
23ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
24 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
25 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
26 * •ñ‚·‚邱‚ƁD
27 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
28 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
29 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
30 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
31 * –Ɛӂ·‚邱‚ƁD
32 *
33 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
34 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
35 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
36 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
37 * ‚̐ӔC‚𕉂í‚È‚¢D
38 *
39 * @(#) $Id: data_flash.c 101 2015-06-02 15:37:23Z coas-nagasima $
40 */
41
42/*
43 * ƒTƒ“ƒvƒ‹ƒvƒƒOƒ‰ƒ€(1)‚Ì–{‘Ì
44 */
45
46#include <kernel.h>
47#include <t_syslog.h>
48#include <sil.h>
49#include "data_flash.h"
50#ifdef __RX
51#include "rx630_ccrx/rx630.h"
52#else
53#include "rx630_msvc/rx630.h"
54#endif
55#include "grsakura.h"
56
57#define FLASH_FWEPROR_ADDR ( ( volatile uint8_t __evenaccess * )0x0008C296 )
58
59#define FLASH_FMODR_ADDR ( ( volatile uint8_t __evenaccess * )0x007FC402 )
60#define FLASH_FMODR_FRDMD_BIT ( 0x01U << 4U )
61
62#define FLASH_DFLRE0_ADDR ( ( volatile uint16_t __evenaccess * )0x007FC440 )
63#define FLASH_DFLRE1_ADDR ( ( volatile uint16_t __evenaccess * )0x007FC442 )
64#define FLASH_DFLWE0_ADDR ( ( volatile uint16_t __evenaccess * )0x007FC450 )
65#define FLASH_DFLWE1_ADDR ( ( volatile uint16_t __evenaccess * )0x007FC452 )
66#define FLASH_FCURAME_ADDR ( ( volatile uint16_t __evenaccess * )0x007FC454 )
67
68#define FLASH_FASTAT_ADDR ( ( volatile uint8_t __evenaccess * )0x007FC410 )
69#define FLASH_FASTAT_DFLWPE_BIT ( 0x01U << 0 )
70#define FLASH_FASTAT_DFLRPE_BIT ( 0x01U << 1 )
71#define FLASH_FASTAT_DFLAE_BIT ( 0x01U << 3 )
72#define FLASH_FASTAT_CMDLK_BIT ( 0x01U << 4 )
73#define FLASH_FASTAT_ROMAE_BIT ( 0x01U << 7 )
74
75#define FLASH_FENTRYR_ADDR ( ( volatile uint16_t __evenaccess * )0x007FFFB2 )
76#define FLASH_FENTRYR_FENRTY0_BIT ( 0x0001U << 0U )
77#define FLASH_FENTRYR_FENRTY1_BIT ( 0x0001U << 1U )
78#define FLASH_FENTRYR_FENRTY2_BIT ( 0x0001U << 2U )
79#define FLASH_FENTRYR_FENRTY3_BIT ( 0x0001U << 3U )
80#define FLASH_FENTRYR_FENTRYD_BIT ( 0x0001U << 7U )
81
82#define FLASH_FRESETR_ADDR ( ( volatile uint16_t __evenaccess * )0x007FFFB6 )
83#define FLASH_FRESETR_FRESET_BIT ( 0x0001U << 0 )
84
85#define FLASH_DFLBCCNT_ADDR ( ( volatile uint16_t __evenaccess * )0x007FFFCA )
86#define FLASH_DFLBCCNT_BCSIZE_BIT ( 0x0001U << 15U )
87#define FLASH_DFLBCCNT_BCADR_OFFSET ( 0U )
88#define FLASH_DFLBCCNT_BCADR_MASK ( 0x7FFU << FLASH_DFLBCCNT_BCADR_OFFSET )
89
90#define FLASH_DFLBCSTAT_ADDR ( ( volatile uint16_t __evenaccess * )0x007FFFCE )
91#define FLASH_DFLBCSTAT_BCST_BIT ( 0x0001U << 0U )
92
93#define FLASH_FSTATR0_ADDR ( ( volatile uint8_t __evenaccess * )0x007FFFB0 )
94#define FLASH_FSTATR0_PRGSPD_BIT ( 0x01U << 0 )
95#define FLASH_FSTATR0_ERSSPD_BIT ( 0x01U << 1 )
96#define FLASH_FSTATR0_SUSRDY_BIT ( 0x01U << 3 )
97#define FLASH_FSTATR0_PRGERR_BIT ( 0x01U << 4 )
98#define FLASH_FSTATR0_ERSERR_BIT ( 0x01U << 5 )
99#define FLASH_FSTATR0_ILGLERR_BIT ( 0x01U << 6 )
100#define FLASH_FSTATR0_FRDY_BIT ( 0x01U << 7 )
101
102#define FLASH_PCKAR_ADDR ( ( volatile uint16_t __evenaccess * )0x007FFFE8 )
103
104#define DATA_FLASH_BLOCK_SIZE 32
105#ifndef _MSC_VER
106#define DATA_FLASH_BASE_ADDR 0x00100000
107#define FCU_FIRMWARE_ADDR 0xFEFFE000
108#define FCU_RAM_ADDR 0x007F8000
109#else
110uint8_t DATA_FLASH_BASE_ADDR[DATA_FLASH_BLOCK_SIZE * 1024];
111uint8_t FCU_FIRMWARE_ADDR[0x2000];
112uint8_t FCU_RAM_ADDR[0x2000];
113#endif
114
115static void fcu_init();
116static void fcu_copy_firm();
117static bool_t fcu_notify_clock();
118static void fcu_read_mode();
119static void fcu_pe_mode();
120static bool_t fcu_write(int blockno, void *data);
121static bool_t fcu_erase(int blockno);
122static bool_t fcu_check_blank(int blockno);
123static bool_t fcu_check_valid(int blockno);
124static bool_t fcu_check_frdy(int tWAIT);
125static bool_t fcu_check_error();
126
127ER data_flash_init()
128{
129 ER ret;
130
131 /* E2ƒf[ƒ^ƒtƒ‰ƒbƒVƒ…
132‚̓ǂݍž‚Ý‹–‰Â */
133 sil_wrh_mem(FLASH_DFLRE0_ADDR, 0x2DFF);
134 sil_wrh_mem(FLASH_DFLRE1_ADDR, 0xD2FF);
135 /* E2ƒf[ƒ^ƒtƒ‰ƒbƒVƒ…
136‚̏‘‚«ž‚Ý‹–‰Â */
137 sil_wrh_mem(FLASH_DFLWE0_ADDR, 0x1EFF);
138 sil_wrh_mem(FLASH_DFLWE1_ADDR, 0xE1FF);
139
140 /* tE16K = 240ms*/
141 fcu_check_frdy(240000);
142
143 /* ƒGƒ‰[Šm”F */
144 fcu_check_error();
145
146 /* FCUƒtƒ@[ƒ€ƒEƒFƒA‚̃Rƒs[ */
147 fcu_copy_firm();
148
149 /* P/Eƒ‚[ƒhˆÚs */
150 fcu_pe_mode();
151
152 /* P/E ƒm[ƒ}ƒ‹ƒ‚[ƒhˆÚs */
153 *((uint8_t *)DATA_FLASH_BASE_ADDR) = 0xFF;
154
155 /* ƒGƒ‰[Šm”F */
156 fcu_check_error();
157
158 /* Žü•ÓƒNƒƒbƒN’Ê’mƒRƒ}ƒ“ƒh”­s */
159 ret = fcu_notify_clock();
160
161 /* ƒŠ[ƒhƒ‚[ƒhˆÚs */
162 fcu_read_mode();
163
164 return ret ? E_OK : E_SYS;
165}
166
167ER data_flash_read(int blockno, void *data)
168{
169 uint16_t *wa, *end;
170 uint16_t *dst = (uint16_t *)data;
171
172 /* P/Eƒ‚[ƒhˆÚs */
173 fcu_pe_mode();
174
175 /* —LŒøƒf[ƒ^ƒ`ƒFƒbƒN */
176 if(!fcu_check_valid(blockno)){
177 /* ƒŠ[ƒhƒ‚[ƒhˆÚs */
178 fcu_read_mode();
179 return E_OBJ;
180 }
181
182 /* ƒŠ[ƒhƒ‚[ƒhˆÚs */
183 fcu_read_mode();
184
185 wa = (uint16_t *)(DATA_FLASH_BLOCK_SIZE * blockno + (intptr_t)DATA_FLASH_BASE_ADDR);
186 end = &wa[DATA_FLASH_BLOCK_SIZE/sizeof(uint16_t)];
187
188 /* “ǂݏo‚µ */
189 for(; wa < end; wa++, dst++){
190 *dst = *wa;
191 }
192
193 return E_OK;
194}
195
196ER data_flash_write(int blockno, void *data)
197{
198 bool_t ret = true;
199
200 /* P/Eƒ‚[ƒhˆÚs */
201 fcu_pe_mode();
202
203 /* ƒuƒ‰ƒ“ƒNƒ`ƒFƒbƒN */
204 if(!fcu_check_blank(blockno)){
205 /* ƒuƒ‰ƒ“ƒN‚Å‚È‚¢‚È‚çƒuƒƒbƒNÁ‹Ž */
206 ret = fcu_erase(blockno);
207 if(!ret)
208 syslog(LOG_DEBUG, "fcu_erase() result = %d", ret);
209 }
210
211 if(ret){
212 /* ‘‚«ž‚Ý */
213 ret = fcu_write(blockno, data);
214 if(!ret)
215 syslog(LOG_DEBUG, "fcu_write() result = %d", ret);
216 }
217
218 /* ƒŠ[ƒhƒ‚[ƒhˆÚs */
219 fcu_read_mode();
220
221 return ret ? E_OK : E_SYS;
222}
223
224static void fcu_copy_firm()
225{
226 unsigned int *src, *dst, *end;
227
228 /* ƒŠ[ƒhƒ‚[ƒhˆÚs */
229 if(sil_reh_mem(FLASH_FENTRYR_ADDR) != 0)
230 sil_wrh_mem(FLASH_FENTRYR_ADDR, 0xAA00);
231
232 /* FCU RAMƒAƒNƒZƒX‹–‰Â */
233 sil_wrh_mem(FLASH_FCURAME_ADDR, 0xC401);
234
235 /* FCUƒtƒ@[ƒ€ƒEƒFƒA‚ðFCU RAM‚ɃRƒs[ */
236 src = (unsigned int *)FCU_FIRMWARE_ADDR;
237 dst = (unsigned int *)FCU_RAM_ADDR;
238 end = &dst[0x2000 / sizeof(unsigned int)];
239 for(; dst < end; dst++, src++)
240 *dst = *src;
241}
242
243static bool_t fcu_notify_clock()
244{
245 volatile uint8_t *ra;
246 volatile uint16_t *wa;
247
248 ra = (volatile uint8_t *)(DATA_FLASH_BASE_ADDR);
249 wa = (volatile uint16_t *)ra;
250
251 /* Žü”g”‚ðÝ’è */
252 sil_wrh_mem(FLASH_PCKAR_ADDR, 48/*FREQ_PCLK / 1000*/);
253
254 /* Žü•ÓƒNƒƒbƒN’Ê’mƒRƒ}ƒ“ƒh”­s */
255 *ra = 0xE9;
256 *ra = 0x03;
257 *wa = 0x0F0F;
258 *wa = 0x0F0F;
259 *wa = 0x0F0F;
260 *ra = 0xD0;
261
262 /* 120ƒÊs */
263 fcu_check_frdy(120);
264
265 /* ƒGƒ‰[Šm”F */
266 return !fcu_check_error();
267}
268
269/*
270 * ƒŠ[ƒhƒ‚[ƒhˆÚs
271 */
272static void fcu_read_mode()
273{
274 int i;
275
276 for(;;){
277 for(i = 0; i < 1000; i++){
278 sil_wrh_mem(FLASH_FENTRYR_ADDR, 0xAA00);
279
280 if(sil_reh_mem(FLASH_FENTRYR_ADDR) != 0)
281 continue;
282
283 sil_wrb_mem(FLASH_FWEPROR_ADDR, 0x02);
284 return;
285 }
286
287 syslog(LOG_WARNING, "fcu_read_mode");
288 }
289}
290
291/*
292 * P/Eƒ‚[ƒhˆÚs
293 */
294static void fcu_pe_mode()
295{
296 sil_wrh_mem(FLASH_FENTRYR_ADDR, 0xAA80);
297 sil_wrb_mem(FLASH_FWEPROR_ADDR, 0x01);
298}
299
300static bool_t fcu_write(int blockno, void *data)
301{
302 volatile uint8_t *ra;
303 volatile uint16_t *wa, *end;
304 uint16_t *src = (uint16_t *)data;
305
306 ra = (volatile uint8_t *)(DATA_FLASH_BLOCK_SIZE * blockno + (intptr_t)DATA_FLASH_BASE_ADDR);
307 end = (volatile uint16_t *)(((intptr_t)ra) + DATA_FLASH_BLOCK_SIZE);
308
309 for(wa = (volatile uint16_t *)ra; wa < end; wa++, src++)
310 {
311 /* ƒvƒƒOƒ‰ƒ€ƒRƒ}ƒ“ƒh”­s */
312 *ra = 0xE8;
313 *ra = 0x01;
314 *wa = *src;
315 *ra = 0xD0;
316
317 /* 2ms~1.1 */
318 fcu_check_frdy(2200);
319
320 /* ƒGƒ‰[Šm”F */
321 if(fcu_check_error())
322 return false;
323 }
324
325 return true;
326}
327
328static bool_t fcu_erase(int blockno)
329{
330 volatile uint8_t *ra;
331
332 ra = (volatile uint8_t *)(DATA_FLASH_BLOCK_SIZE * blockno + (intptr_t)DATA_FLASH_BASE_ADDR);
333
334 /* ƒCƒŒ[ƒXƒRƒ}ƒ“ƒh”­s */
335 *ra = 0x20;
336 *ra = 0xD0;
337
338 /* 20ms~1.1 */
339 fcu_check_frdy(22000);
340
341 /* ƒGƒ‰[Šm”F */
342 return !fcu_check_error();
343}
344
345static bool_t fcu_check_blank(int blockno)
346{
347 volatile uint8_t *ra;
348 volatile uint16_t *wa, *end;
349
350 sil_wrb_mem(FLASH_FMODR_ADDR, sil_reb_mem(FLASH_FMODR_ADDR) | FLASH_FMODR_FRDMD_BIT);
351
352 wa = (volatile uint16_t *)(DATA_FLASH_BLOCK_SIZE * blockno + (intptr_t)DATA_FLASH_BASE_ADDR);
353 end = (volatile uint16_t *)(((intptr_t)wa) + DATA_FLASH_BLOCK_SIZE);
354
355 for(; wa < end; wa++)
356 {
357 sil_wrh_mem(FLASH_DFLBCCNT_ADDR, (((intptr_t)wa) & FLASH_DFLBCCNT_BCADR_MASK) << FLASH_DFLBCCNT_BCADR_OFFSET);
358
359 ra = (volatile uint8_t *)wa;
360 *ra = 0x71;
361 *ra = 0xD0;
362
363 /* 30ƒÊs~1.1 */
364 fcu_check_frdy(33);
365
366 /* ƒGƒ‰[Šm”F */
367 if(fcu_check_error())
368 return false;
369
370 /* ƒuƒ‰ƒ“ƒNŠm”F */
371 if((sil_reh_mem(FLASH_DFLBCSTAT_ADDR) & FLASH_DFLBCSTAT_BCST_BIT) != 0)
372 return false;
373 }
374
375 return true;
376}
377
378static bool_t fcu_check_valid(int blockno)
379{
380 volatile uint8_t *ra;
381 volatile uint16_t *wa, *end;
382
383 sil_wrb_mem(FLASH_FMODR_ADDR, sil_reb_mem(FLASH_FMODR_ADDR) | FLASH_FMODR_FRDMD_BIT);
384
385 wa = (volatile uint16_t *)(DATA_FLASH_BLOCK_SIZE * blockno + (intptr_t)DATA_FLASH_BASE_ADDR);
386 end = (volatile uint16_t *)(((intptr_t)wa) + DATA_FLASH_BLOCK_SIZE);
387
388 for(; wa < end; wa++)
389 {
390 sil_wrh_mem(FLASH_DFLBCCNT_ADDR, (((intptr_t)wa) & FLASH_DFLBCCNT_BCADR_MASK) << FLASH_DFLBCCNT_BCADR_OFFSET);
391
392 ra = (volatile uint8_t *)wa;
393 *ra = 0x71;
394 *ra = 0xD0;
395
396 /* 30ƒÊs~1.1 */
397 fcu_check_frdy(33);
398
399 /* ƒGƒ‰[Šm”F */
400 if(fcu_check_error())
401 return false;
402
403 /* ƒuƒ‰ƒ“ƒNŠm”F */
404 if((sil_reh_mem(FLASH_DFLBCSTAT_ADDR) & FLASH_DFLBCSTAT_BCST_BIT) == 0)
405 return false;
406 }
407
408 return true;
409}
410
411static bool_t fcu_check_error()
412{
413 uint8_t status;
414
415 status = sil_reb_mem(FLASH_FSTATR0_ADDR);
416
417 if((status & (FLASH_FSTATR0_ILGLERR_BIT | FLASH_FSTATR0_ERSERR_BIT | FLASH_FSTATR0_PRGERR_BIT)) == 0)
418 return false;
419
420 if((status & FLASH_FSTATR0_ILGLERR_BIT) != 0){
421 if(sil_reb_mem(FLASH_FASTAT_ADDR) != 0x10){
422 sil_wrb_mem(FLASH_FASTAT_ADDR, 0x10);
423 }
424
425 /* ƒXƒe[ƒ^ƒXƒNƒŠƒAƒRƒ}ƒ“ƒh”­s */
426 *((uint8_t *)DATA_FLASH_BASE_ADDR) = 0x50;
427 }
428
429 syslog(LOG_WARNING, "fcu_check_error %02x", status);
430
431 return true;
432}
433
434static bool_t fcu_check_frdy(int tWAIT)
435{
436 int i, j;
437
438 for(i = 0; i < tWAIT; i++){
439 /* €”õŠ®—¹‚È‚çI—¹ */
440 if((sil_reb_mem(FLASH_FSTATR0_ADDR) & FLASH_FSTATR0_FRDY_BIT) != 0)
441 return true;
442
443 /* 1ƒÊs? */
444 for(j = 0; j < 100; j++);
445 }
446
447 syslog(LOG_WARNING, "fcu_check_frdy timeout");
448
449 /* FCU‰Šú‰» */
450 fcu_init();
451
452 return false;
453}
454
455static void fcu_init()
456{
457 int j;
458
459 sil_wrh_mem(FLASH_FRESETR_ADDR, 0xCC01);
460
461 // 200ƒÊs? */
462 for(j = 0; j < 20000; j++);
463
464 sil_wrh_mem(FLASH_FRESETR_ADDR, 0xCC00);
465}
Note: See TracBrowser for help on using the repository browser.