/*----------------------------------------------------------------------------- * post state changes to registered bus clients */ static void CheckEvent(void) { static uint8_t sActualClient = 0xff; /* actual client's index being processed */ static uint16_t sChangeTestTimeStamp; TClient *pClient; uint16_t actualTime16; bool actValChanged; static bool sNewClientCycleDelay = false; static uint16_t sNewClientCycleTimeStamp; TBusDevReqActualValueEvent *pActVal; bool getNextClient; uint8_t nextClient; static uint16_t sCurPwmActVal[NUM_PWM_CHANNEL]; static bool sCurPwmState[NUM_PWM_CHANNEL]; uint8_t i; uint8_t val8; if (sNumClients == 0) { return; } /* do the change detection not in each cycle */ GET_TIME_MS16(actualTime16); if (((uint16_t)(actualTime16 - sChangeTestTimeStamp)) >= CHANGE_DETECT_CYCLE_TIME_MS) { PwmGetAll(sCurPwmActVal, sizeof(sCurPwmActVal)); for (i = 0; i < NUM_PWM_CHANNEL; i++) { PwmIsOn(i, &sCurPwmState[i]); } if ((memcmp(sCurPwmActVal, sOldPwmActVal, sizeof(sCurPwmActVal)) == 0) && (memcmp(sCurPwmState, sOldPwmState, sizeof(sCurPwmActVal)) == 0)) { actValChanged = false; } else { actValChanged = true; } if (actValChanged) { memcpy(sOldPwmActVal, sCurPwmActVal, sizeof(sOldPwmActVal)); memcpy(sOldPwmState, sCurPwmState, sizeof(sOldPwmState)); sActualClient = 0; sNewClientCycleDelay = false; InitClientState(); } sChangeTestTimeStamp = actualTime16; } if (sActualClient == 0xff) { return; } if (sNewClientCycleDelay) { if (((uint16_t)(actualTime16 - sNewClientCycleTimeStamp)) < RETRY_CYCLE_TIME_MS) { return; } else { sNewClientCycleDelay = false; } } pClient = &sClient[sActualClient]; getNextClient = true; switch (pClient->state) { case eEventInit: pActVal = &sTxBusMsg.msg.devBus.x.devReq.actualValueEvent; sTxBusMsg.type = eBusDevReqActualValueEvent; sTxBusMsg.senderAddr = MY_ADDR; sTxBusMsg.msg.devBus.receiverAddr = pClient->address; pActVal->devType = eBusDevTypePwm4; memcpy(pActVal->actualValue.pwm4.pwm, sCurPwmActVal, sizeof(pActVal->actualValue.pwm4.pwm)); val8 = 0; for (i = 0; i < NUM_PWM_CHANNEL; i++) { val8 |= sCurPwmState[i] ? 1 << i : 0; } pActVal->actualValue.pwm4.state = val8; if (BusSend(&sTxBusMsg) == BUS_SEND_OK) { pClient->state = eEventWaitForConfirmation; pClient->requestTimeStamp = actualTime16; } else { getNextClient = false; } break; case eEventWaitForConfirmation: if ((((uint16_t)(actualTime16 - pClient->requestTimeStamp)) >= RESPONSE_TIMEOUT_MS) && (pClient->state != eEventMaxRetry)) { if (pClient->curRetry < pClient->maxRetry) { /* try again */ pClient->curRetry++; getNextClient = false; pClient->state = eEventInit; } else { pClient->state = eEventMaxRetry; } } break; case eEventConfirmationOK: break; default: break; } if (getNextClient) { nextClient = GetUnconfirmedClient(sActualClient); if (nextClient <= sActualClient) { sNewClientCycleDelay = true; sNewClientCycleTimeStamp = actualTime16; } sActualClient = nextClient; } }
/*----------------------------------------------------------------------------- * post state changes to registered bus clients */ static void ProcessSwitch(void) { static uint8_t sActualClient = 0xff; /* actual client's index being processed */ static uint16_t sChangeTimeStamp; TClient *pClient; uint16_t actualTime16; static bool sNewClientCycleDelay = false; static uint16_t sNewClientCycleTimeStamp; uint8_t rc; bool getNextClient; uint8_t nextClient; bool switchStateChanged; if (sNumClients == 0) { return; } if ((sWindSwitch ^ sWindSwitchOld) != 0) { switchStateChanged = true; } else { switchStateChanged = false; } /* do the change detection not in each cycle */ GET_TIME_MS16(actualTime16); if (switchStateChanged) { sChangeTimeStamp = actualTime16; sActualClient = 0; sNewClientCycleDelay = false; InitClientState(); sWindSwitchOld = sWindSwitch; } if (sActualClient == 0xff) { return; } if (sNewClientCycleDelay) { if (((uint16_t)(actualTime16 - sNewClientCycleTimeStamp)) < RETRY_CYCLE_TIME_MS) { return; } else { sNewClientCycleDelay = false; } } pClient = &sClient[sActualClient]; getNextClient = true; switch (pClient->state) { case eInit: sTxBusMsg.type = eBusDevReqSwitchState; sTxBusMsg.senderAddr = MY_ADDR; sTxBusMsg.msg.devBus.receiverAddr = pClient->address; sTxBusMsg.msg.devBus.x.devReq.switchState.switchState = sWindSwitch; rc = BusSend(&sTxBusMsg); if (rc == BUS_SEND_OK) { pClient->state = eWaitForConfirmation; pClient->requestTimeStamp = actualTime16; } else { getNextClient = false; } break; case eWaitForConfirmation: if (((uint16_t)(actualTime16 - pClient->requestTimeStamp)) >= RESPONSE_TIMEOUT_MS) { /* try once more */ pClient->state = eInit; getNextClient = false; } break; case eConfirmationOK: break; default: break; } if (getNextClient) { nextClient = GetUnconfirmedClient(sActualClient); if (nextClient <= sActualClient) { sNewClientCycleDelay = true; sNewClientCycleTimeStamp = actualTime16; } sActualClient = nextClient; } if (((uint16_t)(actualTime16 - sChangeTimeStamp)) > RETRY_TIMEOUT_MS) { sActualClient = 0xff; // stop } }