The Main loop

The VSCP related main loop for the Paris reference node look like this

while ( 1 ) {   // Loop Forever

   ClrWdt();   // Feed the dog

   if ( ( vscp_initbtncnt > 250 ) &&
                ( VSCP_STATE_INIT != vscp_node_state ) ) {

       // Init button pressed
       vscp_nickname = VSCP_ADDRESS_FREE;


    // Check for a valid  event
    vscp_imsg.flags = 0;

    switch ( vscp_node_state ) {

        // Cold/warm reset
        case VSCP_STATE_STARTUP: 

            // 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;

        // Assigning nickname
        case VSCP_STATE_INIT: 

        // Waiting for host initialisation
        case VSCP_STATE_PREACTIVE:  

        // The normal state
        case VSCP_STATE_ACTIVE:     

            // Check for incoming event?
            if (vscp_imsg.flags & VSCP_VALID_MSG) {

                if ( VSCP_CLASS1_PROTOCOL == vscp_imsg.vscp_class  ) {

                    // Handle protocol event




        // Everything is *very* *very* bad.
        case VSCP_STATE_ERROR: 

        default: // Should not be here...
            vscp_node_state = VSCP_STATE_STARTUP;


    do other things here

We recognize the button function we looked at before. An it is followed by

// Check for a valid  event
vscp_imsg.flags = 0;

which fetch one VSCP event. This event is placed in the vscp_imsg structure if one is available and then the flag VSCP_VALID_MSG s set in vscp_imsg.flags.

If you look at the code for the Paris reference node you will see that the method vscp_getEvent just read a CAN message and translate it into a VSCP event and place it in the global vscp_imsg structure. This is because we use the buffering supplied by the processor in this case. If you don't have that buffering you should probably implement it in your firmware. Anyway the global vscp_imsg is there to make it possible to build systems with low memory footprint and grow from there when needed.

When a possible incoming event is fetched we have a case that goes through the VSCP states.


This is the state we are in after a cold or a warm reset. From here we go to the VSCP_STATE_INIT if a nickname has not been assigned to this node or to the VSCP_STATE_ACTIVE if a nickname is assigned.

This means that a node that is started for the first time will go to nickname discovery while a node that has been started before and which has got a nickname will go into the actice state ready to do it's work.


In the init. state we do one thing. Call the vscp_handleProbeState which is the handler for the nickname discover process. This method will take us out of this state either when a nickname is found or not.


In this state we do one thing, call the method vscp_goActiveState which report to the work that we are here and have found a free nickname id by sending the event CLASS1.EVENT, Type=2, New node on line which is the same as the probe send to look for a free nickaname execpt that the origin is the discovered free nickname and not 0xff.


You should not get to this state but if you do everything is bad.


In the active state two things needs to be done. First if a protocol event is received it must be feed to the vscp firmware code and this is what is done in the method vscp_handleProtocolEvent then if the node have a decision matrix is the event should be feed through it to search for a possible match. This is done in the method doDM which is not part of the vscp firmware code.

That's it, oh well almost.

Very Simple Control Protocol
This document is licensed under Creative Commons BY 4.0 and can be freely copied, redistributed, remixed, transformed, built upon as long as you give credits to the author.

results matching ""

    No results matching ""