提交 | 用户 | age
|
483170
|
1 |
/** |
Q |
2 |
****************************************************************************** |
|
3 |
* @file : KMachine.c |
|
4 |
* @brief : KMachine program body |
|
5 |
****************************************************************************** |
|
6 |
*/ |
|
7 |
|
|
8 |
#include "KMachine.h" |
|
9 |
#include "string.h" |
|
10 |
#include "Globaldef.h" |
|
11 |
#include "stm32f0xx_hal.h" |
|
12 |
|
|
13 |
//#define OB_BASE ((uint32_t)0x1FFFF800U) /*!< FLASH Option Bytes base address */ |
|
14 |
//#define FLASHSIZE_BASE ((uint32_t)0x1FFFF7CCU) /*!< FLASH Size register base address */ |
|
15 |
//#define UID_BASE ((uint32_t)0x1FFFF7ACU) /*!< Unique device ID register base address */ |
|
16 |
|
|
17 |
|
|
18 |
stStoredKMSysCfg storedKMSysCfg ; |
|
19 |
stKMem KMem; |
|
20 |
stRunStat KMRunStat; |
|
21 |
|
|
22 |
//uint8_t * pFlash1 = (uint8_t *)(STORECFGBASE); |
|
23 |
|
|
24 |
//void * pConfigFlashBase = (uint8_t *)(STORECFGBASE); |
|
25 |
|
|
26 |
//uint16_t FlashDatas[16]; |
|
27 |
|
|
28 |
//uint32_t * pUID = (uint32_t *)(UID_BASE); |
|
29 |
const stKMInfoBlock KMInfoBlock = |
|
30 |
{ |
|
31 |
// sizeof(stKMInfoBlock), |
|
32 |
(BOARD_TYPE<<8) + BOARD_VER, //nDeviceType BOARD_VER, //nDevieVer |
|
33 |
0x0100, //ProgVer |
|
34 |
0x0100, //KLinkVer |
|
35 |
0x0100, //KBusVer |
|
36 |
|
|
37 |
4, //nCapacity1 ?K |
|
38 |
1, //nCapacity2 ?k |
|
39 |
16, //nDInput; |
|
40 |
16, //nDOutput |
|
41 |
0, //nAInput |
|
42 |
0, //nAOutput |
|
43 |
0, //nHInput |
|
44 |
0, //nHOutput |
|
45 |
0, //nExt1; |
|
46 |
0, //nExt2; |
|
47 |
0, //nLogSize; |
|
48 |
0, //nPorts; |
|
49 |
0, //nManSize; |
|
50 |
0, //nAbility; |
|
51 |
6, //nSwitchBits; |
|
52 |
}; |
|
53 |
const char VersionStr[] __attribute__((at(FLASH_BASE + 0X1000))) //__attribute__((at(0X8001000))) |
|
54 |
= "3.00"; |
|
55 |
|
|
56 |
const stStoredKMSysCfg KMDefaultSysCfg /*__attribute__((at(STORECFGBASE)))*/ = |
|
57 |
{ |
|
58 |
START_SIGN, |
|
59 |
0x0000, |
|
60 |
|
|
61 |
CFG_VER, |
|
62 |
0x0000, |
|
63 |
0x0000, |
|
64 |
0x0000, |
|
65 |
{ |
|
66 |
{ |
|
67 |
PortType_KLink, //PorttType |
|
68 |
1, //Station |
|
69 |
2304, //Buadrate = * 100; |
|
70 |
0, //ByteSize |
|
71 |
0, //Parity |
|
72 |
0, //StopBits |
|
73 |
0, //endType |
|
74 |
0, //EofChar |
|
75 |
0, //SofChar |
|
76 |
0, //endtime |
|
77 |
0, //recvbuf |
|
78 |
0, //bufsize |
|
79 |
}, |
|
80 |
{ |
|
81 |
PortType_KBus, //PorttType |
|
82 |
0, //Station |
|
83 |
2304, //Buadrate = * 100; |
|
84 |
0, //ByteSize |
|
85 |
0, //Parity |
|
86 |
0, //StopBits |
|
87 |
0, //endType |
|
88 |
0, //EofChar |
|
89 |
0, //SofChar |
|
90 |
0, //endtime |
|
91 |
0, //recvbuf |
|
92 |
0, //bufsize |
|
93 |
} |
|
94 |
}, |
|
95 |
{{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}}, |
|
96 |
{{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1}}, |
|
97 |
{ //default port mapping |
|
98 |
0,0,0,0,0,0 |
|
99 |
}, |
|
100 |
0x0003, |
|
101 |
0x0004, |
|
102 |
0x0005, |
|
103 |
0x0006, |
|
104 |
0x0007, |
|
105 |
0x0008, |
|
106 |
0x0009, |
|
107 |
0x000a, |
|
108 |
0x000b, |
|
109 |
0x000c, |
|
110 |
|
|
111 |
0x0011, |
|
112 |
END_SIGN, |
|
113 |
}; |
|
114 |
|
|
115 |
const stKMSysCfg KMDefaultSysCfg2[7] /*__attribute__((at(STORECFGBASE+sizeof(stKMSysCfg))))*/; |
|
116 |
|
|
117 |
int ReadFlashMem(void * pBuf, void * pAddrFlash, int nByteSize) |
|
118 |
{ |
|
119 |
// memcpy(pBuf,pAddrFlash,nSize); |
|
120 |
for (int i=0;i<nByteSize/4;i++) |
|
121 |
{ |
|
122 |
((uint32_t *)pBuf)[i] = ((uint32_t *)pAddrFlash)[i]; |
|
123 |
} |
|
124 |
for (int i=nByteSize/4*2;i<nByteSize/2;i++) |
|
125 |
{ |
|
126 |
((uint16_t *)pBuf)[i] = ((uint16_t *)pAddrFlash)[i]; |
|
127 |
} |
|
128 |
return nByteSize; |
|
129 |
} |
|
130 |
int EraseFlashMem(void * pAddrFlash, unsigned int Pages) |
|
131 |
{ |
|
132 |
HAL_StatusTypeDef res; |
|
133 |
res = HAL_FLASH_Unlock(); |
|
134 |
uint32_t ErrNo; |
|
135 |
FLASH_EraseInitTypeDef erase1; |
|
136 |
erase1.NbPages=Pages; |
|
137 |
erase1.PageAddress=(unsigned int)pAddrFlash; |
|
138 |
erase1.TypeErase=FLASH_TYPEERASE_PAGES; |
|
139 |
res = HAL_FLASHEx_Erase(&erase1,&ErrNo); |
|
140 |
res = HAL_FLASH_Lock(); |
|
141 |
return res; |
|
142 |
} |
|
143 |
int WriteToFlashMemNoErase(void * pBuf, void * pAddrFlash, unsigned int nByteSize) |
|
144 |
{ |
|
145 |
HAL_StatusTypeDef res; |
|
146 |
res = HAL_FLASH_Unlock(); |
|
147 |
/* |
|
148 |
for (int i=0;i<nSize/2;i++) |
|
149 |
{ |
|
150 |
res = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)pAddrFlash + i*2, ((uint16_t *)pBuf)[i]); |
|
151 |
} |
|
152 |
*/ |
|
153 |
///* |
|
154 |
for (int i=0;i<nByteSize/4;i++) |
|
155 |
{ |
|
156 |
res = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (uint32_t)pAddrFlash + i*4, ((uint32_t *)pBuf)[i]); |
|
157 |
} |
|
158 |
|
|
159 |
for (int i = nByteSize/4 * 2 ; i < nByteSize/2 ; i++) |
|
160 |
{ |
|
161 |
res = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)pAddrFlash + i*2, ((uint16_t *)pBuf)[i]); |
|
162 |
} |
|
163 |
//*/ |
|
164 |
res = HAL_FLASH_Lock(); |
|
165 |
|
|
166 |
return res; |
|
167 |
} |
|
168 |
int EraseAndWriteToFlashMem(void * pBuf, void * pAddrFlash, unsigned int nByteSize) |
|
169 |
{ |
|
170 |
|
|
171 |
HAL_StatusTypeDef res; |
|
172 |
res = HAL_FLASH_Unlock(); |
|
173 |
uint32_t ErrNo; |
|
174 |
FLASH_EraseInitTypeDef erase1; |
|
175 |
erase1.NbPages=1; |
|
176 |
erase1.PageAddress=(unsigned int)pAddrFlash; |
|
177 |
erase1.TypeErase=FLASH_TYPEERASE_PAGES; |
|
178 |
res = HAL_FLASHEx_Erase(&erase1,&ErrNo); |
|
179 |
|
|
180 |
for (int i=0;i<nByteSize/2;i++) |
|
181 |
{ |
|
182 |
res = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)pAddrFlash + i*2, ((uint16_t *)pBuf)[i]); |
|
183 |
} |
|
184 |
/* |
|
185 |
for (int i=0;i<nSize/4;i++) |
|
186 |
{ |
|
187 |
res = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (uint32_t)pAddrFlash + i*4, ((uint32_t *)pBuf)[i]); |
|
188 |
} |
|
189 |
|
|
190 |
for (int i = nSize/4 * 2 ; i < nSize/2 ; i++) |
|
191 |
{ |
|
192 |
res = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)pAddrFlash + i*2, ((uint16_t *)pBuf)[i]); |
|
193 |
} |
|
194 |
*/ |
|
195 |
res = HAL_FLASH_Lock(); |
|
196 |
|
|
197 |
return res; |
|
198 |
} |
|
199 |
|
|
200 |
int ReadFactoryData(void * pDatabuf, int nByteCount) |
|
201 |
{ |
|
202 |
memcpy(pDatabuf,(stFactoryData *)FACTORY_DATA_BASE,nByteCount); |
|
203 |
return 0; |
|
204 |
} |
|
205 |
int WriteFactoryData(void * pDataBuf, int nByteCount) |
|
206 |
{ |
|
207 |
stFactoryData * p1 = (stFactoryData*) pDataBuf; |
|
208 |
stFactoryData * p2 = (stFactoryData *)FACTORY_DATA_BASE; |
|
209 |
p1->Seq1= p2->Seq1+1; |
|
210 |
|
|
211 |
EraseAndWriteToFlashMem(pDataBuf, (stFactoryData *)FACTORY_DATA_BASE,nByteCount); |
|
212 |
return 0; |
|
213 |
} |
|
214 |
|
|
215 |
int ReadProgram(int nProgByteAddr, void *pBuf, int nByteSize, int nBank) |
|
216 |
{ |
|
217 |
if (nBank==0) { |
|
218 |
ReadFlashMem(pBuf, (void *)(STORE_PRG_BASE+nProgByteAddr), nByteSize); |
|
219 |
}else if (nBank ==1) { |
|
220 |
ReadFlashMem(pBuf, (void *)(ALT_PRG_BASE+nProgByteAddr), nByteSize); |
|
221 |
}else if (KMRunStat.nBinProgBank==0) { |
|
222 |
ReadFlashMem(pBuf, (void *)(STORE_PRG_BASE+nProgByteAddr), nByteSize); |
|
223 |
} else { |
|
224 |
ReadFlashMem(pBuf, (void *)(ALT_PRG_BASE+nProgByteAddr), nByteSize); |
|
225 |
} |
|
226 |
return 0; |
|
227 |
} |
|
228 |
int WriteProgram(int nProgAddress, void * pBuf, int nByteSize, int nBank) |
|
229 |
{ |
|
230 |
// Program Save Address;// |
|
231 |
// Program 2 Save Address; // |
|
232 |
void * progByteAddr; |
|
233 |
if (nBank == 0) { |
|
234 |
progByteAddr=(void *)(STORE_PRG_BASE+nProgAddress); |
|
235 |
}else if (nBank==1) { |
|
236 |
progByteAddr=(void *)(ALT_PRG_BASE+nProgAddress); |
|
237 |
} else if (KMRunStat.nBinProgBank==0) { |
|
238 |
progByteAddr=(void *)(ALT_PRG_BASE+nProgAddress); |
|
239 |
}else{ |
|
240 |
progByteAddr=(void *)(STORE_PRG_BASE+nProgAddress); |
|
241 |
} |
|
242 |
if (nProgAddress ==0) { |
|
243 |
EraseAndWriteToFlashMem(pBuf, progByteAddr, nByteSize); |
|
244 |
}else{ |
|
245 |
WriteToFlashMemNoErase(pBuf, progByteAddr, nByteSize); |
|
246 |
} |
|
247 |
return 0; |
|
248 |
} |
|
249 |
|
|
250 |
int LoadDefaultSysCfg(pStoredKMSysCfg theStoredKMSysCfg) |
|
251 |
{ |
|
252 |
memcpy(theStoredKMSysCfg,&KMDefaultSysCfg,sizeof(stKMSysCfg)); |
|
253 |
return 0; |
|
254 |
} |
|
255 |
int ReadSysCfgFromFlash(pStoredKMSysCfg theStoredKMSysCfg) |
|
256 |
{ |
|
257 |
pStoredKMSysCfg pStoreKMSysCfg = (pStoredKMSysCfg)(STORE_SYSREG_BASE); |
|
258 |
// find latest Store Cfg |
|
259 |
int nIndex=-1; |
|
260 |
int nMaxSeq=-1; |
|
261 |
for (int i=0;i<8;i++) |
|
262 |
{ |
|
263 |
if (pStoreKMSysCfg->Sign1 == START_SIGN && pStoreKMSysCfg->EndSign1 == END_SIGN) |
|
264 |
{ |
|
265 |
if (pStoreKMSysCfg->Seq1 > nMaxSeq) |
|
266 |
{ |
|
267 |
nIndex=i;nMaxSeq=pStoreKMSysCfg->Seq1; |
|
268 |
} |
|
269 |
} |
|
270 |
} |
|
271 |
if (nIndex>=0 && nIndex <8) |
|
272 |
{ |
|
273 |
ReadFlashMem(theStoredKMSysCfg,(void *)(&pStoreKMSysCfg[nIndex]),sizeof(stStoredKMSysCfg)); |
|
274 |
}else { |
|
275 |
LoadDefaultSysCfg(theStoredKMSysCfg); |
|
276 |
} |
|
277 |
//memcpy(theKMSysCfg,(void* )STORECFGBASE,sizeof(KMSysCfg)); |
|
278 |
return 0; |
|
279 |
} |
|
280 |
|
|
281 |
int WriteSysCfgToFlash(pStoredKMSysCfg theStoredKMSysCfg) |
|
282 |
{ |
|
283 |
theStoredKMSysCfg->Seq1++; |
|
284 |
// theKMSysCfg->cfgvar16++; |
|
285 |
// find the next empty space to write |
|
286 |
int nIndex=-1; |
|
287 |
int s2=128; |
|
288 |
for (int i=0;i<8;i++) |
|
289 |
{ |
|
290 |
int skip=0; |
|
291 |
unsigned char * nAddr2=(unsigned char *)(STORE_SYSREG_BASE+i*s2); |
|
292 |
for (int j=0;j<s2;j++) |
|
293 |
{ |
|
294 |
if ((nAddr2)[j] != 0xff) {skip =1;break;} |
|
295 |
} |
|
296 |
if (skip==1) {continue;} |
|
297 |
nIndex=i; |
|
298 |
break; |
|
299 |
} |
|
300 |
if (nIndex >=0 && nIndex <8) { |
|
301 |
WriteToFlashMemNoErase(theStoredKMSysCfg,(void *)(STORE_SYSREG_BASE + nIndex*s2),sizeof(theStoredKMSysCfg)); |
|
302 |
} |
|
303 |
else { |
|
304 |
EraseAndWriteToFlashMem(theStoredKMSysCfg,(void *)STORE_SYSREG_BASE,sizeof(theStoredKMSysCfg)); |
|
305 |
} |
|
306 |
return 0; |
|
307 |
} |
|
308 |
|
|
309 |
int is_pow_of_2(uint32_t x) { |
|
310 |
return !(x & (x-1)); |
|
311 |
} |
|
312 |
|
|
313 |
uint32_t next_pow_of_2(uint32_t x) |
|
314 |
{ |
|
315 |
if ( is_pow_of_2(x) ) |
|
316 |
return x; |
|
317 |
x |= x>>1; |
|
318 |
x |= x>>2; |
|
319 |
x |= x>>4; |
|
320 |
x |= x>>8; |
|
321 |
x |= x>>16; |
|
322 |
return x+1; |
|
323 |
} |
|
324 |
|
|
325 |
//uint8_t * pFlash1; |
|
326 |
/* |
|
327 |
stStoreCfg * GetCurStoreCfgAddr(void ) |
|
328 |
{ |
|
329 |
int s = sizeof(stStoreCfg); |
|
330 |
int s2=next_pow_of_2(s); |
|
331 |
stStoreCfg * p1; |
|
332 |
int nMaxSN=0; |
|
333 |
int nMaxId=0; |
|
334 |
for (int i=0; s2*i < STORECFGPAGESIZE ; i++) |
|
335 |
{ |
|
336 |
p1= (stStoreCfg *)(STORECFGBASE + s2 * i ); |
|
337 |
if (p1->Sign1 != START_SIGN) continue; |
|
338 |
if (p1->EndSign1 != END_SIGN) continue; |
|
339 |
|
|
340 |
if (p1->Seq1 >= nMaxSN) {nMaxSN = p1->Seq1; nMaxId = i;} |
|
341 |
} |
|
342 |
// nMaxId=nMaxId+1; |
|
343 |
return (stStoreCfg *)(STORECFGBASE + s2 * nMaxId); |
|
344 |
} |
|
345 |
|
|
346 |
stStoreCfg * GetNextStoreCfgAddr(stStoreCfg * CurCfg ) |
|
347 |
{ |
|
348 |
int s = sizeof(stStoreCfg); |
|
349 |
int s2=next_pow_of_2(s); |
|
350 |
uint32_t nAddr1 = (uint32_t) CurCfg; |
|
351 |
uint32_t nAddr2 = nAddr1 + s2; |
|
352 |
for (int i=1;i<33;i++) |
|
353 |
{ |
|
354 |
int skip=0; |
|
355 |
nAddr2 = nAddr1 + s2*i; |
|
356 |
if ((nAddr2 + s) > STORECFGBASE + STORECFGPAGESIZE) |
|
357 |
{ |
|
358 |
nAddr2=STORECFGBASE; break; |
|
359 |
} |
|
360 |
for (int j=0;j<s2;j++) |
|
361 |
{ |
|
362 |
if (((unsigned char *)nAddr2)[j] != 0xff) |
|
363 |
{skip =1;} |
|
364 |
} |
|
365 |
if (skip==1) {continue;} |
|
366 |
break; |
|
367 |
} |
|
368 |
stStoreCfg * p1 = (stStoreCfg *)nAddr2; |
|
369 |
return p1; |
|
370 |
} |
|
371 |
|
|
372 |
|
|
373 |
int SaveStoreCfg(stStoreCfg * CurCfg) |
|
374 |
{ |
|
375 |
return 0; |
|
376 |
} |
|
377 |
*/ |
|
378 |
// stStoreCfg Cfg2; |
|
379 |
|
|
380 |
int LoadFlashDatas() |
|
381 |
{ |
|
382 |
for (int i=0;i<16;i++) |
|
383 |
{ |
|
384 |
// FlashDatas[i]=((uint16_t *)pConfigFlashBase)[i]; |
|
385 |
} |
|
386 |
return 0; |
|
387 |
} |
|
388 |
/* |
|
389 |
int LoadAndUpdateStoreCfg() |
|
390 |
{ |
|
391 |
stStoreCfg * pFCfg = (stStoreCfg *) GetCurStoreCfgAddr(); |
|
392 |
|
|
393 |
Cfg2.Sign1=START_SIGN; |
|
394 |
Cfg2.Seq1=pFCfg[0].Seq1+1; |
|
395 |
Cfg2.CRC1=0x7777; |
|
396 |
Cfg2.PowerCount=pFCfg[0].PowerCount+1; |
|
397 |
Cfg2.UpTime=pFCfg[0].UpTime+1; |
|
398 |
Cfg2.UserData1=pFCfg[0].UserData1; |
|
399 |
Cfg2.EndSign1=END_SIGN; |
|
400 |
stStoreCfg * pFCfg2 = GetNextStoreCfgAddr(pFCfg); |
|
401 |
|
|
402 |
|
|
403 |
HAL_StatusTypeDef res; |
|
404 |
if (pFCfg2 <= pFCfg) |
|
405 |
{ |
|
406 |
res = (HAL_StatusTypeDef)EraseAndWriteToFlashMem(&Cfg2,pFCfg2,sizeof(stStoreCfg)); |
|
407 |
|
|
408 |
}else |
|
409 |
{ |
|
410 |
res = (HAL_StatusTypeDef)WriteToFlashMemNoErase(&Cfg2,pFCfg2,sizeof(stStoreCfg)); |
|
411 |
} |
|
412 |
return res; |
|
413 |
} |
|
414 |
*/ |
|
415 |
int CheckSavedData(void * pStartAddr, int PageSize, int Pages, int DataSize) |
|
416 |
{ |
|
417 |
return 0; |
|
418 |
}; |
|
419 |
|
|
420 |
|
|
421 |
int nMaxRunStatIndex=-1; |
|
422 |
unsigned int nMaxRunStatSeq=0; |
|
423 |
int nNextRunStatSpace=0; |
|
424 |
int LoadDefaultRunStat(pRunStat theRunStat) |
|
425 |
{ |
|
426 |
return 0; |
|
427 |
} |
|
428 |
int LoadRunStat(pRunStat theRunStat) |
|
429 |
{ |
|
430 |
uchar * pRunStatStore = (uchar *)STORE_RUNSTAT_BASE; |
|
431 |
pRunStat pStoreRunStats = (pRunStat)pRunStatStore; |
|
432 |
// int s = sizeof(stRunStat); |
|
433 |
|
|
434 |
for (int i=0;i * sizeof(stRunStat) < (STORE_RUNSTAT_PAGESIZE * STORE_RUNSTAT_PAGES) ;i++) |
|
435 |
{ |
|
436 |
if (pStoreRunStats[i].Sign1 == START_SIGN ) |
|
437 |
{ |
|
438 |
if (pStoreRunStats[i].Seq1 > nMaxRunStatSeq) |
|
439 |
{ |
|
440 |
nMaxRunStatSeq = pStoreRunStats[i].Seq1; |
|
441 |
nMaxRunStatIndex=i; |
|
442 |
nNextRunStatSpace=i+1; |
|
443 |
} |
|
444 |
} |
|
445 |
} |
|
446 |
if (nMaxRunStatIndex>=0) // && nMaxRunStatIndex <8) |
|
447 |
{ |
|
448 |
ReadFlashMem(theRunStat,(void *)(pStoreRunStats+nMaxRunStatIndex),sizeof(stRunStat)); |
|
449 |
}else { |
|
450 |
LoadDefaultRunStat(theRunStat); |
|
451 |
} |
|
452 |
// find Next Space |
|
453 |
// if Same Page with MaxSeq Index, then not erase, skip and skip. |
|
454 |
// if next Page of MaxSeq Index, then earse if not empty; |
|
455 |
if ((nNextRunStatSpace + 1) * sizeof(stRunStat) > STORE_RUNSTAT_PAGESIZE * STORE_RUNSTAT_PAGES) { |
|
456 |
nNextRunStatSpace=0; |
|
457 |
} |
|
458 |
return 0; |
|
459 |
} |
|
460 |
|
|
461 |
int SaveRunStat(pRunStat theRunStat) |
|
462 |
{ |
|
463 |
nMaxRunStatSeq++; |
|
464 |
theRunStat->Sign1=START_SIGN; |
|
465 |
theRunStat->Seq1 = nMaxRunStatSeq; |
|
466 |
theRunStat->PowerCount=KMem.PwrOnCount; |
|
467 |
theRunStat->UpTime=KMem.TotalRunTime; |
|
468 |
theRunStat->CRC1=0x11; |
|
469 |
theRunStat->EndSign1=END_SIGN; |
|
470 |
|
|
471 |
//check empty |
|
472 |
unsigned char *pFlash = (unsigned char *)(STORE_RUNSTAT_BASE + nNextRunStatSpace*sizeof(stRunStat)); |
|
473 |
int Skip=0; |
|
474 |
for (int j=0;j<sizeof(stRunStat);j++) |
|
475 |
{ |
|
476 |
if (pFlash[j]!=0xff) {Skip =1 ; break;} |
|
477 |
} |
|
478 |
if (Skip ==0 ) |
|
479 |
{ |
|
480 |
WriteToFlashMemNoErase(theRunStat,(void *)(STORE_RUNSTAT_BASE + nNextRunStatSpace*sizeof(stRunStat)),sizeof(stRunStat)); |
|
481 |
}else |
|
482 |
{ |
|
483 |
EraseAndWriteToFlashMem(theRunStat,(void *)(STORE_RUNSTAT_BASE + nNextRunStatSpace*sizeof(stRunStat)),sizeof(stRunStat)); |
|
484 |
} |
|
485 |
nMaxRunStatIndex=nNextRunStatSpace; |
|
486 |
nNextRunStatSpace++; |
|
487 |
if ((nNextRunStatSpace+1) * sizeof(stRunStat) > STORE_RUNSTAT_PAGESIZE * STORE_RUNSTAT_PAGES) |
|
488 |
{ |
|
489 |
nNextRunStatSpace=0; |
|
490 |
} |
|
491 |
return 0; |
|
492 |
} |
|
493 |
|
|
494 |
|
|
495 |
int nEventCount=0; |
|
496 |
int nEventMinIndex; |
|
497 |
int nEventMaxIndex; |
|
498 |
unsigned int nEventMaxSeq=0; |
|
499 |
int nEventNextSpace; |
|
500 |
int nMaxCurTime=0; |
|
501 |
volatile int PowerDownEvent=0; |
|
502 |
volatile int OldPowerDownEvent=0; |
|
503 |
volatile int OldPowerDownEventTime=0; |
|
504 |
|
|
505 |
int CheckEventLog() |
|
506 |
{ |
|
507 |
unsigned int nMinEventSeq=999999999; |
|
508 |
uchar * pEventStore = (uchar *)STORE_LOG_BASE; |
|
509 |
pEventLog theEventLog = (pEventLog) pEventStore; |
|
510 |
// int s = sizeof(stEventLog); |
|
511 |
nEventCount=0; |
|
512 |
|
|
513 |
for (int i=0;i * sizeof(stEventLog) < (STORE_LOG_PAGESIZE * STORE_LOG_PAGES) ;i++) |
|
514 |
{ |
|
515 |
if (theEventLog[i].Sign1 == START_SIGN ) |
|
516 |
{ |
|
517 |
nEventCount++; |
|
518 |
if (theEventLog[i].Seq1 > nEventMaxSeq) |
|
519 |
{ |
|
520 |
nEventMaxSeq = theEventLog[i].Seq1; |
|
521 |
nEventMaxIndex=i; |
|
522 |
nMaxCurTime=theEventLog[i].nTime; |
|
523 |
nEventNextSpace=i+1; |
|
524 |
} |
|
525 |
if (theEventLog[i].Seq1 < nMinEventSeq) |
|
526 |
{ |
|
527 |
nMinEventSeq = theEventLog[i].Seq1; |
|
528 |
nEventMinIndex = i; |
|
529 |
} |
|
530 |
} |
|
531 |
} |
|
532 |
// find Next Space |
|
533 |
// if Same Page with MaxSeq Index, then not erase, skip and skip. |
|
534 |
// if next Page of MaxSeq Index, then earse if not empty; |
|
535 |
if ((nEventNextSpace + 1) * sizeof(stEventLog) > STORE_LOG_PAGESIZE * STORE_LOG_PAGES) { |
|
536 |
nEventNextSpace=0; |
|
537 |
} |
|
538 |
|
|
539 |
return nEventCount; |
|
540 |
} |
|
541 |
|
|
542 |
int AddEventLog(uint32_t nTime, USHORT nEvent, USHORT nParam1, UINT nParam2) |
|
543 |
{ |
|
544 |
nEventMaxSeq++; |
|
545 |
stEventLog thisEventLog={START_SIGN, nEventMaxSeq, nTime,nEvent,nParam1,nParam2}; |
|
546 |
//check empty |
|
547 |
unsigned char *pFlash = (unsigned char *)(STORE_LOG_BASE + nEventNextSpace*sizeof(stEventLog)); |
|
548 |
int Skip=0; |
|
549 |
for (int j=0;j<sizeof(stEventLog);j++) |
|
550 |
{ |
|
551 |
if (pFlash[j]!=0xff) {Skip =1 ; break;} |
|
552 |
} |
|
553 |
if (Skip ==0 ) |
|
554 |
{ |
|
555 |
WriteToFlashMemNoErase(&thisEventLog,(void *)(STORE_LOG_BASE + nEventNextSpace*sizeof(stEventLog)),sizeof(stEventLog)); |
|
556 |
}else |
|
557 |
{ |
|
558 |
EraseAndWriteToFlashMem(&thisEventLog,(void *)(STORE_LOG_BASE + nEventNextSpace*sizeof(stEventLog)),sizeof(stEventLog)); |
|
559 |
|
|
560 |
} |
|
561 |
nEventMaxIndex=nEventNextSpace; |
|
562 |
nEventNextSpace++; |
|
563 |
if ((nEventNextSpace+1) * sizeof(stEventLog) > STORE_LOG_PAGESIZE * STORE_LOG_PAGES) |
|
564 |
{ |
|
565 |
nEventNextSpace=0; |
|
566 |
} |
|
567 |
nEventCount++; |
|
568 |
KMem.nEventCount=nEventCount; |
|
569 |
return 0; |
|
570 |
} |
|
571 |
|
|
572 |
pEventLog GetEventLogAddr(int nIndex) |
|
573 |
{ |
|
574 |
int nEventIndex=nEventMinIndex + nIndex; |
|
575 |
|
|
576 |
if (nEventIndex * sizeof(stEventLog) >= (STORE_LOG_PAGESIZE * STORE_LOG_PAGES)) |
|
577 |
{ |
|
578 |
nEventIndex -= (STORE_LOG_PAGESIZE * STORE_LOG_PAGES)/sizeof(stEventLog); |
|
579 |
} |
|
580 |
unsigned char *pFlash = (unsigned char *)(STORE_LOG_BASE + nEventIndex*sizeof(stEventLog)); |
|
581 |
|
|
582 |
return (pEventLog)pFlash; |
|
583 |
} |
|
584 |
|
|
585 |
int ClearEventLog(void) |
|
586 |
{ |
|
587 |
EraseFlashMem((void *)STORE_LOG_BASE,STORE_LOG_PAGES); |
|
588 |
nEventMinIndex=0; |
|
589 |
nEventMaxIndex=0; |
|
590 |
nEventMaxSeq=0; |
|
591 |
nEventCount=0; |
|
592 |
nEventNextSpace=0; |
|
593 |
return 0; |
|
594 |
} |
|
595 |
int KMachineInit(void) |
|
596 |
{ |
|
597 |
// ClearEventLog(); |
|
598 |
CheckEventLog(); |
|
599 |
LoadRunStat(&KMRunStat); |
|
600 |
KMem.CurTimeSec=nMaxCurTime; |
|
601 |
KMem.TotalRunTime=KMRunStat.UpTime; |
|
602 |
KMRunStat.PowerCount++; |
|
603 |
KMem.PwrOnCount=KMRunStat.PowerCount; |
|
604 |
SaveRunStat(&KMRunStat); |
|
605 |
KMem.SDD[15]=nMaxRunStatIndex; |
|
606 |
KMem.SDD[16]=nMaxRunStatSeq; |
|
607 |
KMem.SDD[17]=nNextRunStatSpace; |
|
608 |
|
|
609 |
|
|
610 |
AddEventLog(KMem.CurTimeSec,EventTypePowerUp,1,12345); |
|
611 |
KMem.SDD[19]=nEventCount; |
|
612 |
KMem.SDD[20]=nEventMinIndex; |
|
613 |
KMem.SDD[21]=nEventMaxIndex; |
|
614 |
KMem.SDD[22]=nEventMaxSeq; |
|
615 |
KMem.SDD[23]=nEventNextSpace; |
|
616 |
|
|
617 |
return 0; |
|
618 |
} |
|
619 |
|
|
620 |
inline void SetAddrBit(unsigned short * pW, unsigned char bitAddr) |
|
621 |
{ |
|
622 |
(*pW)|=1<<(bitAddr&0xf); |
|
623 |
} |
|
624 |
|
|
625 |
inline void ResetBit(unsigned short * pW, unsigned char bitAddr) |
|
626 |
{ |
|
627 |
(*pW)&=~(1<<(bitAddr&0xf)); |
|
628 |
} |
|
629 |
|
|
630 |
static inline void SetBitValue(unsigned short * pW, unsigned char bitAddr, unsigned char Value) |
|
631 |
{ |
|
632 |
if (Value) { SetAddrBit(pW, bitAddr);} |
|
633 |
else {ResetBit(pW, bitAddr);} |
|
634 |
} |
|
635 |
|
|
636 |
static inline unsigned char GetBitValue(unsigned short W, unsigned char bitAddr) |
|
637 |
{ |
|
638 |
if (W&(1<<(bitAddr&0xf))) return 1; |
|
639 |
else return 0; |
|
640 |
} |
|
641 |
|
|
642 |
|
|
643 |
unsigned char GetCoilValue(unsigned char nCoilType, unsigned short nCoilAddr) |
|
644 |
{ |
|
645 |
unsigned char thisValue=0; |
|
646 |
unsigned short nWordAddr=(nCoilAddr&0xff0)>>4; |
|
647 |
unsigned char nBitAddr=nCoilAddr&0xf; |
|
648 |
switch(nCoilType) |
|
649 |
{ |
|
650 |
case KLCoilTypeX: |
|
651 |
if (nCoilAddr >= KLCoilXCount) return 0; |
|
652 |
thisValue = GetBitValue(KMem.WX[nWordAddr], nBitAddr); |
|
653 |
break; |
|
654 |
case KLCoilTypeY: |
|
655 |
if (nCoilAddr >= KLCoilYCount) return 0; |
|
656 |
thisValue = GetBitValue(KMem.WY[nWordAddr], nBitAddr); |
|
657 |
break; |
|
658 |
case KLCoilTypeR: |
|
659 |
if (nCoilAddr >= KLCoilRCount) return 0; |
|
660 |
thisValue = GetBitValue(KMem.WR[nWordAddr], nBitAddr); |
|
661 |
break; |
|
662 |
case KLCoilTypeLX: |
|
663 |
if (nCoilAddr >= KLCoilLXCount) return 0; |
|
664 |
thisValue = GetBitValue(KMem.WLX[nWordAddr], nBitAddr); |
|
665 |
break; |
|
666 |
case KLCoilTypeLY: |
|
667 |
if (nCoilAddr >= KLCoilLYCount) return 0; |
|
668 |
thisValue = GetBitValue(KMem.WLY[nWordAddr], nBitAddr); |
|
669 |
break; |
|
670 |
case KLCoilTypeT: |
|
671 |
if (nCoilAddr >= KLCoilTCount) return 0; |
|
672 |
thisValue = GetBitValue(KMem.WT[nWordAddr], nBitAddr); |
|
673 |
break; |
|
674 |
case KLCoilTypeC: |
|
675 |
if (nCoilAddr >= KLCoilCCount) return 0; |
|
676 |
thisValue = GetBitValue(KMem.WC[nWordAddr], nBitAddr); |
|
677 |
break; |
|
678 |
case KLCoilTypeLR: |
|
679 |
if (nCoilAddr >= KLCoilLRCount) return 0; |
|
680 |
thisValue = GetBitValue(KMem.WLR[nWordAddr], nBitAddr); |
|
681 |
break; |
|
682 |
case KLCoilTypeSR: |
|
683 |
if (nCoilAddr >= KLCoilSRCount) return 0; |
|
684 |
thisValue = GetBitValue(KMem.WSR[nWordAddr], nBitAddr); |
|
685 |
break; |
|
686 |
default: |
|
687 |
break; |
|
688 |
} |
|
689 |
return thisValue; |
|
690 |
} |
|
691 |
int SetCoilValue(unsigned char nCoilType, unsigned short nCoilAddr, unsigned char nCoilValue) |
|
692 |
{ |
|
693 |
unsigned short nWordAddr=(nCoilAddr&0xff0)>>4; |
|
694 |
unsigned char nBitAddr=nCoilAddr&0xf; |
|
695 |
switch(nCoilType) |
|
696 |
{ |
|
697 |
case KLCoilTypeX: |
|
698 |
if (nCoilAddr >= KLCoilXCount) return 0; |
|
699 |
SetBitValue(&KMem.WX[nWordAddr], nBitAddr, nCoilValue); |
|
700 |
break; |
|
701 |
case KLCoilTypeY: |
|
702 |
if (nCoilAddr >= KLCoilYCount) return 0; |
|
703 |
SetBitValue(&KMem.WY[nWordAddr], nBitAddr, nCoilValue); |
|
704 |
break; |
|
705 |
case KLCoilTypeR: |
|
706 |
if (nCoilAddr >= KLCoilRCount) return 0; |
|
707 |
SetBitValue(&KMem.WR[nWordAddr], nBitAddr, nCoilValue); |
|
708 |
break; |
|
709 |
case KLCoilTypeLX: |
|
710 |
if (nCoilAddr >= KLCoilLXCount) return 0; |
|
711 |
SetBitValue(&KMem.WLX[nWordAddr], nBitAddr, nCoilValue); |
|
712 |
break; |
|
713 |
case KLCoilTypeLY: |
|
714 |
if (nCoilAddr >= KLCoilLYCount) return 0; |
|
715 |
SetBitValue(&KMem.WLY[nWordAddr], nBitAddr, nCoilValue); |
|
716 |
break; |
|
717 |
case KLCoilTypeT: |
|
718 |
if (nCoilAddr >= KLCoilTCount) return 0; |
|
719 |
SetBitValue(&KMem.WT[nWordAddr], nBitAddr, nCoilValue); |
|
720 |
break; |
|
721 |
case KLCoilTypeC: |
|
722 |
if (nCoilAddr >= KLCoilCCount) return 0; |
|
723 |
SetBitValue(&KMem.WC[nWordAddr], nBitAddr, nCoilValue); |
|
724 |
break; |
|
725 |
case KLCoilTypeLR: |
|
726 |
if (nCoilAddr >= KLCoilLRCount) return 0; |
|
727 |
SetBitValue(&KMem.WLR[nWordAddr], nBitAddr, nCoilValue); |
|
728 |
break; |
|
729 |
case KLCoilTypeSR: |
|
730 |
if (nCoilAddr >= KLCoilSRCount) return 0; |
|
731 |
SetBitValue(&KMem.WSR[nWordAddr], nBitAddr, nCoilValue); |
|
732 |
break; |
|
733 |
default: |
|
734 |
break; |
|
735 |
} |
|
736 |
return 0; |
|
737 |
} |
|
738 |
|
|
739 |
int GetVarData(int nDataType, int nDataAddr) |
|
740 |
{ |
|
741 |
// TODO: ?????????. |
|
742 |
int thisValue = 0; |
|
743 |
|
|
744 |
switch (nDataType) |
|
745 |
{ |
|
746 |
case KLDataTypeDEC: |
|
747 |
case KLDataTypeHEX: |
|
748 |
thisValue = nDataAddr; |
|
749 |
break; |
|
750 |
case KLDataTypeWX: |
|
751 |
if (nDataAddr >= KLDataWXCount) return 0; |
|
752 |
thisValue = KMem.WX[nDataAddr]; |
|
753 |
break; |
|
754 |
case KLDataTypeWY: |
|
755 |
if (nDataAddr >= KLDataWYCount) return 0; |
|
756 |
thisValue = KMem.WY[nDataAddr]; |
|
757 |
break; |
|
758 |
case KLDataTypeWR: |
|
759 |
if (nDataAddr >= KLDataWRCount) return 0; |
|
760 |
thisValue = KMem.WR[nDataAddr]; |
|
761 |
break; |
|
762 |
case KLDataTypeWLX: |
|
763 |
if (nDataAddr >= KLDataWLCount) return 0; |
|
764 |
thisValue = KMem.WLX[nDataAddr]; |
|
765 |
break; |
|
766 |
case KLDataTypeWLY: |
|
767 |
if (nDataAddr >= KLDataWLCount) return 0; |
|
768 |
thisValue = KMem.WLY[nDataAddr]; |
|
769 |
break; |
|
770 |
case KLDataTypeDT: |
|
771 |
if (nDataAddr >= KLDataDTCount) return 0; |
|
772 |
thisValue = (signed short)KMem.DT[nDataAddr]; |
|
773 |
break; |
|
774 |
case KLDataTypeSDT: |
|
775 |
if (nDataAddr >= KLDataSDTCount) return 0; |
|
776 |
thisValue = KMem.SDT[nDataAddr]; |
|
777 |
break; |
|
778 |
case KLDataTypeWSR: |
|
779 |
if (nDataAddr >= KLCoilLRCount) return 0; |
|
780 |
thisValue = KMem.WSR[nDataAddr]; |
|
781 |
break; |
|
782 |
case KLDataTypeSV: |
|
783 |
if (nDataAddr >= KLDataSVCount) return 0; |
|
784 |
thisValue = KMem.SV[nDataAddr]; |
|
785 |
break; |
|
786 |
case KLDataTypeEV: |
|
787 |
if (nDataAddr >= KLDataEVCount) return 0; |
|
788 |
thisValue = KMem.EV[nDataAddr]; |
|
789 |
break; |
|
790 |
case KLDataTypeLD: |
|
791 |
if (nDataAddr >= KLDataLDCount) return 0; |
|
792 |
thisValue = KMem.DT[nDataAddr]; |
|
793 |
break; |
|
794 |
case KLDataSysCfg: |
|
795 |
if (nDataAddr >= KLCoilSRCount) return 0; |
|
796 |
thisValue = KMem.SDT[nDataAddr]; |
|
797 |
break; |
|
798 |
case KLDataTypeFlash: |
|
799 |
if (nDataAddr >= KLCoilSRCount) return 0; |
|
800 |
thisValue = KMem.SDT[nDataAddr]; |
|
801 |
break; |
|
802 |
case KLDataTypeTest: |
|
803 |
if (nDataAddr >= KLCoilSRCount) return 0; |
|
804 |
thisValue = KMem.SDT[nDataAddr]; |
|
805 |
break; |
|
806 |
} |
|
807 |
return thisValue; |
|
808 |
} |
|
809 |
|
|
810 |
|
|
811 |
int SetVarData(int nDataType, int nDataAddr, int nDataValue) |
|
812 |
{ |
|
813 |
// TODO: ?????????. |
|
814 |
switch (nDataType) |
|
815 |
{ |
|
816 |
// case KLDataTypeDEC: |
|
817 |
// case KLDataTypeHEX: |
|
818 |
// break; |
|
819 |
case KLDataTypeWX: |
|
820 |
if (nDataAddr >= KLDataWXCount) return 0; |
|
821 |
KMem.WX[nDataAddr] = nDataValue; |
|
822 |
break; |
|
823 |
case KLDataTypeWY: |
|
824 |
if (nDataAddr >= KLDataWYCount) return 0; |
|
825 |
KMem.WY[nDataAddr] = nDataValue; |
|
826 |
break; |
|
827 |
case KLDataTypeWR: |
|
828 |
if (nDataAddr >= KLDataWRCount) return 0; |
|
829 |
KMem.WR[nDataAddr] = nDataValue; |
|
830 |
break; |
|
831 |
case KLDataTypeWLX: |
|
832 |
if (nDataAddr >= KLDataWLCount) return 0; |
|
833 |
KMem.WLX[nDataAddr] = nDataValue; |
|
834 |
break; |
|
835 |
case KLDataTypeWLY: |
|
836 |
if (nDataAddr >= KLDataWLCount) return 0; |
|
837 |
KMem.WLY[nDataAddr] = nDataValue; |
|
838 |
break; |
|
839 |
case KLDataTypeDT: |
|
840 |
if (nDataAddr >= KLDataDTCount) return 0; |
|
841 |
KMem.DT[nDataAddr] = nDataValue; |
|
842 |
break; |
|
843 |
case KLDataTypeSDT: |
|
844 |
if (nDataAddr >= KLDataSDTCount) return 0; |
|
845 |
KMem.SDT[nDataAddr] = nDataValue; |
|
846 |
break; |
|
847 |
case KLDataTypeWSR: |
|
848 |
if (nDataAddr >= KLCoilLRCount) return 0; |
|
849 |
KMem.WSR[nDataAddr] = nDataValue; |
|
850 |
break; |
|
851 |
case KLDataTypeSV: |
|
852 |
if (nDataAddr >= KLDataSVCount) return 0; |
|
853 |
KMem.SV[nDataAddr] = nDataValue; |
|
854 |
break; |
|
855 |
case KLDataTypeEV: |
|
856 |
if (nDataAddr >= KLDataEVCount) return 0; |
|
857 |
KMem.EV[nDataAddr] = nDataValue; |
|
858 |
break; |
|
859 |
case KLDataTypeLD: |
|
860 |
if (nDataAddr >= KLDataLDCount) return 0; |
|
861 |
KMem.DT[nDataAddr] = nDataValue; |
|
862 |
break; |
|
863 |
case KLDataSysCfg: |
|
864 |
if (nDataAddr >= KLCoilSRCount) return 0; |
|
865 |
KMem.SDT[nDataAddr] = nDataValue; |
|
866 |
break; |
|
867 |
case KLDataTypeFlash: |
|
868 |
if (nDataAddr >= KLCoilSRCount) return 0; |
|
869 |
KMem.SDT[nDataAddr] = nDataValue; |
|
870 |
break; |
|
871 |
case KLDataTypeTest: |
|
872 |
if (nDataAddr >= KLCoilSRCount) return 0; |
|
873 |
KMem.SDT[nDataAddr] = nDataValue; |
|
874 |
break; |
|
875 |
} |
|
876 |
|
|
877 |
return 0; |
|
878 |
} |
|
879 |
|