/** ****************************************************************************** * @file : KMachine.c * @brief : KMachine program body ****************************************************************************** */ #include "KMachine.h" #include "string.h" #include "Globaldef.h" #include "stm32f0xx_hal.h" //#define OB_BASE ((uint32_t)0x1FFFF800U) /*!< FLASH Option Bytes base address */ //#define FLASHSIZE_BASE ((uint32_t)0x1FFFF7CCU) /*!< FLASH Size register base address */ //#define UID_BASE ((uint32_t)0x1FFFF7ACU) /*!< Unique device ID register base address */ stStoredKMSysCfg storedKMSysCfg ; stKMem KMem; stRunStat KMRunStat; //uint8_t * pFlash1 = (uint8_t *)(STORECFGBASE); //void * pConfigFlashBase = (uint8_t *)(STORECFGBASE); //uint16_t FlashDatas[16]; //uint32_t * pUID = (uint32_t *)(UID_BASE); const stKMInfoBlock KMInfoBlock = { (BOARD_TYPE<<8) + BOARD_VER, //nDeviceType BOARD_VER, //nDevieVer 0x0100, //ProgVer 0x0100, //KLinkVer 0x0100, //KBusVer // 0x0100, //KNetVer // 0x0100, //KWLVer 4, //nCapacity1 ?K 1, //nCapacity2 ?k DINPUT, //nDInput; DOUTPUT, //nDOutput 0, //nAInput 0, //nAOutput 0, //nHInput 0, //nHOutput 0, //nExt1; 0, //nExt2; 0, //nLogSize; 0, //nPorts; 0, //nManSize; 0, //nAbility; 6, //nSwitchBits; }; const char VersionStr[] __attribute__((at(FLASH_BASE + 0X1000))) //__attribute__((at(0X8001000))) = "3.00"; const stStoredKMSysCfg KMDefaultSysCfg /*__attribute__((at(STORECFGBASE)))*/ = { START_SIGN, 0x0000, CFG_VER, 0x0000, 0x0000, {0,0,0,0,0,0}, { { 1, 0, 2304, //Buadrate * 100; PortType_KLink, //PorttType 1, //ByteSize 0, //Parity 0, //StopBits 0, //EofChar 0, //SofChar }, { 1, 0, 2304, //Buadrate * 100; PortType_KBus, //PorttType 1, //ByteSize 0, //Parity 0, //StopBits 0, //EofChar 0, //SofChar } }, {{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}}, {{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}}, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, {0}, 0x0011, END_SIGN, }; const stKMSysCfg KMDefaultSysCfg2[7] /*__attribute__((at(STORECFGBASE+sizeof(stKMSysCfg))))*/; int ReadFlashMem(void * pBuf, void * pAddrFlash, int nByteSize) { // memcpy(pBuf,pAddrFlash,nSize); for (int i=0;iSign1 == START_SIGN && pStoreKMSysCfg->EndSign1 == END_SIGN) { if (pStoreKMSysCfg->Seq1 > nMaxSeq) { nIndex=i;nMaxSeq=pStoreKMSysCfg->Seq1; } } } if (nIndex>=0 && nIndex <8) { ReadFlashMem(theStoredKMSysCfg,(void *)(&pStoreKMSysCfg[nIndex]),sizeof(stStoredKMSysCfg)); }else { LoadDefaultSysCfg(theStoredKMSysCfg); } //memcpy(theKMSysCfg,(void* )STORECFGBASE,sizeof(KMSysCfg)); return 0; } int WriteSysCfgToFlash(pStoredKMSysCfg theStoredKMSysCfg) { theStoredKMSysCfg->Seq1++; // theKMSysCfg->cfgvar16++; // find the next empty space to write int nIndex=-1; int s2=128; for (int i=0;i<8;i++) { int skip=0; unsigned char * nAddr2=(unsigned char *)(STORE_SYSREG_BASE+i*s2); for (int j=0;j=0 && nIndex <8) { WriteToFlashMemNoErase(theStoredKMSysCfg,(void *)(STORE_SYSREG_BASE + nIndex*s2),sizeof(theStoredKMSysCfg)); } else { EraseAndWriteToFlashMem(theStoredKMSysCfg,(void *)STORE_SYSREG_BASE,sizeof(theStoredKMSysCfg)); } return 0; } int is_pow_of_2(uint32_t x) { return !(x & (x-1)); } uint32_t next_pow_of_2(uint32_t x) { if ( is_pow_of_2(x) ) return x; x |= x>>1; x |= x>>2; x |= x>>4; x |= x>>8; x |= x>>16; return x+1; } //uint8_t * pFlash1; /* stStoreCfg * GetCurStoreCfgAddr(void ) { int s = sizeof(stStoreCfg); int s2=next_pow_of_2(s); stStoreCfg * p1; int nMaxSN=0; int nMaxId=0; for (int i=0; s2*i < STORECFGPAGESIZE ; i++) { p1= (stStoreCfg *)(STORECFGBASE + s2 * i ); if (p1->Sign1 != START_SIGN) continue; if (p1->EndSign1 != END_SIGN) continue; if (p1->Seq1 >= nMaxSN) {nMaxSN = p1->Seq1; nMaxId = i;} } // nMaxId=nMaxId+1; return (stStoreCfg *)(STORECFGBASE + s2 * nMaxId); } stStoreCfg * GetNextStoreCfgAddr(stStoreCfg * CurCfg ) { int s = sizeof(stStoreCfg); int s2=next_pow_of_2(s); uint32_t nAddr1 = (uint32_t) CurCfg; uint32_t nAddr2 = nAddr1 + s2; for (int i=1;i<33;i++) { int skip=0; nAddr2 = nAddr1 + s2*i; if ((nAddr2 + s) > STORECFGBASE + STORECFGPAGESIZE) { nAddr2=STORECFGBASE; break; } for (int j=0;j nMaxRunStatSeq) { nMaxRunStatSeq = pStoreRunStats[i].Seq1; nMaxRunStatIndex=i; nNextRunStatSpace=i+1; } } } if (nMaxRunStatIndex>=0) // && nMaxRunStatIndex <8) { ReadFlashMem(theRunStat,(void *)(pStoreRunStats+nMaxRunStatIndex),sizeof(stRunStat)); }else { LoadDefaultRunStat(theRunStat); } // find Next Space // if Same Page with MaxSeq Index, then not erase, skip and skip. // if next Page of MaxSeq Index, then earse if not empty; if ((nNextRunStatSpace + 1) * sizeof(stRunStat) > STORE_RUNSTAT_PAGESIZE * STORE_RUNSTAT_PAGES) { nNextRunStatSpace=0; } return 0; } int SaveRunStat(pRunStat theRunStat) { nMaxRunStatSeq++; theRunStat->Sign1=START_SIGN; theRunStat->Seq1 = nMaxRunStatSeq; theRunStat->PowerCount=KMem.PwrOnCount; theRunStat->UpTime=KMem.TotalRunTime; theRunStat->CRC1=0x11; theRunStat->EndSign1=END_SIGN; //check empty unsigned char *pFlash = (unsigned char *)(STORE_RUNSTAT_BASE + nNextRunStatSpace*sizeof(stRunStat)); int Skip=0; for (int j=0;j STORE_RUNSTAT_PAGESIZE * STORE_RUNSTAT_PAGES) { nNextRunStatSpace=0; } return 0; } int nEventCount=0; int nEventMinIndex; int nEventMaxIndex; unsigned int nEventMaxSeq=0; int nEventNextSpace; int nMaxCurTime=0; volatile int PowerDownEvent=0; volatile int OldPowerDownEvent=0; volatile int OldPowerDownEventTime=0; int CheckEventLog() { unsigned int nMinEventSeq=999999999; uchar * pEventStore = (uchar *)STORE_LOG_BASE; pEventLog theEventLog = (pEventLog) pEventStore; // int s = sizeof(stEventLog); nEventCount=0; for (int i=0;i * sizeof(stEventLog) < (STORE_LOG_PAGESIZE * STORE_LOG_PAGES) ;i++) { if (theEventLog[i].Sign1 == START_SIGN ) { nEventCount++; if (theEventLog[i].Seq1 > nEventMaxSeq) { nEventMaxSeq = theEventLog[i].Seq1; nEventMaxIndex=i; nMaxCurTime=theEventLog[i].nTime; nEventNextSpace=i+1; } if (theEventLog[i].Seq1 < nMinEventSeq) { nMinEventSeq = theEventLog[i].Seq1; nEventMinIndex = i; } } } // find Next Space // if Same Page with MaxSeq Index, then not erase, skip and skip. // if next Page of MaxSeq Index, then earse if not empty; if ((nEventNextSpace + 1) * sizeof(stEventLog) > STORE_LOG_PAGESIZE * STORE_LOG_PAGES) { nEventNextSpace=0; } return nEventCount; } int AddEventLog(uint32_t nTime, USHORT nEvent, USHORT nParam1, UINT nParam2) { nEventMaxSeq++; stEventLog thisEventLog={START_SIGN, nEventMaxSeq, nTime,nEvent,nParam1,nParam2}; //check empty unsigned char *pFlash = (unsigned char *)(STORE_LOG_BASE + nEventNextSpace*sizeof(stEventLog)); int Skip=0; for (int j=0;j STORE_LOG_PAGESIZE * STORE_LOG_PAGES) { nEventNextSpace=0; } nEventCount++; KMem.nEventCount=nEventCount; return 0; } pEventLog GetEventLogAddr(int nIndex) { int nEventIndex=nEventMinIndex + nIndex; if (nEventIndex * sizeof(stEventLog) >= (STORE_LOG_PAGESIZE * STORE_LOG_PAGES)) { nEventIndex -= (STORE_LOG_PAGESIZE * STORE_LOG_PAGES)/sizeof(stEventLog); } unsigned char *pFlash = (unsigned char *)(STORE_LOG_BASE + nEventIndex*sizeof(stEventLog)); return (pEventLog)pFlash; } int ClearEventLog(void) { EraseFlashMem((void *)STORE_LOG_BASE,STORE_LOG_PAGES); nEventMinIndex=0; nEventMaxIndex=0; nEventMaxSeq=0; nEventCount=0; nEventNextSpace=0; return 0; } int KMachineInit(void) { // ClearEventLog(); CheckEventLog(); LoadRunStat(&KMRunStat); KMem.CurTimeSec=nMaxCurTime; KMem.TotalRunTime=KMRunStat.UpTime; KMRunStat.PowerCount++; KMem.PwrOnCount=KMRunStat.PowerCount; SaveRunStat(&KMRunStat); KMem.SDD[15]=nMaxRunStatIndex; KMem.SDD[16]=nMaxRunStatSeq; KMem.SDD[17]=nNextRunStatSpace; AddEventLog(KMem.CurTimeSec,EventTypePowerUp,1,12345); KMem.SDD[19]=nEventCount; KMem.SDD[20]=nEventMinIndex; KMem.SDD[21]=nEventMaxIndex; KMem.SDD[22]=nEventMaxSeq; KMem.SDD[23]=nEventNextSpace; return 0; } inline void SetAddrBit(unsigned short * pW, unsigned char bitAddr) { (*pW)|=1<<(bitAddr&0xf); } inline void ResetBit(unsigned short * pW, unsigned char bitAddr) { (*pW)&=~(1<<(bitAddr&0xf)); } static inline void SetBitValue(unsigned short * pW, unsigned char bitAddr, unsigned char Value) { if (Value) { SetAddrBit(pW, bitAddr);} else {ResetBit(pW, bitAddr);} } static inline unsigned char GetBitValue(unsigned short W, unsigned char bitAddr) { if (W&(1<<(bitAddr&0xf))) return 1; else return 0; } unsigned char GetCoilValue(unsigned char nCoilType, unsigned short nCoilAddr) { unsigned char thisValue=0; unsigned short nWordAddr=(nCoilAddr&0xff0)>>4; unsigned char nBitAddr=nCoilAddr&0xf; switch(nCoilType) { case KLCoilTypeX: if (nCoilAddr >= KLCoilXCount) return 0; thisValue = GetBitValue(KMem.WX[nWordAddr], nBitAddr); break; case KLCoilTypeY: if (nCoilAddr >= KLCoilYCount) return 0; thisValue = GetBitValue(KMem.WY[nWordAddr], nBitAddr); break; case KLCoilTypeR: if (nCoilAddr >= KLCoilRCount) return 0; thisValue = GetBitValue(KMem.WR[nWordAddr], nBitAddr); break; case KLCoilTypeLX: if (nCoilAddr >= KLCoilLXCount) return 0; thisValue = GetBitValue(KMem.WLX[nWordAddr], nBitAddr); break; case KLCoilTypeLY: if (nCoilAddr >= KLCoilLYCount) return 0; thisValue = GetBitValue(KMem.WLY[nWordAddr], nBitAddr); break; case KLCoilTypeT: if (nCoilAddr >= KLCoilTCount) return 0; thisValue = GetBitValue(KMem.WT[nWordAddr], nBitAddr); break; case KLCoilTypeC: if (nCoilAddr >= KLCoilCCount) return 0; thisValue = GetBitValue(KMem.WC[nWordAddr], nBitAddr); break; case KLCoilTypeLR: if (nCoilAddr >= KLCoilLRCount) return 0; thisValue = GetBitValue(KMem.WLR[nWordAddr], nBitAddr); break; case KLCoilTypeSR: if (nCoilAddr >= KLCoilSRCount) return 0; thisValue = GetBitValue(KMem.WSR[nWordAddr], nBitAddr); break; default: break; } return thisValue; } int SetCoilValue(unsigned char nCoilType, unsigned short nCoilAddr, unsigned char nCoilValue) { unsigned short nWordAddr=(nCoilAddr&0xff0)>>4; unsigned char nBitAddr=nCoilAddr&0xf; switch(nCoilType) { case KLCoilTypeX: if (nCoilAddr >= KLCoilXCount) return 0; SetBitValue(&KMem.WX[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeY: if (nCoilAddr >= KLCoilYCount) return 0; SetBitValue(&KMem.WY[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeR: if (nCoilAddr >= KLCoilRCount) return 0; SetBitValue(&KMem.WR[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeLX: if (nCoilAddr >= KLCoilLXCount) return 0; SetBitValue(&KMem.WLX[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeLY: if (nCoilAddr >= KLCoilLYCount) return 0; SetBitValue(&KMem.WLY[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeT: if (nCoilAddr >= KLCoilTCount) return 0; SetBitValue(&KMem.WT[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeC: if (nCoilAddr >= KLCoilCCount) return 0; SetBitValue(&KMem.WC[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeLR: if (nCoilAddr >= KLCoilLRCount) return 0; SetBitValue(&KMem.WLR[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeSR: if (nCoilAddr >= KLCoilSRCount) return 0; SetBitValue(&KMem.WSR[nWordAddr], nBitAddr, nCoilValue); break; default: break; } return 0; } int GetVarData(int nDataType, int nDataAddr) { // TODO: ?????????. int thisValue = 0; switch (nDataType) { case KLDataTypeDEC: case KLDataTypeHEX: thisValue = nDataAddr; break; case KLDataTypeWX: if (nDataAddr >= KLDataWXCount) return 0; thisValue = KMem.WX[nDataAddr]; break; case KLDataTypeWY: if (nDataAddr >= KLDataWYCount) return 0; thisValue = KMem.WY[nDataAddr]; break; case KLDataTypeWR: if (nDataAddr >= KLDataWRCount) return 0; thisValue = KMem.WR[nDataAddr]; break; case KLDataTypeWLX: if (nDataAddr >= KLDataWLCount) return 0; thisValue = KMem.WLX[nDataAddr]; break; case KLDataTypeWLY: if (nDataAddr >= KLDataWLCount) return 0; thisValue = KMem.WLY[nDataAddr]; break; case KLDataTypeDT: if (nDataAddr >= KLDataDTCount) return 0; thisValue = (signed short)KMem.DT[nDataAddr]; break; case KLDataTypeSDT: if (nDataAddr >= KLDataSDTCount) return 0; thisValue = KMem.SDT[nDataAddr]; break; case KLDataTypeWSR: if (nDataAddr >= KLCoilLRCount) return 0; thisValue = KMem.WSR[nDataAddr]; break; case KLDataTypeSV: if (nDataAddr >= KLDataSVCount) return 0; thisValue = KMem.SV[nDataAddr]; break; case KLDataTypeEV: if (nDataAddr >= KLDataEVCount) return 0; thisValue = KMem.EV[nDataAddr]; break; case KLDataTypeLD: if (nDataAddr >= KLDataLDCount) return 0; thisValue = KMem.DT[nDataAddr]; break; case KLDataSysCfg: if (nDataAddr >= KLCoilSRCount) return 0; thisValue = KMem.SDT[nDataAddr]; break; case KLDataTypeFlash: if (nDataAddr >= KLCoilSRCount) return 0; thisValue = KMem.SDT[nDataAddr]; break; case KLDataTypeTest: if (nDataAddr >= KLCoilSRCount) return 0; thisValue = KMem.SDT[nDataAddr]; break; } return thisValue; } int SetVarData(int nDataType, int nDataAddr, int nDataValue) { // TODO: ?????????. switch (nDataType) { // case KLDataTypeDEC: // case KLDataTypeHEX: // break; case KLDataTypeWX: if (nDataAddr >= KLDataWXCount) return 0; KMem.WX[nDataAddr] = nDataValue; break; case KLDataTypeWY: if (nDataAddr >= KLDataWYCount) return 0; KMem.WY[nDataAddr] = nDataValue; break; case KLDataTypeWR: if (nDataAddr >= KLDataWRCount) return 0; KMem.WR[nDataAddr] = nDataValue; break; case KLDataTypeWLX: if (nDataAddr >= KLDataWLCount) return 0; KMem.WLX[nDataAddr] = nDataValue; break; case KLDataTypeWLY: if (nDataAddr >= KLDataWLCount) return 0; KMem.WLY[nDataAddr] = nDataValue; break; case KLDataTypeDT: if (nDataAddr >= KLDataDTCount) return 0; KMem.DT[nDataAddr] = nDataValue; break; case KLDataTypeSDT: if (nDataAddr >= KLDataSDTCount) return 0; KMem.SDT[nDataAddr] = nDataValue; break; case KLDataTypeWSR: if (nDataAddr >= KLCoilLRCount) return 0; KMem.WSR[nDataAddr] = nDataValue; break; case KLDataTypeSV: if (nDataAddr >= KLDataSVCount) return 0; KMem.SV[nDataAddr] = nDataValue; break; case KLDataTypeEV: if (nDataAddr >= KLDataEVCount) return 0; KMem.EV[nDataAddr] = nDataValue; break; case KLDataTypeLD: if (nDataAddr >= KLDataLDCount) return 0; KMem.DT[nDataAddr] = nDataValue; break; case KLDataSysCfg: if (nDataAddr >= KLCoilSRCount) return 0; KMem.SDT[nDataAddr] = nDataValue; break; case KLDataTypeFlash: if (nDataAddr >= KLCoilSRCount) return 0; KMem.SDT[nDataAddr] = nDataValue; break; case KLDataTypeTest: if (nDataAddr >= KLCoilSRCount) return 0; KMem.SDT[nDataAddr] = nDataValue; break; } return 0; }