/*----------------------------------------------------------------------------- * restore pwm output state * * restore block: * byte 0: 0b0000xxxx: on/off mask: 0 off, 1 on , bit0 .. channel 0 * bit1 .. channel 1 * bit2 .. channel 2 * bit3 .. channel 3 * byte 1: low byte channel 0 * byte 2: high byte channel 0 * byte 3: low byte channel 1 * byte 4: high byte channel 1 * byte 5: low byte channel 2 * byte 6: high byte channel 2 * byte 7: low byte channel 3 * byte 8: high byte channel 3 */ static void RestorePwm(void) { uint8_t *ptrToEeprom; uint8_t flags; uint8_t sizeRestore = 1 + NUM_PWM_CHANNEL * sizeof(uint16_t); uint8_t pwmLow; uint8_t pwmHigh; uint8_t pwmMask; uint8_t i; /* find the newest state */ for (ptrToEeprom = EEPROM_PWM_RESTORE_START; ptrToEeprom < (EEPROM_PWM_RESTORE_END - sizeRestore); ptrToEeprom += sizeRestore) { pwmMask = eeprom_read_byte(ptrToEeprom); if (pwmMask != 0xff) { break; } } if (ptrToEeprom > (EEPROM_PWM_RESTORE_END - sizeRestore)) { /* not found -> no restore * set pwm[] = 0xffff, state off */ for (i = 0; i < NUM_PWM_CHANNEL; i++) { PwmOn(i, false); PwmSet(i, 0xffff); } spNextPtrToEeprom = EEPROM_PWM_RESTORE_START; return; } spNextPtrToEeprom = ptrToEeprom + sizeRestore; if (spNextPtrToEeprom > (EEPROM_PWM_RESTORE_END - sizeRestore)) { spNextPtrToEeprom = EEPROM_PWM_RESTORE_START; } /* restore pwm output */ flags = DISABLE_INT; for (i = 0; i < NUM_PWM_CHANNEL; i++) { if (pwmMask & (1 << i)) { PwmOn(i, true); } pwmLow = eeprom_read_byte(ptrToEeprom + 1 + i * sizeof(uint16_t)); pwmHigh = eeprom_read_byte(ptrToEeprom + 1 + i * sizeof(uint16_t) + 1); PwmSet(i, pwmLow + 256 * pwmHigh); } /* delete */ eeprom_write_byte((uint8_t *)ptrToEeprom, 0xff); for (i = 0; i < NUM_PWM_CHANNEL; i++) { eeprom_write_byte(ptrToEeprom + 1 + i * 2, 0xff); eeprom_write_byte(ptrToEeprom + 1 + i * 2 + 1, 0xff); } RESTORE_INT(flags); }
/*----------------------------------------------------------------------------- * erase flash (application section) */ void FlashErase(void) { uint16_t pageWordAddr; int flags; flags = DISABLE_INT; for (pageWordAddr = 0; pageWordAddr < FIRMWARE_WORD_SIZE; pageWordAddr += PAGE_WORD_SIZE) { FlashPageErase(pageWordAddr); } RESTORE_INT(flags); }
/*----------------------------------------------------------------------------- * terminate flash programing */ bool FlashProgramTerminate(void) { int flags; if (sActualProgramingPage != INV_PAGE) { /* program current page */ flags = DISABLE_INT; FlashProgramPagePuffer(sActualProgramingPage); RESTORE_INT(flags); } return true; }
/*----------------------------------------------------------------------------- * Flashprogrammierung abschließen */ BOOL FlashProgramTerminate(void) { int flags; if (sActualProgramingPage != INV_PAGE) { /* nooch im Puffer befindliche Page programmieren */ flags = DISABLE_INT; FlashProgramPagePuffer(sActualProgramingPage); RESTORE_INT(flags); } return TRUE; }
/*----------------------------------------------------------------------------- * program flash */ bool FlashProgram(uint16_t wordAddr, uint16_t *pBuf, uint16_t numWords) { uint16_t page; uint16_t startPage; uint16_t endPage; uint16_t wordOffset; /* word offset within page */ uint8_t numPageWords; int flags; if ((wordAddr + numWords) > FIRMWARE_WORD_SIZE) { return false; } flags = DISABLE_INT; startPage = wordAddr & ~(PAGE_WORD_SIZE - 1); endPage = (wordAddr + numWords - 1) & ~(PAGE_WORD_SIZE - 1); wordOffset = wordAddr - startPage; if ((startPage != sActualProgramingPage) && (sActualProgramingPage != INV_PAGE)) { /* if continue in other page, program current buffer */ FlashProgramPagePuffer(sActualProgramingPage); } for (page = startPage; page <= endPage; page += PAGE_WORD_SIZE) { numPageWords = min(PAGE_WORD_SIZE - wordOffset, numWords); numWords -= numPageWords; FlashFillPagePuffer(wordOffset, pBuf, numPageWords); if ((wordOffset + numPageWords) == PAGE_WORD_SIZE) { /* buffer is full -> program page */ FlashProgramPagePuffer(page); sActualProgramingPage = INV_PAGE; /* next page not yet known */ } else { sActualProgramingPage = page; } pBuf += numPageWords; wordOffset = 0; } RESTORE_INT(flags); return true; }
/*----------------------------------------------------------------------------- * Flash programmieren */ BOOL FlashProgram(UINT16 wordAddr, UINT16 *pBuf, UINT16 numWords) { UINT16 page; UINT16 startPage; UINT16 endPage; UINT16 wordOffset; /* wordoffset innerhalb page */ UINT8 numPageWords; int flags; if ((wordAddr + numWords) > FIRMWARE_WORD_SIZE) { return FALSE; } flags = DISABLE_INT; startPage = wordAddr & ~(PAGE_WORD_SIZE -1); endPage = (wordAddr + numWords - 1) & ~(PAGE_WORD_SIZE -1); wordOffset = wordAddr - startPage; if ((startPage != sActualProgramingPage) && (sActualProgramingPage != INV_PAGE)) { /* zuvor teilgefüllte Page programmieren falls in anderer Page fortgesetzt wird */ FlashProgramPagePuffer(sActualProgramingPage); } for (page = startPage; page <= endPage; page += PAGE_WORD_SIZE) { numPageWords = min(PAGE_WORD_SIZE - wordOffset, numWords); numWords -= numPageWords; FlashFillPagePuffer(wordOffset, pBuf, numPageWords); if ((wordOffset + numPageWords) == PAGE_WORD_SIZE) { /* bei gefülltem Pagepuffer -> Pagepuffer programmieren */ FlashProgramPagePuffer(page); sActualProgramingPage = INV_PAGE; /* nächste Page ist beliebig */ } else { sActualProgramingPage = page; } pBuf += numPageWords; wordOffset = 0; } RESTORE_INT(flags); return TRUE; }
AB_IMEXPORTER_ACCOUNTINFO* AB_ImExporterAccountInfo_fromDb(GWEN_DB_NODE *db){ AB_IMEXPORTER_ACCOUNTINFO *iea; const char *s; GWEN_DB_NODE *dbT; iea=AB_ImExporterAccountInfo_new(); #define RESTORE_CHAR(NAME) \ s=GWEN_DB_GetCharValue(db, __STRING(NAME), 0, 0);\ if (s)\ iea->NAME=strdup(s); #define RESTORE_INT(NAME, DEFAULT) \ iea->NAME=GWEN_DB_GetIntValue(db, __STRING(NAME), 0, DEFAULT); RESTORE_CHAR(bankCode); RESTORE_CHAR(bankName); RESTORE_CHAR(accountNumber); RESTORE_CHAR(iban); RESTORE_CHAR(bic); RESTORE_CHAR(owner); RESTORE_CHAR(currency); RESTORE_CHAR(description); RESTORE_INT(accountType, AB_AccountType_Bank); RESTORE_INT(accountId, 0); #undef RESTORE_CHAR #undef RESTORE_INT dbT=GWEN_DB_GetGroup(db, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "statusList"); if (dbT) { dbT=GWEN_DB_FindFirstGroup(dbT, "status"); while(dbT) { AB_ACCOUNT_STATUS *ast; ast=AB_AccountStatus_fromDb(dbT); assert(ast); AB_AccountStatus_List_Add(ast, iea->accStatusList); dbT=GWEN_DB_FindNextGroup(dbT, "status"); } } dbT=GWEN_DB_GetGroup(db, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "transactionList"); if (dbT) { dbT=GWEN_DB_FindFirstGroup(dbT, "transaction"); while(dbT) { AB_TRANSACTION *t; t=AB_Transaction_fromDb(dbT); assert(t); AB_Transaction_List_Add(t, iea->transactions); dbT=GWEN_DB_FindNextGroup(dbT, "transaction"); } } dbT=GWEN_DB_GetGroup(db, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "standingOrderList"); if (dbT) { dbT=GWEN_DB_FindFirstGroup(dbT, "standingOrder"); while(dbT) { AB_TRANSACTION *t; t=AB_Transaction_fromDb(dbT); assert(t); AB_Transaction_List_Add(t, iea->standingOrders); dbT=GWEN_DB_FindNextGroup(dbT, "standingOrder"); } } dbT=GWEN_DB_GetGroup(db, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "transferList"); if (dbT) { dbT=GWEN_DB_FindFirstGroup(dbT, "transfer"); while(dbT) { AB_TRANSACTION *t; t=AB_Transaction_fromDb(dbT); assert(t); AB_Transaction_List_Add(t, iea->transfers); dbT=GWEN_DB_FindNextGroup(dbT, "transfer"); } } dbT=GWEN_DB_GetGroup(db, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "datedTransferList"); if (dbT) { dbT=GWEN_DB_FindFirstGroup(dbT, "datedTransfer"); while(dbT) { AB_TRANSACTION *t; t=AB_Transaction_fromDb(dbT); assert(t); AB_Transaction_List_Add(t, iea->datedTransfers); dbT=GWEN_DB_FindNextGroup(dbT, "datedTransfer"); } } dbT=GWEN_DB_GetGroup(db, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "notedTransactionList"); if (dbT) { dbT=GWEN_DB_FindFirstGroup(dbT, "notedTransaction"); while(dbT) { AB_TRANSACTION *t; t=AB_Transaction_fromDb(dbT); assert(t); AB_Transaction_List_Add(t, iea->notedTransactions); dbT=GWEN_DB_FindNextGroup(dbT, "notedTransaction"); } } return iea; }
/*----------------------------------------------------------------------------- * process received bus telegrams */ static void ProcessBus(void) { uint8_t ret; TBusMsgType msgType; uint8_t i; uint8_t *p; bool msgForMe = false; uint8_t flags; uint8_t old_osccal; static uint8_t sOsccal = 0; uint16_t startCnt; uint16_t stopCnt; uint16_t clocks; uint16_t diff; uint16_t seqLen; static int sCount = 0; static uint16_t sMinDiff = 0xffff; static uint8_t sMinOsccal = 0; uint8_t osccal_corr; ret = BusCheck(); if (ret == BUS_MSG_OK) { msgType = spRxBusMsg->type; switch (msgType) { case eBusDevReqReboot: case eBusDevReqInfo: case eBusDevReqSetAddr: case eBusDevReqEepromRead: case eBusDevReqEepromWrite: case eBusDevReqDoClockCalib: if (spRxBusMsg->msg.devBus.receiverAddr == MY_ADDR) { msgForMe = true; } break; default: break; } if (msgForMe == false) { return; } switch (msgType) { case eBusDevReqReboot: /* reset controller with watchdog */ /* set watchdog timeout to shortest value (14 ms) */ cli(); wdt_enable(WDTO_15MS); /* wait for reset */ while (1); break; case eBusDevReqInfo: sTxBusMsg.type = eBusDevRespInfo; sTxBusMsg.senderAddr = MY_ADDR; sTxBusMsg.msg.devBus.receiverAddr = spRxBusMsg->senderAddr; sTxBusMsg.msg.devBus.x.devResp.info.devType = eBusDevTypeSw8Cal; strncpy((char *)(sTxBusMsg.msg.devBus.x.devResp.info.version), version, BUS_DEV_INFO_VERSION_LEN); sTxBusMsg.msg.devBus.x.devResp.info.version[BUS_DEV_INFO_VERSION_LEN - 1] = '\0'; BusSend(&sTxBusMsg); break; case eBusDevReqSetAddr: sTxBusMsg.senderAddr = MY_ADDR; sTxBusMsg.type = eBusDevRespSetAddr; sTxBusMsg.msg.devBus.receiverAddr = spRxBusMsg->senderAddr; p = &(spRxBusMsg->msg.devBus.x.devReq.setAddr.addr); eeprom_write_byte((uint8_t *)MODUL_ADDRESS, *p); BusSend(&sTxBusMsg); break; case eBusDevReqEepromRead: sTxBusMsg.senderAddr = MY_ADDR; sTxBusMsg.type = eBusDevRespEepromRead; sTxBusMsg.msg.devBus.receiverAddr = spRxBusMsg->senderAddr; sTxBusMsg.msg.devBus.x.devResp.readEeprom.data = eeprom_read_byte((const uint8_t *)spRxBusMsg->msg.devBus.x.devReq.readEeprom.addr); BusSend(&sTxBusMsg); break; case eBusDevReqEepromWrite: sTxBusMsg.senderAddr = MY_ADDR; sTxBusMsg.type = eBusDevRespEepromWrite; sTxBusMsg.msg.devBus.receiverAddr = spRxBusMsg->senderAddr; p = &(spRxBusMsg->msg.devBus.x.devReq.writeEeprom.data); eeprom_write_byte((uint8_t *)spRxBusMsg->msg.devBus.x.devReq.readEeprom.addr, *p); BusSend(&sTxBusMsg); break; case eBusDevReqDoClockCalib: if (spRxBusMsg->msg.devBus.x.devReq.doClockCalib.command == eBusDoClockCalibInit) { sCount = 0; sOsccal = 0; sMinDiff = 0xffff; } else if (sCount > MAX_CAL_TEL) { sTxBusMsg.msg.devBus.x.devResp.doClockCalib.state = eBusDoClockCalibStateError; sTxBusMsg.senderAddr = MY_ADDR; sTxBusMsg.type = eBusDevRespDoClockCalib; sTxBusMsg.msg.devBus.receiverAddr = spRxBusMsg->senderAddr; BusSend(&sTxBusMsg); break; } flags = DISABLE_INT; BUS_TRANSCEIVER_POWER_UP; PORTB = 0; /* 8 bytes 0x00: 8 * (1 start bit + 8 data bits) + 7 stop bits */ seqLen = 8 * 1000000 * 9 / 9600 + 7 * 1000000 * 1 / 9600; /* = 8229 us */ old_osccal = OSCCAL; ExitComm(); InitTimer1(); TCCR1B = (1 << ICES1) | TIMER1_PRESCALER; OSCCAL = sOsccal; NOP_10; for (i = 0; i < 8; i++) { startCnt = Synchronize(); stopCnt = ClkMeasure(); clocks = stopCnt - startCnt; if (clocks > seqLen) { diff = clocks - seqLen; } else { diff = seqLen - clocks; } if (diff < sMinDiff) { sMinDiff = diff; sMinOsccal = OSCCAL; } OSCCAL++; NOP_4; } BUS_TRANSCEIVER_POWER_DOWN; InitTimer1(); InitComm(); sOsccal = OSCCAL; OSCCAL = old_osccal; RESTORE_INT(flags); if (sCount < MAX_CAL_TEL) { sTxBusMsg.msg.devBus.x.devResp.doClockCalib.state = eBusDoClockCalibStateContiune; sCount++; } else { sTxBusMsg.msg.devBus.x.devResp.doClockCalib.state = eBusDoClockCalibStateSuccess; /* save the osccal correction value to eeprom */ osccal_corr = eeprom_read_byte((const uint8_t *)OSCCAL_CORR); osccal_corr += sMinOsccal - old_osccal; eeprom_write_byte((uint8_t *)OSCCAL_CORR, osccal_corr); OSCCAL = sMinOsccal; NOP_10; } sTxBusMsg.senderAddr = MY_ADDR; sTxBusMsg.type = eBusDevRespDoClockCalib; sTxBusMsg.msg.devBus.receiverAddr = spRxBusMsg->senderAddr; BusSend(&sTxBusMsg); break; default: break; } } }