/////////////////////////////////////////////////////////////////////////////// // vscp_preactive // void vscp_handleReactive( void ) { if ( E_OK == VSCP_deqMsgRx( &RxMsg)) { // incoming message? // Yes, incoming message if (( VSCP_CLASS1_PROTOCOL == RxMsg.vscp_class) && ( VSCP_TYPE_PROTOCOL_SET_NICKNAME == RxMsg.vscp_type) && ( VSCP_ADDRESS_FREE == RxMsg.data[0])) { // Assign nickname vscp_nickname = RxMsg.data[2]; vscp_setNickname( vscp_nickname); vscp_setSegmentCRC( VSCP_CRC_DEFAULT);// segment code (non server segment ) vscp_init(); // Clear Activation, with a Right Asigned NICKNAME } } else { // Check for time out if ( vscp_timer > VSCP_PROBE_TIMEOUT) { // Yes, we have a timeout vscp_nickname = VSCP_ADDRESS_FREE; vscp_setNickname( VSCP_ADDRESS_FREE); vscp_init(); //No answer from Server, Clear Restart with VSCP_ADDRESS_FREE } } }
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(); } } }
//*************************************************************************** // Main() - Main Routine //*************************************************************************** void main(){ OSCCON = 0xF0; //Initialitation of Internal Oscillator OSCTUNEbits.PLLEN = 1; hardware_setup(); //Hardware initialization if ( !vscp_check_pstorage() ) // Check VSCP persistent storage and init_app_eeprom(); // restore if needed init_app_ram(); // Initialize data vscp_init(); // Initialize the VSCP functionality while(1){ //Handler scheduler ClrWdt(); // Feed the dog if(timeEvent._10mS){ //10mS Event timeEvent._10mS = 0; vscp_10mS_Running(); hardware_10mS(); } if(timeEvent._100mS){ //100mS Event timeEvent._100mS = 0; vscp_100mS_Running(); vscp_ledActivity(); } if(timeEvent._1s){ //1second Event timeEvent._1s = 0; vscp_doOneSecondWork(); // Do VSCP one second jobs greenLed_pin = !greenLed_pin; } vscp_freeRunning(); //TODO: Handling the override event } }
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 } }
/////////////////////////////////////////////////////////////////////////////// // vscp_handleDropNickname // void vscp_handleDropNickname( void ) { if (( 1 == RxMsg.length ) && ( vscp_nickname == RxMsg.data[0])) { // Yes, we are addressed vscp_nickname = VSCP_ADDRESS_FREE; vscp_setNickname( VSCP_ADDRESS_FREE ); vscp_init(); // Clear Restart with VSCP_ADDRESS_FREE } }
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(); } }
/////////////////////////////////////////////////////////////////////////////// // vscp_rcv_heartbeat // void vscp_handleHeartbeat( void ) { if ((5 == RxMsg.length)&& ( vscp_getSegmentCRC()!= RxMsg.data[0])) { // Stored CRC are different than received // We must be on a different segment vscp_setSegmentCRC( RxMsg.data[0]); // Introduce ourself in the proper way and start from the beginning vscp_nickname = VSCP_ADDRESS_FREE; vscp_setNickname( VSCP_ADDRESS_FREE); vscp_init(); // Clear Restart with VSCP_ADDRESS_FREE } }
/////////////////////////////////////////////////////////////////////////////// // vscp_handleProbeState // void vscp_handleProbeState( void ) { switch ( vscp_node_substate ) { case VSCP_SUBSTATE_NONE: if ( VSCP_ADDRESS_FREE != vscp_probe_address ) { SendMsg.priority = VSCP_PRIORITY_HIGH; SendMsg.vscp_class = VSCP_CLASS1_PROTOCOL; SendMsg.vscp_type = VSCP_TYPE_PROTOCOL_NEW_NODE_ONLINE; SendMsg.length = 1 ; SendMsg.data[ 0 ] = vscp_probe_address; // send the probe VSCP_enqMsgTx( &SendMsg, FALSE); 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 SendMsg.priority = VSCP_PRIORITY_HIGH; SendMsg.vscp_class = VSCP_CLASS1_PROTOCOL; SendMsg.vscp_type = VSCP_TYPE_PROTOCOL_PROBE_ACK; SendMsg.data[ 0 ] = 0xff; // we are unassigned SendMsg.length = 1 ; // send the error event VSCP_enqMsgTx( &SendMsg, FALSE); } break; case VSCP_SUBSTATE_INIT_PROBE_SENT: if ( E_OK == VSCP_deqMsgRx( &RxMsg)) { // incoming message? // Yes, incoming message if ( ( VSCP_CLASS1_PROTOCOL == RxMsg.vscp_class ) && ( VSCP_TYPE_PROTOCOL_PROBE_ACK == RxMsg.vscp_type ) ) { // Yes it was an ack from the segment master or a node if ( !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. Repet each probe four times ( 4 * 500ms = 2 S) if ( vscp_probe_cnt >= 4) { // Yes we have a timeout, no answer received if ( !vscp_probe_address) { // master controller probe? // No master controler on segment, try next node vscp_probe_address++; vscp_node_substate = VSCP_SUBSTATE_NONE; } else { // No answer, We have found a free address - use it vscp_nickname = vscp_probe_address; vscp_setNickname( vscp_nickname); vscp_setSegmentCRC( VSCP_CRC_DEFAULT);// segment code (non server segment ) vscp_init(); // Clear Activation, with a Right Discovered NICKNAME } } else { vscp_node_substate = VSCP_SUBSTATE_NONE; } } // Timeout } break; case VSCP_SUBSTATE_INIT_PROBE_ACK: // Developed in function before break; default: vscp_node_substate = VSCP_SUBSTATE_NONE; break; } }
/////////////////////////////////////////////////////////////////////////////// // Main entry point. // void main(void) { static TICK8 t = 0; BYTE i; char strBuf[10]; // Initialize any application specific hardware. InitializeBoard(); // Initialize all stack related components. // Following steps must be performed for all applications using // PICmicro TCP/IP Stack. TickInit(); // Initialize file system. fsysInit(); // Intialize HTTP Execution unit htpexecInit(); // Initialze serial port serInit(); // Initialize Stack and application related NV variables. appcfgInit(); appcfgUSART(); // Configure the USART #ifdef SER_USE_INTERRUPT // Interrupt enabled serial ports have to be enabled serEnable(); #endif appcfgCpuIO(); // Configure the CPU's I/O port pin directions - input or output appcfgCpuIOValues(); // Configure the CPU's I/O port pin default values appcfgADC(); // Configure ADC unit appcfgPWM(); // Configure PWM unit // Serial configuration menu - display it for configured time and // allow user to enter configuration menu scfInit( appcfgGetc( APPCFG_STARTUP_SER_DLY ) ); StackInit(); #if defined(STACK_USE_HTTP_SERVER) HTTPInit(); #endif #if defined( STACK_USE_DHCP ) || defined( STACK_USE_IP_GLEANING ) // If DHCP is NOT enabled if ( ( appcfgGetc( APPCFG_NETFLAGS ) & APPCFG_NETFLAGS_DHCP ) == 0 ) { // Force IP address display update. myDHCPBindCount = 1; #if defined( STACK_USE_DHCP ) DHCPDisable(); #endif } #endif #if ( DEBUG_MAIN >= LOG_DEBUG ) debugPutMsg(1); //@mxd:1:Starting main loop #endif // Init VSCP functionality vscp_init(); bInitialized = FALSE; // Not initialized #if defined(STACK_USE_NTP_SERVER) // Initialize time hour = 0; minute = 0; second = 0; #endif appcfgPutc( VSCP_DM_MATRIX_BASE, 0x00 ); appcfgPutc( VSCP_DM_MATRIX_BASE+1, 0x00 ); appcfgPutc( VSCP_DM_MATRIX_BASE+2, 0x00 ); appcfgPutc( VSCP_DM_MATRIX_BASE+3, 0x00 ); // // Once all items are initialized, go into infinite loop and let // stack items execute their tasks. // If application needs to perform its own task, it should be // done at the end of while loop. // Note that this is a "co-operative mult-tasking" mechanism // where every task performs its tasks (whether all in one shot // or part of it) and returns so that other tasks can do their // job. // If a task needs very long time to do its job, it must broken // down into smaller pieces so that other tasks can have CPU time. // while ( 1 ) { // Used for initial delay to give stack and chip some time to // initialize. If not used messages sent during this time will // fail. if ( TickGet() > ( 5 * TICK_SECOND ) ) { bInitialized = TRUE; } // We should do the ftp download every three hours //if ( TickGetDiff( TickGet(), loadTime ) >= ( 3 * 3600 * TICK_SECOND ) ) { // loadTime = TickGet(); // bftpLoadWork = TRUE; //} // Blink SYSTEM LED every second. if ( appcfgGetc( APPCFG_SYSFLAGS ) & APPCFG_SYSFLAGS_BLINKB6 ) { if ( TickGetDiff8bit( t ) >= ((TICK8)( TICKS_PER_SECOND / 2 ) ) ) { t = TickGet8bit(); TRISB_RB6 = 0; LATB6 ^= 1; } } // This task performs normal stack task including checking for incoming packet, // type of packet and calling appropriate stack entity to process it. StackTask(); #if defined(STACK_USE_HTTP_SERVER) // This is a TCP application. It listens to TCP port 80 // with one or more sockets and responds to remote requests. HTTPServer(); #endif #if defined(STACK_USE_FTP_SERVER) FTPServer(); #endif // Add your application speicifc tasks here. ProcessIO(); #if defined(VSCP_USE_TCP ) // VSCP Task if ( bInitialized ) { vscp_tcp_task(); } #endif if ( bInitialized ) { vscp_main_task(); process_can_message(); if ( g_can_error ) { send_can_error_message( g_can_error ); g_can_error = 0; } } #if defined(STACK_USE_NTP_SERVER) if ( bInitialized ) { //ntp_task(); } #endif // For DHCP information, display how many times we have renewed the IP // configuration since last reset. if ( DHCPBindCount != myDHCPBindCount ) { #if (DEBUG_MAIN >= LOG_INFO) debugPutMsg( 2 ); // @mxd:2:DHCP Bind Count = %D debugPutByteHex(DHCPBindCount); #endif // Display new IP address #if (DEBUG_MAIN >= LOG_INFO) debugPutMsg( 3 ); //@mxd:3:DHCP complete, IP = %D.%D.%D.%D debugPutByteHex( AppConfig.MyIPAddr.v[ 0 ] ); debugPutByteHex( AppConfig.MyIPAddr.v[ 1 ] ); debugPutByteHex( AppConfig.MyIPAddr.v[ 2 ] ); debugPutByteHex( AppConfig.MyIPAddr.v[ 3 ] ); #endif myDHCPBindCount = DHCPBindCount; } } }
//*************************************************************************** // 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 }