void vscp_handleProbeState(void) { switch (vscp_node_substate) { case VSCP_SUBSTATE_NONE: if (VSCP_ADDRESS_FREE != vscp_probe_address) { vscp_omsg.flags = VSCP_VALID_MSG + 1; // one databyte vscp_omsg.priority = VSCP_PRIORITY_HIGH; vscp_omsg.vscp_class = VSCP_CLASS1_PROTOCOL; vscp_omsg.vscp_type = VSCP_TYPE_PROTOCOL_NEW_NODE_ONLINE; vscp_omsg.data[ 0 ] = vscp_probe_address; // send the probe vscp_sendEvent(); vscp_node_substate = VSCP_SUBSTATE_INIT_PROBE_SENT; vscp_timer = 0; } else { // No free address -> error vscp_node_state = VSCP_STATE_ERROR; // Tell system we are giving up vscp_omsg.flags = VSCP_VALID_MSG + 1; // one databyte vscp_omsg.data[ 0 ] = 0xff; // we are unassigned vscp_omsg.priority = VSCP_PRIORITY_LOW; vscp_omsg.vscp_class = VSCP_CLASS1_PROTOCOL; vscp_omsg.vscp_type = VSCP_TYPE_PROTOCOL_PROBE_ACK; // send the error event vscp_sendEvent(); } break; case VSCP_SUBSTATE_INIT_PROBE_SENT: if (vscp_imsg.flags & VSCP_VALID_MSG) { // incoming event? // Yes, incoming event if ((VSCP_CLASS1_PROTOCOL == vscp_imsg.vscp_class) && (VSCP_TYPE_PROTOCOL_PROBE_ACK == vscp_imsg.vscp_type)) { // Yes it was an ack from the segment master or a node if (0 == vscp_probe_address) { // Master controller answered // wait for address vscp_node_state = VSCP_STATE_PREACTIVE; vscp_timer = 0; // reset timer } else { // node answered, try next address vscp_probe_address++; vscp_node_substate = VSCP_SUBSTATE_NONE; vscp_probe_cnt = 0; } } } else { if (vscp_timer > VSCP_PROBE_TIMEOUT) { // Check for timeout vscp_probe_cnt++; // Another timeout if (vscp_probe_cnt >= VSCP_PROBE_TIMEOUT_COUNT) { // Yes we have a timeout if (0 == vscp_probe_address) { // master controller probe? // No master controler on segment, try next node vscp_probe_address++; vscp_node_substate = VSCP_SUBSTATE_NONE; vscp_timer = 0; vscp_probe_cnt = 0; } else { // We have found a free address - use it vscp_nickname = vscp_probe_address; vscp_node_state = VSCP_STATE_ACTIVE; vscp_node_substate = VSCP_SUBSTATE_NONE; vscp_writeNicknamePermanent(vscp_nickname); vscp_setSegmentCRC(0x40); // segment code (non server segment ) // Report success vscp_probe_cnt = 0; vscp_goActiveState(); } } else { vscp_node_substate = VSCP_SUBSTATE_NONE; } } // Timeout } break; case VSCP_SUBSTATE_INIT_PROBE_ACK: break; default: vscp_node_substate = VSCP_SUBSTATE_NONE; break; } vscp_imsg.flags = 0; }
//*************************************************************************** // Main() - Main Routine //*************************************************************************** void main( void ) { unsigned char a; unsigned char i; unsigned char ctrlreg; // Current control register BOOL bOn; EmDataFlags.EmDataReceived = 0; EmDataFlags.EmDataTrue = 0; EmDataTimer = 0; init(); // Initialize Microcontroller // Check VSCP persistent storage and // restore if needed if ( !vscp_check_pstorage() ) { // Spoiled or not initialized - reinitialize init_app_eeprom(); } vscp_init(); // Initialize the VSCP functionality while ( 1 ) { // Loop Forever ClrWdt(); // Give the dog a bone if ( ( vscp_initbtncnt > 250 ) && ( VSCP_STATE_INIT != vscp_node_state ) ) { // Init button pressed vscp_nickname = VSCP_ADDRESS_FREE; writeEEPROM( VSCP_EEPROM_NICKNAME, VSCP_ADDRESS_FREE ); vscp_init(); } // Check for a valid event vscp_imsg.flags = 0; vscp_getEvent(); // do a meaurement if needed if ( measurement_clock > 1000 ) { measurement_clock = 0; // Do VSCP one second jobs vscp_doOneSecondWork(); // Temperature report timers are only updated if in active // state guid_reset if ( VSCP_STATE_ACTIVE == vscp_node_state ) { } } switch ( vscp_node_state ) { case VSCP_STATE_STARTUP: // Cold/warm reset // Get nickname from EEPROM if ( VSCP_ADDRESS_FREE == vscp_nickname ) { // new on segment need a nickname vscp_node_state = VSCP_STATE_INIT; } else { // been here before - go on vscp_node_state = VSCP_STATE_ACTIVE; vscp_goActiveState(); } break; case VSCP_STATE_INIT: // Assigning nickname vscp_handleProbeState(); break; case VSCP_STATE_PREACTIVE: // Waiting for host initialisation vscp_goActiveState(); break; case VSCP_STATE_ACTIVE: // The normal state if ( vscp_imsg.flags & VSCP_VALID_MSG ) { // incoming message? vscp_handleProtocolEvent(); } break; case VSCP_STATE_ERROR: // Everything is *very* *very* bad. vscp_error(); break; default: // Should not be here... vscp_node_state = VSCP_STATE_STARTUP; break; } doWork(); } // while }