示例#1
0
文件: main.c 项目: tpotechnix/homebus
/*-----------------------------------------------------------------------------
*  send switch state change to clients
*  - client address list is read from eeprom
*  - if there is no confirmation from client within RESPONSE_TIMEOUT2
*    the next client in list is processed
*  - telegrams to clients without response are repeated again and again
*    til telegrams to all clients in list are confirmed
*  - if switchStateChanged occurs while client confirmations are missing
*    actual client process is canceled and the new state telegram is sent
*    to clients 
*/
static void ProcessSwitch(uint8_t switchState) {

   static uint8_t   sActualClient = 0xff; /* actual client's index being processed */
   static uint16_t  sChangeTimeStamp;
   TClient        *pClient;
   uint8_t          i;
   uint16_t         actualTime16;
   uint8_t          actualTime8;
   bool           switchStateChanged;
   bool           startProcess;
   
   if ((switchState ^ sSwitchStateOld) != 0) {
       switchStateChanged = true;
   } else {
       switchStateChanged = false;
   }
 
   if (switchStateChanged) {
      if (sActualClient < BUS_MAX_CLIENT_NUM) {
         pClient = &sClient[sActualClient];
         if (pClient->state == eWaitForConfirmation1) {
            startProcess = false;
         } else {
            startProcess = true;
            sSwitchStateOld = switchState;
         }
      } else {
         startProcess = true;
         sSwitchStateOld = switchState;
      }
      if (startProcess == true) {
         sSwitchStateActual = switchState;
         GET_TIME_MS16(sChangeTimeStamp);
         /* set up client descriptor array */
         sActualClient = 0;
         pClient = &sClient[0];
         for (i = 0; i < BUS_MAX_CLIENT_NUM; i++) {
            pClient->address = eeprom_read_byte((const uint8_t *)(CLIENT_ADDRESS_BASE + i));
            if (pClient->address != BUS_CLIENT_ADDRESS_INVALID) {
               pClient->state = eInit;
            } else {
               pClient->state = eSkip;
            }
            pClient++;
         }
      }
   }
       
   if (sActualClient < BUS_MAX_CLIENT_NUM) {
      GET_TIME_MS16(actualTime16);
      if (((uint16_t)(actualTime16 - sChangeTimeStamp)) < RETRY_TIMEOUT2_MS) {
         pClient = &sClient[sActualClient];
         if (pClient->state == eConfirmationOK) {
            /* get next client */
            sActualClient = GetUnconfirmedClient(sActualClient);
            if (sActualClient < BUS_MAX_CLIENT_NUM) {
               pClient = &sClient[sActualClient];
            } else {
               /* we are ready */
            }
         }
         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 = sSwitchStateActual;
               BusSend(&sTxBusMsg);  
               pClient->state = eWaitForConfirmation1;
               GET_TIME_MS16(pClient->requestTimeStamp);
               break;
            case eWaitForConfirmation1:
               actualTime8 = GET_TIME_MS;
               if (((uint8_t)(actualTime8 - pClient->requestTimeStamp)) >= RESPONSE_TIMEOUT1_MS) {
                  pClient->state = eWaitForConfirmation2;
                  GET_TIME_MS16(pClient->requestTimeStamp);
               }
               break;
            case eWaitForConfirmation2:
               GET_TIME_MS16(actualTime16);
               if (((uint16_t)(actualTime16 - pClient->requestTimeStamp)) >= RESPONSE_TIMEOUT2_MS) {
                  /* set client for next try after the other clients */
                  pClient->state = eInit;
                  /* try next client */
                  sActualClient = GetUnconfirmedClient(sActualClient);
               }
               break;
            default:
               break;
         }
      } else {
         sActualClient = 0xff;
      }
   }
}
示例#2
0
文件: main.c 项目: busmaster/homebus
/*-----------------------------------------------------------------------------
*   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;
    }
}
示例#3
0
文件: main.c 项目: tpotechnix/homebus
/*-----------------------------------------------------------------------------
*   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 
    }
}