| | |
| | | */ |
| | | |
| | | #include "KMachine.h" |
| | | #include "KBus.h" |
| | | #include "string.h" |
| | | #include "Globaldef.h" |
| | | #include "stm32f0xx_hal.h" |
| | | #include "stm32f0xx.h" |
| | | #include "stm32f0xx_ll_flash.h" |
| | | #include "PLCFunctions.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 */ |
| | | |
| | | //#define FLASH_BASE |
| | | //#define FLASH_PAGE_SIZE 0x00000400U |
| | | //#define FLASH_BANK1_END ((uint32_t)0x0800FFFFU) /*!< FLASH END address of bank1 */ |
| | | #define ApplicationAddress 0x08001000 //应用程序首地址定义 |
| | | #if defined(STM32F030x8) |
| | | #define NEW_APP_INFOBLOCK_ADDR 0x08008000 // 存储的新应用程序信息块的地址 |
| | | #define NEW_APP_ADDR ((uint32_t)0x08009000U) // 存储的新应用程序的地址 |
| | | #endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F051x8 || STM32F042x6 || STM32F048xx || STM32F058xx || STM32F070x6 */ |
| | | |
| | | #if defined(STM32F030xC) |
| | | #define NEW_APP_INFOBLOCK_ADDR 0x08020000 // 存储的新应用程序信息块的地址 |
| | | #define NEW_APP_ADDR ((uint32_t)0x08021000U) // 存储的新应用程序的地址 |
| | | #endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx || STM32F030xC */ |
| | | |
| | | |
| | | stStoredKMSysCfg storedKMSysCfg ; |
| | | stKMem KMem; |
| | | stRunStat KMRunStat; |
| | | |
| | | |
| | | extern void SetErrLed(uchar bOn); |
| | | |
| | | //uint8_t * pFlash1 = (uint8_t *)(STORECFGBASE); |
| | | |
| | |
| | | //uint16_t FlashDatas[16]; |
| | | |
| | | //uint32_t * pUID = (uint32_t *)(UID_BASE); |
| | | const stKMInfoBlock KMInfoBlock = |
| | | { |
| | | // sizeof(stKMInfoBlock), |
| | | (BOARD_TYPE<<8) + BOARD_VER, //nDeviceType BOARD_VER, //nDevieVer |
| | | 0x0107, //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 + 0X2000))) //__attribute__((at(0X8001000))) |
| | | = "3.00"; |
| | |
| | | CFG_VER, |
| | | 0x0000, //workmode |
| | | 0x0000, //switchfunc |
| | | 0x0000, //pad1; |
| | | 4, //nCfgBlockCount; |
| | | { //comportparam[2] |
| | | { |
| | | PortType_KLink, //PorttType |
| | | 1, //Station |
| | | 2304, //Buadrate = * 100; |
| | | 0, //ByteSize |
| | | 1152, //Buadrate = * 100; |
| | | 1, //ByteSize |
| | | 0, //Parity |
| | | 0, //StopBits |
| | | 0, //endType |
| | | 1, //endType |
| | | 0, //EofChar |
| | | 0, //SofChar |
| | | 0, //endtime |
| | | 9, //endtime |
| | | 0, //recvbuf |
| | | 0, //bufsize |
| | | }, |
| | |
| | | PortType_KBus, //PorttType |
| | | 0, //Station |
| | | 2304, //Buadrate = * 100; |
| | | 0, //ByteSize |
| | | 1, //ByteSize |
| | | 0, //Parity |
| | | 0, //StopBits |
| | | 0, //endType |
| | | 1, //endType |
| | | 0, //EofChar |
| | | 0, //SofChar |
| | | 0, //endtime |
| | | 1, //endtime |
| | | 0, //recvbuf |
| | | 0, //bufsize |
| | | } |
| | |
| | | 0x0030, |
| | | 0x0040, |
| | | 0x0050, |
| | | 0x0060 |
| | | 0x0060, |
| | | 0x0070, |
| | | 0x0080, |
| | | }, |
| | | 0x0003, //padding s |
| | | 0x0004, |
| | | 0x0005, |
| | | 0x0006, |
| | | 0x0007, |
| | | 0x0008, |
| | | 0,0,0,0, |
| | | { |
| | | {0,sizeof(stKMSysCfg)}, |
| | | {1,100}, |
| | | {2,100}, |
| | | {3,32}, |
| | | {4,32}, |
| | | }, |
| | | 0x0008, //padding s |
| | | 0x0009, |
| | | 0x000a, |
| | | 0x000b, |
| | | 0x000c, |
| | | }, |
| | | 0x0011, //CRC16 |
| | | END_SIGN, |
| | | }; |
| | | |
| | | int nEventCount=0; |
| | | int nEventMinIndex; |
| | | int nEventMaxIndex; |
| | | unsigned int nEventMaxSeq=0; |
| | | int nEventNextSpace; |
| | | int nMaxCurTime=0; |
| | | volatile int PowerState = 0; |
| | | |
| | | volatile int PowerDownEvent=0; |
| | | volatile int OldPowerDownEvent=0; |
| | | volatile int OldPowerDownEventTime=0; |
| | | int nMaxRunStatIndex=-1; |
| | | unsigned int nMaxRunStatSeq=0; |
| | | int nNextRunStatSpace=0; |
| | | |
| | | int KMRegisterPort(ushort nType,stPortDef * theParam) |
| | | { |
| | | int curPortId = KMem.nTotalPorts; |
| | | |
| | | KMem.pPorts[curPortId] = theParam; |
| | | |
| | | KMem.nTotalPorts++; |
| | | return curPortId; |
| | | } |
| | | |
| | | int KMPortReqFunc(int nPortIndex,int nReqId, int nParam1, int nParam2, void ** pData, unsigned short * nlen1) |
| | | { |
| | | if (KMem.pPorts[nPortIndex]->ReqCommFunc) |
| | | return KMem.pPorts[nPortIndex]->ReqCommFunc(KMem.pPorts[nPortIndex]->pInstance, nReqId, nParam1, nParam2, pData, nlen1); |
| | | else return -1; |
| | | } |
| | | |
| | | int KMRunService(int nSvrId, int nParam1, int nParam2, void **pData, unsigned short *nlen1) |
| | | { |
| | | int res; |
| | | switch(nSvrId) |
| | | { |
| | | case ReqNone: |
| | | break; |
| | | |
| | | case ReqInit: |
| | | break; |
| | | case ReqReset: |
| | | __set_PRIMASK(1); //关闭全局中断 |
| | | NVIC_SystemReset(); |
| | | break; |
| | | case ReqStop: |
| | | break; |
| | | case ReqRun: |
| | | break; |
| | | case ReqBlinkLED: |
| | | break; |
| | | case ReqStartDiag: |
| | | break; |
| | | case ReqStopDiag: |
| | | break; |
| | | case ReqUpdateFirm: |
| | | |
| | | res = WriteNewApp(nParam1,*pData,*nlen1); |
| | | |
| | | break; |
| | | case ReqUpdateFirmInfo: |
| | | res = WriteNewAppInfo(nParam1,*pData,*nlen1); |
| | | break; |
| | | |
| | | default: |
| | | res = -1; |
| | | break; |
| | | |
| | | } |
| | | return res; |
| | | } |
| | | |
| | | int KMachineInit(void) |
| | | { |
| | | // ClearEventLog(); |
| | | KMem.LastScanTime=0; |
| | | KMem.ScanTimeuS=0; |
| | | KMem.MinScanTimeuS=99999; |
| | | KMem.MaxScanTimeuS=0; |
| | | |
| | | // KMem.SDD[14]=(unsigned int)&KMStoreSysCfg; |
| | | // KMem.SDD[15]=(unsigned int)&KMStoreSysCfg1; |
| | | KMem.SDD[12]=((uint32_t *)UID_BASE)[0]; |
| | | // KMem.SDD[13]=((uint32_t *)UID_BASE)[1]; |
| | | // KMem.SDD[14]=((uint32_t *)UID_BASE)[2]; |
| | | KMem.SDD[13]=PendSvCount; |
| | | KMem.SDD[14]=RCC->CSR; |
| | | // KMem.SDD[15]=*(uint32_t *)FLASHSIZE_BASE; |
| | | // KMem.SDD[16]=(unsigned int)&KMSysCfg; |
| | | |
| | | KMem.nTotalPorts = 0; |
| | | 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; |
| | | } |
| | | |
| | | int KMachineLoopProc(void) |
| | | { |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | |
| | | //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;i<nByteSize/4;i++) |
| | | { |
| | | ((uint32_t *)pBuf)[i] = ((uint32_t *)pAddrFlash)[i]; |
| | | } |
| | | for (int i=nByteSize/4*2;i<nByteSize/2;i++) |
| | | { |
| | | ((uint16_t *)pBuf)[i] = ((uint16_t *)pAddrFlash)[i]; |
| | | } |
| | | memcpy(pBuf,pAddrFlash,nByteSize); |
| | | // for (int i=0;i<nByteSize/4;i++) |
| | | // { |
| | | // ((uint32_t *)pBuf)[i] = ((uint32_t *)pAddrFlash)[i]; |
| | | // } |
| | | // for (int i=nByteSize/4*2;i<nByteSize/2;i++) |
| | | // { |
| | | // ((uint16_t *)pBuf)[i] = ((uint16_t *)pAddrFlash)[i]; |
| | | // } |
| | | |
| | | return nByteSize; |
| | | } |
| | | |
| | | int EraseFlashMem(void * pAddrFlash, unsigned int Pages) |
| | | { |
| | | HAL_StatusTypeDef res; |
| | | res = HAL_FLASH_Unlock(); |
| | | uint32_t ErrNo; |
| | | FLASH_EraseInitTypeDef erase1; |
| | | erase1.NbPages=Pages; |
| | | erase1.PageAddress=(unsigned int)pAddrFlash; |
| | | erase1.TypeErase=FLASH_TYPEERASE_PAGES; |
| | | res = HAL_FLASHEx_Erase(&erase1,&ErrNo); |
| | | res = HAL_FLASH_Lock(); |
| | | ErrorStatus res; |
| | | res = LL_Flash_Unlock(); |
| | | // uint32_t ErrNo; |
| | | res = LL_Flash_PageErase(pAddrFlash,Pages); |
| | | LL_FLASH_Lock(FLASH); |
| | | return res; |
| | | } |
| | | |
| | | int WriteToFlashMemNoErase(void * pBuf, void * pAddrFlash, unsigned int nByteSize) |
| | | { |
| | | HAL_StatusTypeDef res; |
| | | res = HAL_FLASH_Unlock(); |
| | | /* |
| | | for (int i=0;i<nSize/2;i++) |
| | | { |
| | | res = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)pAddrFlash + i*2, ((uint16_t *)pBuf)[i]); |
| | | } |
| | | */ |
| | | ErrorStatus res; |
| | | SetErrLed(1); |
| | | res = LL_Flash_Unlock(); |
| | | // __disable_irq(); |
| | | ///* |
| | | for (int i=0;i<nByteSize/4;i++) |
| | | for (int i=0;i<(nByteSize+1)/2;i++) |
| | | { |
| | | res = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (uint32_t)pAddrFlash + i*4, ((uint32_t *)pBuf)[i]); |
| | | unsigned short value = ((uint8_t *)pBuf)[i*2] + (((uint8_t *)pBuf)[i*2 +1] << 8); |
| | | res = LL_FLASH_Program(ProgaraType_DATA16, (uint32_t)pAddrFlash + i*2, value); |
| | | if (res == ERROR) break; |
| | | } |
| | | |
| | | for (int i = nByteSize/4 * 2 ; i < nByteSize/2 ; i++) |
| | | { |
| | | res = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)pAddrFlash + i*2, ((uint16_t *)pBuf)[i]); |
| | | } |
| | | //*/ |
| | | res = HAL_FLASH_Lock(); |
| | | |
| | | return res; |
| | | // */ |
| | | // __enable_irq(); |
| | | LL_FLASH_Lock(FLASH); |
| | | if (res == ERROR) return 1; |
| | | return 0; |
| | | } |
| | | |
| | | int EraseAndWriteToFlashMem(void * pBuf, void * pAddrFlash, unsigned int nByteSize) |
| | | { |
| | | |
| | | HAL_StatusTypeDef res; |
| | | res = HAL_FLASH_Unlock(); |
| | | uint32_t ErrNo; |
| | | FLASH_EraseInitTypeDef erase1; |
| | | erase1.NbPages=(nByteSize-1) / FLASH_PAGESIZE + 1;; |
| | | erase1.PageAddress=(unsigned int)pAddrFlash; |
| | | erase1.TypeErase=FLASH_TYPEERASE_PAGES; |
| | | res = HAL_FLASHEx_Erase(&erase1,&ErrNo); |
| | | |
| | | for (int i=0;i<nByteSize/2;i++) |
| | | SetErrLed(1); |
| | | ErrorStatus res; |
| | | res = LL_Flash_Unlock(); |
| | | // __disable_irq(); |
| | | int NbPages = (nByteSize-1) / FLASH_PAGE_SIZE + 1; |
| | | // FLASH_EraseInitTypeDef erase1; |
| | | // erase1.NbPages=(nByteSize-1) / FLASH_PAGE_SIZE + 1;; |
| | | // erase1.PageAddress=(unsigned int)pAddrFlash; |
| | | // erase1.TypeErase=FLASH_TYPEERASE_PAGES; |
| | | res = LL_Flash_PageErase(pAddrFlash,NbPages); |
| | | for (int i=0;i<(nByteSize+1)/2;i++) |
| | | { |
| | | res = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)pAddrFlash + i*2, ((uint16_t *)pBuf)[i]); |
| | | unsigned short value = ((uint8_t *)pBuf)[i*2] + (((uint8_t *)pBuf)[i*2 +1] << 8); |
| | | res = LL_FLASH_Program(ProgaraType_DATA16, (uint32_t)pAddrFlash + i*2, value); |
| | | if (res == ERROR) break; |
| | | } |
| | | /* |
| | | for (int i=0;i<nSize/4;i++) |
| | | { |
| | | res = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (uint32_t)pAddrFlash + i*4, ((uint32_t *)pBuf)[i]); |
| | | } |
| | | |
| | | // __enable_irq(); |
| | | LL_FLASH_Lock(FLASH); |
| | | if (res == ERROR) return 1; |
| | | return 0; |
| | | } |
| | | |
| | | /* 烧录Flash,并自动擦除,页起始和跨页时自动擦除 页面中部分不擦除 */ |
| | | int WriteToFlashAutoErase(void * pBuf, void * pAddrFlash, unsigned int nByteSize) |
| | | { |
| | | SetErrLed(1); |
| | | ErrorStatus res; |
| | | res = LL_Flash_Unlock(); |
| | | // __disable_irq(); |
| | | |
| | | for (int i = nSize/4 * 2 ; i < nSize/2 ; i++) |
| | | { |
| | | res = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)pAddrFlash + i*2, ((uint16_t *)pBuf)[i]); |
| | | } |
| | | */ |
| | | res = HAL_FLASH_Lock(); |
| | | int StartPage = (int)pAddrFlash / FLASH_PAGE_SIZE; |
| | | int EndPage = ((int)pAddrFlash + nByteSize) / FLASH_PAGE_SIZE; |
| | | int StartOffset = (int)pAddrFlash & (FLASH_PAGE_SIZE-1); |
| | | |
| | | return res; |
| | | int NbPages = EndPage -StartPage + 1; |
| | | |
| | | if (StartOffset == 0) { // 从最开始 , 全部擦除,然后再存储. |
| | | res = LL_Flash_PageErase(pAddrFlash,NbPages); |
| | | for (int i=0;i<(nByteSize+1)/2;i++) |
| | | { |
| | | unsigned short value = ((uint8_t *)pBuf)[i*2] + (((uint8_t *)pBuf)[i*2 +1] << 8); |
| | | res = LL_FLASH_Program(ProgaraType_DATA16, (uint32_t)pAddrFlash + i*2, value); |
| | | if (res == ERROR) break; |
| | | } |
| | | }else if (NbPages > 1){ // 跨页存储 |
| | | // 先前面的部分 |
| | | int i; |
| | | for (i=0;i<(nByteSize+1)/2 && (((int)pAddrFlash + i*2) &(FLASH_PAGE_SIZE -1))!=0 ;i++) |
| | | { |
| | | unsigned short value = ((uint8_t *)pBuf)[i*2] + (((uint8_t *)pBuf)[i*2 +1] << 8); |
| | | res = LL_FLASH_Program(ProgaraType_DATA16, (uint32_t)pAddrFlash + i*2, value); |
| | | if (res == ERROR) break; |
| | | } |
| | | // 擦除后面的部分. |
| | | res = LL_Flash_PageErase((void *)((int)pAddrFlash + i*2),NbPages - 1); |
| | | // 继续存储 |
| | | for ( ;i<(nByteSize+1)/2;i++) |
| | | { |
| | | unsigned short value = ((uint8_t *)pBuf)[i*2] + (((uint8_t *)pBuf)[i*2 +1] << 8); |
| | | res = LL_FLASH_Program(ProgaraType_DATA16, (uint32_t)pAddrFlash + i*2, value); |
| | | if (res == ERROR) break; |
| | | } |
| | | }else { |
| | | // 正常写入,不需要擦除 |
| | | for (int i=0;i<(nByteSize+1)/2;i++) |
| | | { |
| | | unsigned short value = ((uint8_t *)pBuf)[i*2] + (((uint8_t *)pBuf)[i*2 +1] << 8); |
| | | res = LL_FLASH_Program(ProgaraType_DATA16, (uint32_t)pAddrFlash + i*2, value); |
| | | if (res == ERROR) break; |
| | | } |
| | | } |
| | | // __enable_irq(); |
| | | LL_FLASH_Lock(FLASH); |
| | | if (res == ERROR) return 1; |
| | | return 0; |
| | | } |
| | | |
| | | int ReadFactoryData(void * pDatabuf, int nByteCount) |
| | |
| | | EraseAndWriteToFlashMem(pDataBuf, (stFactoryData *)FACTORY_DATA_BASE,nByteCount); |
| | | return 0; |
| | | } |
| | | |
| | | int ReadProgram(int nProgByteAddr, void *pBuf, int nByteSize, int nBank) |
| | | #if (ENABLE_PLC) |
| | | int ReadPLCProgram(int nBank, int nProgByteAddr, void *pBuf, int nByteSize) |
| | | { |
| | | stStoredBinProgs * pStoredProg; |
| | | if (nBank==0) { |
| | | ReadFlashMem(pBuf, (void *)(STORE_PRG_BASE+nProgByteAddr), nByteSize); |
| | | pStoredProg = (void *)(STORE_PRG_BASE); |
| | | }else if (nBank ==1) { |
| | | ReadFlashMem(pBuf, (void *)(ALT_PRG_BASE+nProgByteAddr), nByteSize); |
| | | }else if (KMRunStat.nBinProgBank==0) { |
| | | ReadFlashMem(pBuf, (void *)(STORE_PRG_BASE+nProgByteAddr), nByteSize); |
| | | pStoredProg = (void *)(ALT_PRG_BASE); |
| | | }else if (storedKMSysCfg.theKMSysCfg.nProgBank==0) { |
| | | pStoredProg = (void *)(STORE_PRG_BASE); |
| | | } else { |
| | | ReadFlashMem(pBuf, (void *)(ALT_PRG_BASE+nProgByteAddr), nByteSize); |
| | | pStoredProg = (void *)(ALT_PRG_BASE); |
| | | } |
| | | void * progByteAddr; |
| | | progByteAddr =(unsigned char *)&pStoredProg->BinInstrcns + nProgByteAddr; |
| | | |
| | | ReadFlashMem(pBuf, (void *)(progByteAddr), nByteSize); |
| | | return 0; |
| | | } |
| | | int WriteProgram(int nProgAddress, void * pBuf, int nByteSize, int nBank) |
| | | |
| | | int StartPLCProgram(int nBank, int nByteSize, int nCRC) |
| | | { |
| | | void * progHdrAddr; |
| | | int nRes = 0; |
| | | if (nBank == 0) { |
| | | progHdrAddr=(void *)(STORE_PRG_BASE); |
| | | }else if (nBank==1) { |
| | | progHdrAddr=(void *)(ALT_PRG_BASE); |
| | | } else if (storedKMSysCfg.theKMSysCfg.nProgBank==0) { |
| | | progHdrAddr=(void *)(ALT_PRG_BASE); |
| | | }else{ |
| | | progHdrAddr=(void *)(STORE_PRG_BASE); |
| | | } |
| | | |
| | | stStoredHdr theHdr; |
| | | theHdr.nBlockSign = 0xAA55; |
| | | theHdr.nBlockType = 0; |
| | | theHdr.nSeq = 1; |
| | | theHdr.nSize = nByteSize; |
| | | theHdr.nCRC2 = nCRC; |
| | | |
| | | WriteToFlashAutoErase(&theHdr,(void *)progHdrAddr,sizeof(stStoredHdr)); |
| | | |
| | | return nRes; |
| | | } |
| | | int WritePLCProgram(int nBank, int nProgAddress, void * pBuf, int nByteSize) |
| | | { |
| | | // Program Save Address;// |
| | | // Program 2 Save Address; // |
| | | void * progByteAddr; |
| | | stStoredBinProgs * pStoredProg; |
| | | |
| | | if (nBank == 0) { |
| | | progByteAddr=(void *)(STORE_PRG_BASE+nProgAddress); |
| | | pStoredProg=(stStoredBinProgs *)(STORE_PRG_BASE); |
| | | }else if (nBank==1) { |
| | | progByteAddr=(void *)(ALT_PRG_BASE+nProgAddress); |
| | | } else if (KMRunStat.nBinProgBank==0) { |
| | | progByteAddr=(void *)(ALT_PRG_BASE+nProgAddress); |
| | | pStoredProg=(stStoredBinProgs *)(ALT_PRG_BASE); |
| | | } else if (storedKMSysCfg.theKMSysCfg.nProgBank==0) { |
| | | pStoredProg=(stStoredBinProgs *)(ALT_PRG_BASE); |
| | | }else{ |
| | | progByteAddr=(void *)(STORE_PRG_BASE+nProgAddress); |
| | | pStoredProg=(stStoredBinProgs *)(STORE_PRG_BASE); |
| | | } |
| | | if ( (nProgAddress & (STORE_PRG_PAGESIZE - 1)) ==0) { |
| | | EraseAndWriteToFlashMem(pBuf, progByteAddr, nByteSize); |
| | | }else{ |
| | | WriteToFlashMemNoErase(pBuf, progByteAddr, nByteSize); |
| | | } |
| | | void * progByteAddr; |
| | | progByteAddr =(unsigned char *)&pStoredProg->BinInstrcns + nProgAddress; |
| | | WriteToFlashAutoErase(pBuf,progByteAddr,nByteSize); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int FinishiPLCProgram(int nBank, int nProgSteps,int nCRC ) |
| | | { |
| | | int nRes = 0; |
| | | |
| | | if (storedKMSysCfg.theKMSysCfg.nProgBank == 0 ) { |
| | | storedKMSysCfg.theKMSysCfg.nProgBank = 1; |
| | | }else { |
| | | storedKMSysCfg.theKMSysCfg.nProgBank = 0; |
| | | } |
| | | storedKMSysCfg.theKMSysCfg.nProgSize = nProgSteps; |
| | | |
| | | WriteSysCfgToFlash(&storedKMSysCfg); |
| | | |
| | | KMRunStat.nBinProgSize=nProgSteps; |
| | | KMRunStat.nBinProgBank=storedKMSysCfg.theKMSysCfg.nProgBank; |
| | | |
| | | SaveRunStat(&KMRunStat); |
| | | |
| | | return nRes; |
| | | } |
| | | int ReadPLCAnno(int nBank, int nProgByteAddr, void *pBuf, int nByteSize) |
| | | { |
| | | stStoredBinProgs * pStoredProg; |
| | | if (nBank==0) { |
| | | pStoredProg = (void *)(STORE_PRG_BASE); |
| | | }else if (nBank ==1) { |
| | | pStoredProg = (void *)(ALT_PRG_BASE); |
| | | }else if (storedKMSysCfg.theKMSysCfg.nProgBank==0) { |
| | | pStoredProg = (void *)(STORE_PRG_BASE); |
| | | } else { |
| | | pStoredProg = (void *)(ALT_PRG_BASE); |
| | | } |
| | | void * progByteAddr; |
| | | progByteAddr =(unsigned char *)&pStoredProg->BinInstrcns + nProgByteAddr; |
| | | |
| | | ReadFlashMem(pBuf, (void *)(progByteAddr), nByteSize); |
| | | return 0; |
| | | } |
| | | |
| | | int StartPLCAnno(int nBank, int nByteSize, int nCRC) |
| | | { |
| | | void * StoredAnnoHdrAddr; |
| | | int nRes = 0; |
| | | |
| | | StoredAnnoHdrAddr=(void *)(STORE_PLC_ANNO_BASE); |
| | | |
| | | |
| | | stStoredHdr theHdr; |
| | | theHdr.nBlockSign = 0xAA55; |
| | | theHdr.nBlockType = 3; |
| | | theHdr.nSeq = 1; |
| | | theHdr.nSize = nByteSize; |
| | | theHdr.nCRC2 = nCRC; |
| | | |
| | | WriteToFlashAutoErase(&theHdr,(void *)StoredAnnoHdrAddr,sizeof(stStoredHdr)); |
| | | |
| | | return nRes; |
| | | } |
| | | int WritePLCAnno(int nBank, int nByteAddress, void * pBuf, int nByteSize) |
| | | { |
| | | // Program Save Address;// |
| | | // Program 2 Save Address; // |
| | | stStoredAnno * pStoredAnno; |
| | | pStoredAnno=(stStoredAnno *)(STORE_PLC_ANNO_BASE); |
| | | |
| | | void * nByteAddr; |
| | | nByteAddr =pStoredAnno->Annos + nByteAddress; |
| | | WriteToFlashAutoErase(pBuf,nByteAddr,nByteSize); |
| | | |
| | | return 0; |
| | | } |
| | | int FinishiPLCAnno(int nBank, int nByteSize,int nCRC ) |
| | | { |
| | | int nRes = 0; |
| | | |
| | | storedKMSysCfg.theKMSysCfg.nAnnoSize = nByteSize; |
| | | WriteSysCfgToFlash(&storedKMSysCfg); |
| | | /* |
| | | KMRunStat.nBinProgSize=nProgSteps; |
| | | KMRunStat.nBinProgBank=storedKMSysCfg.theKMSysCfg.nProgBank; |
| | | |
| | | SaveRunStat(&KMRunStat); |
| | | */ |
| | | return nRes; |
| | | } |
| | | |
| | | #endif //ENABLE_PLC |
| | | int LoadDefaultSysCfg(pStoredKMSysCfg theStoredKMSysCfg) |
| | | { |
| | | memcpy(theStoredKMSysCfg,&KMDefaultSysCfg,sizeof(stStoredKMSysCfg)); |
| | |
| | | return 0; |
| | | }; |
| | | |
| | | |
| | | int nMaxRunStatIndex=-1; |
| | | unsigned int nMaxRunStatSeq=0; |
| | | int nNextRunStatSpace=0; |
| | | int LoadDefaultRunStat(pRunStat theRunStat) |
| | | { |
| | | theRunStat->PowerCount=1; |
| | |
| | | // theRunStat->WorkMode=0; |
| | | // theRunStat->WorkMode2=0; |
| | | // theRunStat->nBinProgBank=0; |
| | | // theRunStat->nBinProgSize=0; |
| | | // theRunStat->nBinInstrcnSize=0; |
| | | return 0; |
| | | } |
| | | int LoadRunStat(pRunStat theRunStat) |
| | |
| | | pRunStat pStoreRunStats = (pRunStat)pRunStatStore; |
| | | // int s = sizeof(stRunStat); |
| | | |
| | | for (int i=0;i * sizeof(stRunStat) < (STORE_RUNSTAT_PAGESIZE * STORE_RUNSTAT_PAGES) ;i++) |
| | | for (int i=0;i * sizeof(stRunStat) < (FLASH_PAGE_SIZE * STORE_RUNSTAT_PAGES) ;i++) |
| | | { |
| | | if (pStoreRunStats[i].Sign1 == START_SIGN ) |
| | | { |
| | |
| | | // 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) { |
| | | if ((nNextRunStatSpace + 1) * sizeof(stRunStat) > FLASH_PAGE_SIZE * STORE_RUNSTAT_PAGES) { |
| | | nNextRunStatSpace=0; |
| | | } |
| | | return 0; |
| | |
| | | } |
| | | nMaxRunStatIndex=nNextRunStatSpace; |
| | | nNextRunStatSpace++; |
| | | if ((nNextRunStatSpace+1) * sizeof(stRunStat) > STORE_RUNSTAT_PAGESIZE * STORE_RUNSTAT_PAGES) |
| | | if ((nNextRunStatSpace+1) * sizeof(stRunStat) > FLASH_PAGE_SIZE * STORE_RUNSTAT_PAGES) |
| | | { |
| | | nNextRunStatSpace=0; |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | int WriteNewApp(int nProgByteOffset, void *pBuf, int nByteSize) |
| | | { |
| | | |
| | | int res = -1; |
| | | int FlashSize = *(ushort *)FLASHSIZE_BASE; |
| | | int NewAppAddress ; |
| | | if (FlashSize == 64) { |
| | | NewAppAddress = 0x08009000U; |
| | | }else if (FlashSize == 256) { |
| | | NewAppAddress = 0x08021000U; |
| | | } |
| | | if ((nProgByteOffset&(FLASH_PAGE_SIZE-1)) ==0){ |
| | | // EraseFlashMem((void *)(NewAppAddress + nProgByteAddr),1); |
| | | |
| | | res = EraseAndWriteToFlashMem(pBuf,(void *)(NewAppAddress + nProgByteOffset),nByteSize); |
| | | }else { |
| | | // if (nByteSize>64) return 0; |
| | | res = WriteToFlashMemNoErase(pBuf,(void *)(NewAppAddress + nProgByteOffset),nByteSize); |
| | | } |
| | | return res; |
| | | } |
| | | |
| | | int nEventCount=0; |
| | | int nEventMinIndex; |
| | | int nEventMaxIndex; |
| | | unsigned int nEventMaxSeq=0; |
| | | int nEventNextSpace; |
| | | int nMaxCurTime=0; |
| | | volatile int PowerState = 0; |
| | | |
| | | volatile int PowerDownEvent=0; |
| | | volatile int OldPowerDownEvent=0; |
| | | volatile int OldPowerDownEventTime=0; |
| | | int WriteNewAppInfo(int nProgByteAddr, void *pBuf, int nByteSize) |
| | | { |
| | | int FlashSize = *(ushort *)FLASHSIZE_BASE; |
| | | int NewAppInfoBlockAddress ; |
| | | if (FlashSize == 64) { |
| | | NewAppInfoBlockAddress = 0x08008000; |
| | | }else if (FlashSize == 256) { |
| | | NewAppInfoBlockAddress = 0x08020000; |
| | | } |
| | | |
| | | int res = EraseAndWriteToFlashMem(pBuf,(void *)(NewAppInfoBlockAddress + nProgByteAddr),nByteSize); |
| | | return res; |
| | | } |
| | | |
| | | int CheckEventLog() |
| | | { |
| | |
| | | // int s = sizeof(stEventLog); |
| | | nEventCount=0; |
| | | |
| | | for (int i=0;i * sizeof(stEventLog) < (STORE_LOG_PAGESIZE * STORE_LOG_PAGES) ;i++) |
| | | for (int i=0;i * sizeof(stEventLog) < (FLASH_PAGE_SIZE * STORE_LOG_PAGES) ;i++) |
| | | { |
| | | if (theEventLog[i].Sign1 == START_SIGN ) |
| | | { |
| | |
| | | // 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) { |
| | | if ((nEventNextSpace + 1) * sizeof(stEventLog) > FLASH_PAGE_SIZE * STORE_LOG_PAGES) { |
| | | nEventNextSpace=0; |
| | | } |
| | | |
| | |
| | | } |
| | | nEventMaxIndex=nEventNextSpace; |
| | | nEventNextSpace++; |
| | | if ((nEventNextSpace+1) * sizeof(stEventLog) > STORE_LOG_PAGESIZE * STORE_LOG_PAGES) |
| | | if ((nEventNextSpace+1) * sizeof(stEventLog) > FLASH_PAGE_SIZE * STORE_LOG_PAGES) |
| | | { |
| | | nEventNextSpace=0; |
| | | } |
| | |
| | | { |
| | | int nEventIndex=nEventMinIndex + nIndex; |
| | | |
| | | if (nEventIndex * sizeof(stEventLog) >= (STORE_LOG_PAGESIZE * STORE_LOG_PAGES)) |
| | | if (nEventIndex * sizeof(stEventLog) >= (FLASH_PAGE_SIZE * STORE_LOG_PAGES)) |
| | | { |
| | | nEventIndex -= (STORE_LOG_PAGESIZE * STORE_LOG_PAGES)/sizeof(stEventLog); |
| | | nEventIndex -= (FLASH_PAGE_SIZE * STORE_LOG_PAGES)/sizeof(stEventLog); |
| | | } |
| | | unsigned char *pFlash = (unsigned char *)(STORE_LOG_BASE + nEventIndex*sizeof(stEventLog)); |
| | | |
| | |
| | | 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 bitPos) |
| | | { |
| | | (*pW)|=1<<(bitPos&0xf); |
| | | } |
| | | |
| | | inline void SetAddrBit(unsigned short * pW, unsigned char bitAddr) |
| | | inline void ResetBit(unsigned short * pW, unsigned char bitPos) |
| | | { |
| | | (*pW)|=1<<(bitAddr&0xf); |
| | | (*pW)&=~(1<<(bitPos&0xf)); |
| | | } |
| | | |
| | | inline void ResetBit(unsigned short * pW, unsigned char bitAddr) |
| | | static inline void SetBitValue(unsigned short * pW, unsigned char bitPos, unsigned char Value) |
| | | { |
| | | (*pW)&=~(1<<(bitAddr&0xf)); |
| | | if (Value) { SetAddrBit(pW, bitPos);} |
| | | else {ResetBit(pW, bitPos);} |
| | | } |
| | | |
| | | static inline void SetBitValue(unsigned short * pW, unsigned char bitAddr, unsigned char Value) |
| | | static inline unsigned char GetBitValue(unsigned short W, unsigned char bitPos) |
| | | { |
| | | 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; |
| | | if (W&(1<<(bitPos&0xf))) return 1; |
| | | else return 0; |
| | | } |
| | | |
| | |
| | | { |
| | | unsigned char thisValue=0; |
| | | unsigned short nWordAddr=(nCoilAddr&0xff0)>>4; |
| | | unsigned char nBitAddr=nCoilAddr&0xf; |
| | | unsigned char nBitPos=nCoilAddr&0xf; |
| | | switch(nCoilType) |
| | | { |
| | | case KLCoilTypeX: |
| | | if (nCoilAddr >= KLCoilXCount) return 0; |
| | | thisValue = GetBitValue(KMem.WX[nWordAddr], nBitAddr); |
| | | thisValue = GetBitValue(KMem.WX[nWordAddr], nBitPos); |
| | | break; |
| | | case KLCoilTypeY: |
| | | if (nCoilAddr >= KLCoilYCount) return 0; |
| | | thisValue = GetBitValue(KMem.WY[nWordAddr], nBitAddr); |
| | | thisValue = GetBitValue(KMem.WY[nWordAddr], nBitPos); |
| | | break; |
| | | case KLCoilTypeR: |
| | | if (nCoilAddr >= KLCoilRCount) return 0; |
| | | thisValue = GetBitValue(KMem.WR[nWordAddr], nBitAddr); |
| | | |
| | | if (nCoilAddr < KLCoilRCount) { |
| | | thisValue = GetBitValue(KMem.WR[nWordAddr], nBitPos); |
| | | }else if (nCoilAddr > 9000) { |
| | | if (nCoilAddr == 9010) thisValue = 1; |
| | | if (nCoilAddr == 9011) thisValue = 0; |
| | | if (nCoilAddr == 9013) thisValue = GetBitValue(KMem.WSR[nWordAddr], 13); |
| | | } |
| | | // return thisValue; |
| | | break; |
| | | case KLCoilTypeLX: |
| | | if (nCoilAddr >= KLCoilLXCount) return 0; |
| | | thisValue = GetBitValue(KMem.WLX[nWordAddr], nBitAddr); |
| | | thisValue = GetBitValue(KMem.WLX[nWordAddr], nBitPos); |
| | | break; |
| | | case KLCoilTypeLY: |
| | | if (nCoilAddr >= KLCoilLYCount) return 0; |
| | | thisValue = GetBitValue(KMem.WLY[nWordAddr], nBitAddr); |
| | | thisValue = GetBitValue(KMem.WLY[nWordAddr], nBitPos); |
| | | break; |
| | | #if (ENABLE_PLC) |
| | | case KLCoilTypeT: |
| | | if (nCoilAddr >= KLCoilTCount) return 0; |
| | | thisValue = GetBitValue(KMem.WT[nWordAddr], nBitAddr); |
| | | thisValue = GetBitValue(PLCMem.WT[nWordAddr], nBitPos); |
| | | break; |
| | | case KLCoilTypeC: |
| | | if (nCoilAddr >= KLCoilCCount) return 0; |
| | | thisValue = GetBitValue(KMem.WC[nWordAddr], nBitAddr); |
| | | thisValue = GetBitValue(PLCMem.WC[nWordAddr], nBitPos); |
| | | break; |
| | | #endif |
| | | case KLCoilTypeLR: |
| | | if (nCoilAddr >= KLCoilLRCount) return 0; |
| | | thisValue = GetBitValue(KMem.WLR[nWordAddr], nBitAddr); |
| | | thisValue = GetBitValue(KMem.WLR[nWordAddr], nBitPos); |
| | | break; |
| | | case KLCoilTypeSR: |
| | | if (nCoilAddr >= KLCoilSRCount) return 0; |
| | | thisValue = GetBitValue(KMem.WSR[nWordAddr], nBitAddr); |
| | | thisValue = GetBitValue(KMem.WSR[nWordAddr], nBitPos); |
| | | break; |
| | | default: |
| | | break; |
| | |
| | | if (nCoilAddr >= KLCoilLYCount) return 0; |
| | | SetBitValue(&KMem.WLY[nWordAddr], nBitAddr, nCoilValue); |
| | | break; |
| | | #if (ENABLE_PLC) |
| | | case KLCoilTypeT: |
| | | if (nCoilAddr >= KLCoilTCount) return 0; |
| | | SetBitValue(&KMem.WT[nWordAddr], nBitAddr, nCoilValue); |
| | | SetBitValue(&PLCMem.WT[nWordAddr], nBitAddr, nCoilValue); |
| | | break; |
| | | case KLCoilTypeC: |
| | | if (nCoilAddr >= KLCoilCCount) return 0; |
| | | SetBitValue(&KMem.WC[nWordAddr], nBitAddr, nCoilValue); |
| | | SetBitValue(&PLCMem.WC[nWordAddr], nBitAddr, nCoilValue); |
| | | break; |
| | | #endif |
| | | case KLCoilTypeLR: |
| | | if (nCoilAddr >= KLCoilLRCount) return 0; |
| | | SetBitValue(&KMem.WLR[nWordAddr], nBitAddr, nCoilValue); |
| | |
| | | if (nDataAddr >= KLCoilLRCount) return 0; |
| | | thisValue = KMem.WSR[nDataAddr]; |
| | | break; |
| | | #if (ENABLE_PLC) |
| | | case KLDataTypeSV: |
| | | if (nDataAddr >= KLDataSVCount) return 0; |
| | | thisValue = KMem.SV[nDataAddr]; |
| | | thisValue = PLCMem.SV[nDataAddr]; |
| | | break; |
| | | case KLDataTypeEV: |
| | | if (nDataAddr >= KLDataEVCount) return 0; |
| | | thisValue = KMem.EV[nDataAddr]; |
| | | thisValue = PLCMem.EV[nDataAddr]; |
| | | break; |
| | | #endif |
| | | case KLDataTypeLD: |
| | | if (nDataAddr >= KLDataLDCount) return 0; |
| | | thisValue = KMem.DT[nDataAddr]; |
| | |
| | | if (nDataAddr >= KLCoilLRCount) return 0; |
| | | KMem.WSR[nDataAddr] = nDataValue; |
| | | break; |
| | | #if (ENABLE_PLC) |
| | | case KLDataTypeSV: |
| | | if (nDataAddr >= KLDataSVCount) return 0; |
| | | KMem.SV[nDataAddr] = nDataValue; |
| | | PLCMem.SV[nDataAddr] = nDataValue; |
| | | break; |
| | | case KLDataTypeEV: |
| | | if (nDataAddr >= KLDataEVCount) return 0; |
| | | KMem.EV[nDataAddr] = nDataValue; |
| | | PLCMem.EV[nDataAddr] = nDataValue; |
| | | break; |
| | | #endif |
| | | case KLDataTypeLD: |
| | | if (nDataAddr >= KLDataLDCount) return 0; |
| | | KMem.DT[nDataAddr] = nDataValue; |
| | |
| | | return 0; |
| | | } |
| | | |
| | | |
| | | int KMachineSvFunc (int nChn, int nSvType, int nParam,void * pBuf, int nLen1) |
| | | { |
| | | int iRet =0; |
| | | switch (nSvType){ |
| | | case ReqNone: |
| | | break; |
| | | case ReqInit: |
| | | break; |
| | | case ReqReset: |
| | | break; |
| | | case ReqStop: |
| | | break; |
| | | case ReqRun: |
| | | break; |
| | | case ReqBlinkLED: |
| | | KMRunStat.bLEDFlick=nParam; |
| | | break; |
| | | case ReqStartDiag: |
| | | break; |
| | | case ReqStopDiag: |
| | | break; |
| | | case ReqTransFirmware: |
| | | break; |
| | | case ReqTransCfg: |
| | | break; |
| | | case ReqTransProg: |
| | | break; |
| | | case ReqTransData: |
| | | break; |
| | | case ReqTransBlink: |
| | | break; |
| | | case ReqTransChild: |
| | | break; |
| | | case ReqTransInfo: |
| | | break; |
| | | case ReqTransOutBandData: |
| | | break; |
| | | case ReqRead1Bit: |
| | | break; |
| | | case ReqWrite1Bit: |
| | | break; |
| | | case ReqReadBits: |
| | | break; |
| | | case ReqWriteBits: |
| | | break; |
| | | case ReqReadData: |
| | | break; |
| | | case ReqWriteData: |
| | | break; |
| | | case ReqRemoteTran: |
| | | break; |
| | | |
| | | default: |
| | | iRet = -1; |
| | | break; |
| | | } |
| | | return iRet; |
| | | } |