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();
        }
    }
}
Beispiel #2
0
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;

}