OSDN Git Service

update libMiMic
[mimic/MiMicSDK.git] / lib / src / driver / flash / LPCxxx / NyLPC_cOnchipFlashWriter.c
1 #include "NyLPC_config.h"
2 #if NyLPC_MCU==NyLPC_MCU_LPC4088 || NyLPC_MCU==NyLPC_MCU_LPC17xx
3 #include "LPC17xx_IAP.h"
4 #include "NyLPC_cOnchipFlashWriter.h"
5
6
7 /**
8  * 指定したアドレスが、オンチップフラッシュかどうか
9  */
10 NyLPC_TBool NyLPC_cOnchipFlashWriter_isOnchipFlash(const void* i_addr)
11 {
12     unsigned long snum;
13     return LPC17xx_IAP_addr2Sector(i_addr,&snum)==LPC17xx_IAP_CMD_SUCCESS;
14 }
15
16 NyLPC_TUInt8 _work[256];
17
18
19 NyLPC_TBool NyLPC_cOnchipFlashWriter_write(const void* i_dest,const void* i_src,NyLPC_TUInt32 i_size)
20 {
21     NyLPC_TUInt32 size;
22     const char* src;
23     NyLPC_TUInt32 snum;
24     const char* fblock_addr;
25     const char* dest_addr;
26     NyLPC_TUInt32 wsize;
27     NyLPC_TUInt16 s_padding;
28     NyLPC_TUInt16 free_size;
29     if(i_size%4!=0){
30         NyLPC_OnErrorGoto(Error);
31     }
32     if(((NyLPC_TUInt32)i_dest)%4!=0){
33         NyLPC_OnErrorGoto(Error);
34     }
35     size=i_size;
36     src=(const char*)i_src;
37     dest_addr=(const char*)i_dest;
38     for(;size>0;){
39         //開始位置の端数を調べる
40         s_padding=((NyLPC_TUInt32)dest_addr)%256;
41         //書き込みアドレス取得
42         fblock_addr=dest_addr-s_padding;
43         //書込み可能サイズを計算
44         free_size=256-s_padding;
45         //書込みサイズを決定
46         wsize=(free_size>size)?size:free_size;
47         //Flashから一時RAMへ前方パディングを読む
48         if(s_padding>0){
49             memcpy(_work,fblock_addr,s_padding);
50         }
51         //書き込むデータを一時RAMへ書き込む
52         memcpy(_work+s_padding,src,wsize);
53         //後半
54         if(256-(wsize+s_padding)>0){
55             memcpy(_work+s_padding+wsize,fblock_addr+(wsize+s_padding),256-(wsize+s_padding));
56         }
57
58         //Flashへ書込み
59         //開始セクタ
60         if(!LPC17xx_IAP_addr2Sector(fblock_addr,&snum)){
61             NyLPC_OnErrorGoto(Error);
62         }
63         //IAPのprepareコマンド
64
65         if(LPC17xx_IAP_CMD_SUCCESS!=LPC17xx_IAP_prepare(snum,snum)){
66             NyLPC_OnErrorGoto(Error);
67         }
68         //IAPのwriteコマンド
69         if(LPC17xx_IAP_CMD_SUCCESS!=LPC17xx_IAP_copyRam2Flash(fblock_addr,_work,256)){
70             NyLPC_OnErrorGoto(Error);
71         }
72         dest_addr+=wsize;
73         src+=wsize;
74         size-=wsize;
75     }
76     return NyLPC_TBool_TRUE;
77 Error:
78     return NyLPC_TBool_FALSE;
79 }
80
81 /**
82  * セクタ+オフセット形式で、データを書き込みます。
83  */
84 NyLPC_TBool NyLPC_cOnchipFlashWriter_writeSector(NyLPC_TUInt16 i_sector,NyLPC_TUInt32 i_offset,const void* i_src,NyLPC_TUInt32 i_size)
85 {
86     void* addr;
87     if(!LPC17xx_IAP_sector2Addr(i_sector,&addr)){
88         return NyLPC_TBool_FALSE;
89     }
90     addr=(void*)((NyLPC_TUInt32)addr+i_offset);
91     return NyLPC_cOnchipFlashWriter_write(addr,i_src,i_size);
92
93 }
94 /**
95  * FlashRomのセクタ番号Nにイレースを実行します。
96  */
97 NyLPC_TBool NyLPC_cOnchipFlashWriter_elase(NyLPC_TUInt16 i_sector_s,NyLPC_TUInt16 i_sector_e)
98 {
99     if(LPC17xx_IAP_CMD_SUCCESS!=LPC17xx_IAP_prepare(i_sector_s,i_sector_e)){
100         return NyLPC_TBool_FALSE;
101     }
102     if(LPC17xx_IAP_CMD_SUCCESS!=LPC17xx_IAP_erase(i_sector_s,i_sector_e)){
103         return NyLPC_TBool_FALSE;
104     }
105     return NyLPC_TBool_TRUE;
106 }
107
108
109
110 #ifdef TEST
111 #include "stdio.h"
112 unsigned long buf[128]={0x1,0x2,0x03,0x04,0x05};
113 #define MIMIC_CONFIG_ADDR ((long*)(0x00018000+1280))
114 void setup(void)
115 {
116     NyLPC_TcFlashWriter_t writer;
117     NyLPC_cFlashWriter_initialize(&writer);
118     unsigned long p;
119     NyLPC_cFlashWriter_elase(&writer,29);
120 //  NyLPC_cFlashWriter_write(&writer,MIMIC_CONFIG_ADDR-8,buf,5*4);
121     NyLPC_cFlashWriter_finalize(&writer);
122     return;
123 }
124 void loop(void)
125 {
126     //Implementation
127     //ここにメインタスクを書きます。
128     for(;;){}
129 }
130 #endif
131 #endif