void vscp_handlePreActiveState(void) { if ( vscp_imsg.flags & VSCP_VALID_MSG ) { // incoming event? if ((VSCP_CLASS1_PROTOCOL == vscp_imsg.vscp_class) && (VSCP_TYPE_PROTOCOL_SET_NICKNAME == vscp_imsg.vscp_type) && (VSCP_ADDRESS_FREE == vscp_imsg.data[ 0 ])) { // Assign nickname vscp_nickname = vscp_imsg.data[ 1 ]; vscp_writeNicknamePermanent(vscp_nickname); vscp_setSegmentCRC(0x40); // Go active state vscp_node_state = VSCP_STATE_ACTIVE; } } else { // Check for time out if (vscp_timer > VSCP_PROBE_TIMEOUT) { // Yes, we have a timeout vscp_nickname = VSCP_ADDRESS_FREE; vscp_writeNicknamePermanent(VSCP_ADDRESS_FREE); vscp_init(); } } }
void vscp_handleDropNickname(void) { uint8_t bytes = vscp_imsg.flags & 0x0f; #ifdef DROP_NICKNAME_EXTENDED_FEATURES uint8_t brake = 0; #endif if ((bytes >= 1) && (vscp_nickname == vscp_imsg.data[ 0 ])) { // Yes, we are addressed #ifdef DROP_NICKNAME_EXTENDED_FEATURES // Optional Byte 1: // bit7 - go idle do not start, bit6 - reset persistent storage // bit5 - reset device but keep nickname // bit5 and bit 7 are concurrent, here I give bit 5 higher priority // Optional byte 2: time in seconds before restarting (makes only sense // with either none of the bits or only bit 5 of byte1 set. if (bytes >= 2) { // byte 1 does exist // bit 6 set: reset persistent storage, continue to check other // options in byte 1 if (vscp_imsg.data[1] & (1<<6)) { // reset persistent storage here } // bit 5 set: reset device, keep nickname, disregard other option // below this by using 'brake' if ((vscp_imsg.data[1] & (1<<5)) && (brake == 0)) { vscp_hardreset(); brake = 1;} // bit 7 set: go idle, e.g. stay in an endless loop until re-power if ((vscp_imsg.data[1] & (1<<7)) && (brake == 0)) { vscp_nickname = VSCP_ADDRESS_FREE; vscp_writeNicknamePermanent(VSCP_ADDRESS_FREE); for (;;) {}; // wait forever } } #endif // none of the options from byte 1 have been used or byte 1 itself // has not been transmitted at all if ((bytes == 1) || ((bytes > 1) && (vscp_imsg.data[1] == 0))) { // this is the regular behaviour without using byte 1 options vscp_nickname = VSCP_ADDRESS_FREE; vscp_writeNicknamePermanent(VSCP_ADDRESS_FREE); vscp_init(); } #ifdef DROP_NICKNAME_EXTENDED_FEATURES // now check if timing was passed in byte 2 if (bytes > 2) { // and waiting for options that made sense if ( (vscp_imsg.data[1] == 0) || ( vscp_imsg.data[1] & (1<<6)) || ( vscp_imsg.data[1] & (1<<5)) ) { // wait platform independently vscp_wait_s(vscp_imsg.data[2]); } } #endif } }
int8_t vscp_check_pstorage(void) { // Check if persistent storage is initialised. if ( ( VSCP_INITIALIZED_BYTE0_VALUE == vscp_getControlByte( VSCP_INITIALIZED_BYTE0_INDEX ) ) && ( VSCP_INITIALIZED_BYTE1_VALUE == vscp_getControlByte( VSCP_INITIALIZED_BYTE1_INDEX ) ) ) { return TRUE; } vscp_initledfunc = VSCP_LED_BLINK1; // Initialise persistent storage vscp_init_pstorage(); // No nickname yet. vscp_writeNicknamePermanent( VSCP_ADDRESS_FREE ); // Mark persistent storage as initialised vscp_setControlByte( VSCP_INITIALIZED_BYTE0_INDEX, VSCP_INITIALIZED_BYTE0_VALUE ); vscp_setControlByte( VSCP_INITIALIZED_BYTE1_INDEX, VSCP_INITIALIZED_BYTE1_VALUE ); return FALSE; }
void vscp_handleSetNickname(void) { if ((2 == (vscp_imsg.flags & 0x0f)) && (vscp_nickname == vscp_imsg.data[ 0 ])) { // Yes, we are addressed vscp_nickname = vscp_imsg.data[ 1 ]; vscp_writeNicknamePermanent(vscp_nickname); vscp_setSegmentCRC(0x40); } }
void vscp_handleDropNickname(void) { if ((1 == (vscp_imsg.flags & 0x0f)) && (vscp_nickname == vscp_imsg.data[ 0 ])) { // Yes, we are addressed vscp_nickname = VSCP_ADDRESS_FREE; vscp_writeNicknamePermanent(VSCP_ADDRESS_FREE); vscp_init(); } }
void vscp_handleHeartbeat(void) { if ((5 == (vscp_imsg.flags & 0x0f)) && (vscp_getSegmentCRC() != vscp_imsg.data[ 0 ])) { // Stored CRC are different than received // We must be on a different segment vscp_setSegmentCRC(vscp_imsg.data[ 0 ]); // Introduce ourself in the proper way and start from the beginning vscp_nickname = VSCP_ADDRESS_FREE; vscp_writeNicknamePermanent(VSCP_ADDRESS_FREE); vscp_node_state = VSCP_STATE_INIT; } }
int8_t vscp_check_pstorage(void) { // controlbyte == 01xxxxxx means initialized // everything else is uninitialized if ((vscp_getSegmentCRC() & 0xc0) == 0x40) { return TRUE; } // No nickname yet. vscp_writeNicknamePermanent(0xff); // No segment CRC yet. vscp_setSegmentCRC(0x00); // Initial startup // write allowed vscp_setControlByte(0xA0); return FALSE; }
void vscp_handleSetNickname(void) { if ( ( 2 == (vscp_imsg.flags & 0x0f ) ) && (vscp_nickname == vscp_imsg.data[ 0 ])) { // Yes, we are addressed vscp_nickname = vscp_imsg.data[ 1 ]; vscp_writeNicknamePermanent(vscp_nickname); //return nickname accepted vscp_omsg.flags = VSCP_VALID_MSG + 1; // one data byte vscp_omsg.priority = VSCP_PRIORITY_HIGH; vscp_omsg.vscp_class = VSCP_CLASS1_PROTOCOL; vscp_omsg.vscp_type = VSCP_TYPE_PROTOCOL_NICKNAME_ACCEPTED; vscp_omsg.data[ 0 ] = vscp_nickname; // send the event vscp_sendEvent(); } }
/*! * @brief verify functionality of the custom defined vscp functions * vscp_firmware.h @ line 457 */ void test_vscp_externals(){ uint8_t FlashValue8; /*! gets an 8-bit vscp data field from permanent storage */ uint8_t val; /*! assign a value to write to buffer -> permanent storage */ printf("Testing vscp_functions\r\n"); val = 0x11; vscp_writeNicknamePermanent(val); FlashValue8 = vscp_readNicknamePermanent(); printf("Read %d dec, %x hex\r\n", FlashValue8, FlashValue8); val = 0x22; vscp_setSegmentCRC(val); FlashValue8 = vscp_getSegmentCRC(); printf("Read %d dec, %x hex\r\n", FlashValue8, FlashValue8); val = 0x33; vscp_setControlByte(val); FlashValue8 = vscp_getControlByte(); printf("Read %d dec, %x hex\r\n", FlashValue8, FlashValue8); }
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; }