/** 
Sets the module LEDs to the selected mode.
On Zigbee BoosterPack, GPIO2 & GPIO3 are connected to LEDs. 
@param mode - LED Display mode
@pre module GPIOs were configured as outputs
@return 0 if success, else error
@note on Zigbee BoosterPack, DIP switch S4 must have switches "3" and "4" set to "ON" to see the LEDs.
*/
static uint8_t setModuleLeds(uint8_t mode)
{
    if (mode > RGB_LED_DISPLAY_MODE_MAX)
        return 1;
    
    mode <<= 2;         // Since GPIO2 & GPIO3 are used, need to shift over 2 bits
    
    if (sysGpio(GPIO_CLEAR, ALL_GPIO_PINS) != MODULE_SUCCESS)   //First, turn all off
    {
        return 2;       // Module error
    }      
    if (mode != 0)      // If mode is 0 then don't leave all off
    {
        if (sysGpio(GPIO_SET, (mode & 0x0C)) != MODULE_SUCCESS)
        {
            return 3;   // Module error
        }
    }
    return 0;
}
void stateMachine()
{
    while (1)
    {
        if (zigbeeNetworkStatus == NWK_ONLINE)
        {  
            if(moduleHasMessageWaiting())      //wait until SRDY goes low indicating a message has been received.
            {
                getMessage();                      
                displayMessage();
            }   
        }
        
        switch (state)
        {
        case STATE_IDLE:
            {
                if (stateFlags & STATE_FLAG_SEND_INFO_MESSAGE)  //if there is a pending info message to be sent
                {
                    state = STATE_SEND_INFO_MESSAGE;            //then send the message and clear the flag
                    stateFlags &= ~STATE_FLAG_SEND_INFO_MESSAGE;
                }
                /* Other flags (for different messages or events) can be added here */
                break;
            }
            
        case STATE_MODULE_STARTUP:
            {
#define MODULE_START_DELAY_IF_FAIL_MS   5000    // Must be greater than MODULE_START_FAIL_LED_ONTIME
                moduleResult_t result;
                struct moduleConfiguration defaultConfiguration = DEFAULT_MODULE_CONFIGURATION_END_DEVICE;
                
                /* Uncomment below to restrict the device to a specific PANID
                defaultConfiguration.panId = 0x1234;
                */
                
                struct applicationConfiguration endDeviceConf;
                endDeviceConf.endPoint = 1;
                endDeviceConf.latencyRequested = LATENCY_NORMAL;
                endDeviceConf.profileId = 0xcc00; // the clock profile is 0xCC00
                endDeviceConf.deviceId = 0x8866;
                endDeviceConf.deviceVersion = 0x01;
                endDeviceConf.numberOfBindingInputClusters = 4; // number of binding input cluster
                endDeviceConf.bindingInputClusters[0] = 0x0000; // basic cluster
                endDeviceConf.bindingInputClusters[1] = 0x0003; // identify cluster
                endDeviceConf.bindingInputClusters[2] = 0xfc01; // synchronise clock cluster
                endDeviceConf.bindingInputClusters[3] = 0xfc02; // send string message cluster
                endDeviceConf.numberOfBindingOutputClusters = 4; // number of binding output cluster
                endDeviceConf.bindingOutputClusters[0] = 0x0000;
                endDeviceConf.bindingOutputClusters[1] = 0x0003;
                endDeviceConf.bindingOutputClusters[2] = 0xfc01;
                endDeviceConf.bindingOutputClusters[3] = 0xfc02;
                
                struct applicationConfiguration ac;
                ac.endPoint = 1;
                ac.deviceVersion = 0x10;
                ac.profileId = 0xfafa;
                ac.latencyRequested = LATENCY_NORMAL;
                
                ac.numberOfBindingInputClusters = 2;
                ac.bindingInputClusters[0] =        0x0000;    
                ac.bindingInputClusters[1] =        0x0900;    
                ac.numberOfBindingOutputClusters = 2;
                ac.bindingOutputClusters[0] =        0x0000;
                ac.bindingOutputClusters[1] =        0x0900;
                
                /* Below is an example of how to restrict the device to only one channel:
                defaultConfiguration.channelMask = CHANNEL_MASK_17;
                printf("DEMO - USING CUSTOM CHANNEL 17\r\n");
                */
                
                //while ((result = startModule(&defaultConfiguration, GENERIC_APPLICATION_CONFIGURATION)) != MODULE_SUCCESS)
                while ((result = startModule(&defaultConfiguration, &ac)) != MODULE_SUCCESS)
                {
                    SET_NETWORK_FAILURE_LED_ON();          // Turn on the LED to show failure
                    printf("FAILED. Error Code 0x%02X. Retrying...\r\n", result);
                    delayMs(MODULE_START_DELAY_IF_FAIL_MS/2);                    
                    SET_NETWORK_FAILURE_LED_OFF();
                    delayMs(MODULE_START_DELAY_IF_FAIL_MS/2);
                }
                
                INIT_BOOSTER_PACK_LEDS();                
                SET_NETWORK_LED_ON();
                SET_NETWORK_FAILURE_LED_OFF();
                printf("Success\r\n"); 
                /* Module is now initialized so store MAC Address */
                zbGetDeviceInfo(DIP_MAC_ADDRESS);
                memcpy(hdr.mac, zmBuf+SRSP_DIP_VALUE_FIELD, 8);
#define MESSAGE_PERIOD_SECONDS  4
                int16_t timerResult = initTimer(MESSAGE_PERIOD_SECONDS);
                if (timerResult != 0)
                {
                    printf("timerResult Error %d, STOPPING\r\n", timerResult);
                    while (1);   
                }
                
                state = STATE_DISPLAY_NETWORK_INFORMATION;
                break;
            }
        case STATE_DISPLAY_NETWORK_INFORMATION:
            {
                printf("~ni~");
                /* On network, display info about this network */              
                displayNetworkConfigurationParameters();                
                displayDeviceInformation();
                /* Set module GPIOs as output and turn them off */
                if ((sysGpio(GPIO_SET_DIRECTION, ALL_GPIO_PINS) != MODULE_SUCCESS) || (sysGpio(GPIO_CLEAR, ALL_GPIO_PINS) != MODULE_SUCCESS))
                {
                    printf("ERROR\r\n");
                }
                state = STATE_SEND_INFO_MESSAGE;
                break;   
            }
        case STATE_SEND_INFO_MESSAGE:
            {
                printf("~im~");
                
                struct infoMessage im;
                /* See infoMessage.h for description of these info message fields.*/
                im.header = hdr;
                im.deviceType = DEVICETYPE_TESLA_CONTROLS_END_DEVICE_DEMO;
                im.header.sequence = sequenceNumber++;
                im.numParameters = getSensorValues(im.kvps);    // Does two things: Loads infoMessage with sensor value KVPs and gets the number of them
                                
                // now, add status message interval
                im.kvps[im.numParameters].oid = OID_STATUS_MESSAGE_INTERVAL;
                im.kvps[im.numParameters].value = MESSAGE_PERIOD_SECONDS;
                im.numParameters++;
                
                // add zigbee module information:
                if (sysVersion() != MODULE_SUCCESS)
                {
                    printf("ERROR retriving module information\r\n");
                } else {                
                displaySysVersion();
                
                // Product ID
                im.kvps[im.numParameters].oid = OID_MODULE_PRODUCT_ID;
                im.kvps[im.numParameters].value = zmBuf[SYS_VERSION_RESULT_PRODUCTID_FIELD];
                im.numParameters++;
                
                // FW - Major
                im.kvps[im.numParameters].oid = OID_MODULE_FIRMWARE_MAJOR;
                im.kvps[im.numParameters].value = zmBuf[SYS_VERSION_RESULT_FW_MAJOR_FIELD];
                im.numParameters++;    
                
                // FW - Minor
                im.kvps[im.numParameters].oid = OID_MODULE_FIRMWARE_MINOR;
                im.kvps[im.numParameters].value = zmBuf[SYS_VERSION_RESULT_FW_MINOR_FIELD];
                im.numParameters++;  

                // FW - Build
                im.kvps[im.numParameters].oid = OID_MODULE_FIRMWARE_BUILD;
                im.kvps[im.numParameters].value = zmBuf[SYS_VERSION_RESULT_FW_BUILD_FIELD];
                im.numParameters++;
                }
                
                printInfoMessage(&im);
#define RESTART_DELAY_IF_MESSAGE_FAIL_MS 5000
                uint8_t messageBuffer[MAX_INFO_MESSAGE_SIZE];
                serializeInfoMessage(&im, messageBuffer);
                setLed(SEND_MESSAGE_LED); //indicate that we are sending a message
                moduleResult_t result = afSendData(DEFAULT_ENDPOINT, DEFAULT_ENDPOINT, 0, INFO_MESSAGE_CLUSTER, messageBuffer, getSizeOfInfoMessage(&im)); // and send it
                clearLed(SEND_MESSAGE_LED);                
                if (result != MODULE_SUCCESS)
                {
                    zigbeeNetworkStatus = NWK_OFFLINE;
                    printf("afSendData error %02X; restarting...\r\n", result);
                    delayMs(RESTART_DELAY_IF_MESSAGE_FAIL_MS);  //allow enough time for coordinator to fully restart, if that caused our problem
                    state = STATE_MODULE_STARTUP;
                } else {   
                    printf("Success\r\n");
                    state = STATE_IDLE;
                }
                break;   
            }
        default:     //should never happen
            {
                printf("UNKNOWN STATE\r\n");
                state = STATE_MODULE_STARTUP;
            }
            break;
        }
    } 
}
/**
Start the Module and join a network, using the AF/ZDO interface. Reads RF Operating Region (US/EU) from GPIO.
@param moduleConfiguration the settings to use to start the module
@param applicationConfiguration the settings to use to start the Zigbee Application
@see struct moduleConfiguration in module_utilities.h for information about each field of the moduleConfiguration
@see struct applicationConfiguration in application_configuration.h for information about each field of the applicationConfiguration
@see module.c for more information about each of these steps.
*/
moduleResult_t startModule(const struct moduleConfiguration* mc, const struct applicationConfiguration* ac)
{
	printf("Module Startup\r\n");
    /* Initialize the Module */
    RETURN_RESULT_IF_FAIL(moduleReset(), METHOD_START_MODULE);
    /* Clear out any old network or state information (if requested) */
    RETURN_RESULT_IF_FAIL(setStartupOptions(mc->startupOptions), METHOD_START_MODULE);   

/* This section is for reading Operating region from GPIO pins - omit if using different method */
    /* First, configure GPIOs as inputs: */
    RETURN_RESULT_IF_FAIL(sysGpio(GPIO_SET_DIRECTION , GPIO_DIRECTION_ALL_INPUTS), METHOD_START_MODULE);    
    RETURN_RESULT_IF_FAIL(sysGpio(GPIO_SET_INPUT_MODE , GPIO_INPUT_MODE_ALL_PULL_UPS), METHOD_START_MODULE); 
    /* Now, read GPIO inputs 0 & 1: */
    RETURN_RESULT_IF_FAIL(sysGpio(GPIO_READ, (GPIO_0 | GPIO_1)), METHOD_START_MODULE);
    /* The operating region (US vs. EU etc.) is based on DIP Switch settings, read from GPIO 0 & 1 */
    uint16_t moduleRegion = zmBuf[SYS_GPIO_READ_RESULT_FIELD];
    
/*** Done reading GPIO inputs. If application needs them as outputs then configure accordingly ***/
    
    /* Reset the Module to apply the changes we just set */
    RETURN_RESULT_IF_FAIL(moduleReset(), METHOD_START_MODULE);
    /* Read the productId - this indicates the model of module used. */
    uint8_t productId = zmBuf[SYS_RESET_IND_PRODUCTID_FIELD]; 
    /* If this is not valid (bad firmware) then stop */
    RETURN_RESULT_IF_EXPRESSION_TRUE((productId < MINIMUM_BUILD_ID), METHOD_START_MODULE,
                                     ZM_INVALID_MODULE_CONFIGURATION);       
    /* Configure the module's RF output */
    setModuleRfPower(productId, moduleRegion);
    /* Set any end device options */
    if (mc->deviceType == END_DEVICE)
	    RETURN_RESULT_IF_FAIL(setPollRate(mc->endDevicePollRate), METHOD_START_MODULE);
    /* Configure which RF Channels to use. If none set then this will default to 11. */
    RETURN_RESULT_IF_FAIL(setZigbeeDeviceType(mc->deviceType), METHOD_START_MODULE);     // Set Zigbee Device Type
    RETURN_RESULT_IF_FAIL(setChannelMask(mc->channelMask), METHOD_START_MODULE);
    RETURN_RESULT_IF_FAIL(setPanId(mc->panId), METHOD_START_MODULE);
    RETURN_RESULT_IF_FAIL(setCallbacks(CALLBACKS_ENABLED), METHOD_START_MODULE);
    
	                                                    // Note: ZCD_NV_SECURITY_MODE defaults to 01
	  if (mc->securityMode != SECURITY_MODE_OFF)        // Note: If a coordinator has ZCD_NV_SECURITY_MODE = 00, router must have ZCD_NV_SECURITY_MODE = 01 or else they won't communicate
	  {
	      RETURN_RESULT_IF_FAIL(setSecurityMode(mc->securityMode), METHOD_START_MODULE);
	      RETURN_RESULT_IF_FAIL(setSecurityKey(mc->securityKey), METHOD_START_MODULE);
	  }

	  if (ac == GENERIC_APPLICATION_CONFIGURATION)	  //TODO: use custom applicationFramework if this isn't null:
	  {
	    RETURN_RESULT_IF_FAIL(afRegisterGenericApplication(), METHOD_START_MODULE);    // Configure the Module for our application
	  } else {
	    printf("Custom Application Frameworks not supported\r\n");
	    return INVALID_PARAMETER;
	  }
	  RETURN_RESULT_IF_FAIL(zdoStartApplication(), METHOD_START_MODULE);		// Start your engines

	  /* Wait until this device has joined a network. Device State will change to DEV_ROUTER,
      DEV_END_DEVICE, or DEV_COORD to indicate that the device has correctly joined a network. */

	#ifdef ZDO_STATE_CHANGE_IND_HANDLED_BY_APPLICATION  //if you're handling this in your application instead...
	  return MODULE_SUCCESS;
	#else
	#define TEN_SECONDS 10000
	#define FIFTEEN_SECONDS 15000
	#define START_TIMEOUT FIFTEEN_SECONDS
	  RETURN_RESULT(waitForDeviceState(getDeviceStateForDeviceType(mc->deviceType), START_TIMEOUT), METHOD_START_MODULE);
	#endif

}
/** 
The main state machine for the application.
Never exits.
*/
void stateMachine()
{
 //   while (1)
  //  {
        if (zigbeeNetworkStatus == NWK_ONLINE)
        {
            if(moduleHasMessageWaiting())      //wait until SRDY goes low indicating a message has been received. 
                stateFlags |= STATE_FLAG_MESSAGE_WAITING;
        }
        
        switch (state)
        {
        case STATE_IDLE:
            {
                if (stateFlags & STATE_FLAG_MESSAGE_WAITING & coordinator_on)    // If there is a message waiting...
                {
                    parseMessages();                            // ... then display it
                    trackingStateMachine(current_router_index);
                    stateFlags &= ~STATE_FLAG_MESSAGE_WAITING;
                }
                
                if (stateFlags & STATE_FLAG_BUTTON_PRESSED)     // If ISR set this flag...
                {
                    if (debounceButton(ANY_BUTTON))             // ...then debounce it
                    {
                        processButtonPress();                   // ...and process it
                    }
                    if (debounceButtonHold(ANY_BUTTON))
                    {
                        processButtonHold();
                    }
                    stateFlags &= ~STATE_FLAG_BUTTON_PRESSED;
                }
                
                /* Other flags (for different messages or events) can be added here */
                break;
            }
            
        case STATE_MODULE_STARTUP:              // Start the Zigbee Module on the network
            {
#define MODULE_START_DELAY_IF_FAIL_MS 5000
                moduleResult_t result;
                struct moduleConfiguration defaultConfiguration = DEFAULT_MODULE_CONFIGURATION_COORDINATOR;
                
                /* Uncomment below to restrict the device to a specific PANID
                defaultConfiguration.panId = 0x1234;
                */
                
                /* Below is an example of how to restrict the device to only one channel:
                defaultConfiguration.channelMask = CHANNEL_MASK_17;
                printf("DEMO - USING CUSTOM CHANNEL 17\r\n");
                */
                
                while ((result = startModule(&defaultConfiguration, GENERIC_APPLICATION_CONFIGURATION)) != MODULE_SUCCESS)
                {
                    printf("FAILED. Error Code 0x%02X. Retrying...\r\n", result);
                    delayMs(MODULE_START_DELAY_IF_FAIL_MS);
                }
                //printf("Success\r\n");
                zigbeeNetworkStatus = NWK_ONLINE;
                
                state = STATE_DISPLAY_NETWORK_INFORMATION;
                break;
            }
        case STATE_DISPLAY_NETWORK_INFORMATION:
            {
                printf("~ni~");
                /* On network, display info about this network */
                displayNetworkConfigurationParameters();
                displayDeviceInformation();
                if (sysGpio(GPIO_SET_DIRECTION, ALL_GPIO_PINS) != MODULE_SUCCESS)   //Set module GPIOs as output
                {
                    printf("ERROR\r\n");
                }
                /*
                printf("Press button to change which received value is displayed on RGB LED. D6 & D5 will indicate mode:\r\n");
                printf("    None = None\r\n");
                printf("    Yellow (D9) = IR Temp Sensor\r\n");
                printf("    Red (D8) = Color Sensor\r\n");
                */
                printf("Displaying Messages Received\r\n");
                setModuleLeds(RGB_LED_DISPLAY_MODE_NONE);
                
                /* Now the network is running - wait for any received messages from the ZM */
#ifdef VERBOSE_MESSAGE_DISPLAY    
                printAfIncomingMsgHeaderNames();
#endif                
                state = STATE_IDLE;
                break;
            }
            
        default:     //should never happen
            {
                printf("UNKNOWN STATE\r\n");
                state = STATE_MODULE_STARTUP;
            }
            break;
        }
 //   } 
}    
Esempio n. 5
0
void sendcmd(unsigned char * req, unsigned char cmdtype){
	switch (cmdtype)
	{
	case 0:
		sysPing();
		break;
	case 1:
		sysSetExtAddr((SetExtAddrFormat_t*) req);
		break;
	case 2:
		sysGetExtAddr();
		break;
	case 3:
		sysRamRead((RamReadFormat_t*) req);
		break;
	case 4:
		sysRamWrite((RamWriteFormat_t*) req);
		break;
	case 5:
		sysResetReq((ResetReqFormat_t*) req);
		break;
	case 6:
		sysVersion();
		break;
	case 7:
		sysOsalNvRead((OsalNvReadFormat_t*) req);
		break;
	case 8:
		sysOsalNvWrite((OsalNvWriteFormat_t*) req);
		break;
	case 9:
		sysOsalNvItemInit((OsalNvItemInitFormat_t*) req);
		break;
	case 10:
		sysOsalNvDelete((OsalNvDeleteFormat_t*) req);
		break;
	case 11:
		sysOsalNvLength((OsalNvLengthFormat_t*) req);
		break;
	case 12:
		sysOsalStartTimer((OsalStartTimerFormat_t*) req);
		break;
	case 13:
		sysOsalStopTimer((OsalStopTimerFormat_t*) req);
		break;
	case 14:
		sysStackTune((StackTuneFormat_t*) req);
		break;
	case 15:
		sysAdcRead((AdcReadFormat_t*) req);
		break;
	case 16:
		sysGpio((GpioFormat_t*) req);
		break;
	case 17:
		sysRandom();
		break;
	case 18:
		sysSetTime((SetTimeFormat_t*) req);
		break;
	case 19:
		sysGetTime();
		break;
	case 20:
		sysSetTxPower((SetTxPowerFormat_t*) req);
		break;
	case 21:
		afRegister((RegisterFormat_t*) req);
		break;
	case 22:
		afDataRequest((DataRequestFormat_t*) req);
		break;
	case 23:
		afDataRequestExt((DataRequestExtFormat_t*) req);
		break;
	case 24:
		afDataRequestSrcRtg((DataRequestSrcRtgFormat_t*) req);
		break;
	case 25:
		afInterPanCtl((InterPanCtlFormat_t*) req);
		break;
	case 26:
		afDataStore((DataStoreFormat_t*) req);
		break;
	case 27:
		afDataRetrieve((DataRetrieveFormat_t*) req);
		break;
	case 28:
		afApsfConfigSet((ApsfConfigSetFormat_t*) req);
		break;
	case 29:
		zdoNwkAddrReq((NwkAddrReqFormat_t*) req);
		break;
	case 30:
		zdoIeeeAddrReq((IeeeAddrReqFormat_t*) req);
		break;
	case 31:
		zdoNodeDescReq((NodeDescReqFormat_t*) req);
		break;
	case 32:
		zdoPowerDescReq((PowerDescReqFormat_t*) req);
		break;
	case 33:
		zdoSimpleDescReq((SimpleDescReqFormat_t*) req);
		break;
	case 34:
		zdoActiveEpReq((ActiveEpReqFormat_t*) req);
		break;
	case 35:
		zdoMatchDescReq((MatchDescReqFormat_t*) req);
		break;
	case 36:
		zdoComplexDescReq((ComplexDescReqFormat_t*) req);
		break;
	case 37:
		zdoUserDescReq((UserDescReqFormat_t*) req);
		break;
	case 38:
		zdoDeviceAnnce((DeviceAnnceFormat_t*) req);
		break;
	case 39:
		zdoUserDescSet((UserDescSetFormat_t*) req);
		break;
	case 40:
		zdoServerDiscReq((ServerDiscReqFormat_t*) req);
		break;
	case 41:
		zdoEndDeviceBindReq((EndDeviceBindReqFormat_t*) req);
		break;
	case 42:
		zdoBindReq((BindReqFormat_t*) req);
		break;
	case 43:
		zdoUnbindReq((UnbindReqFormat_t*) req);
		break;
	case 44:
		zdoMgmtNwkDiscReq((MgmtNwkDiscReqFormat_t*) req);
		break;
	case 45:
		zdoMgmtLqiReq((MgmtLqiReqFormat_t*) req);
		break;
	case 46:
		zdoMgmtRtgReq((MgmtRtgReqFormat_t*) req);
		break;
	case 47:
		zdoMgmtBindReq((MgmtBindReqFormat_t*) req);
		break;
	case 48:
		zdoMgmtLeaveReq((MgmtLeaveReqFormat_t*) req);
		break;
	case 49:
		zdoMgmtDirectJoinReq((MgmtDirectJoinReqFormat_t*) req);
		break;
	case 50:
		zdoMgmtPermitJoinReq((MgmtPermitJoinReqFormat_t*) req);
		break;
	case 51:
		zdoMgmtNwkUpdateReq((MgmtNwkUpdateReqFormat_t*) req);
		break;
	case 52:
		zdoStartupFromApp((StartupFromAppFormat_t*) req);
		break;
	case 53:
		zdoAutoFindDestination((AutoFindDestinationFormat_t*) req);
		break;
	case 54:
		zdoSetLinkKey((SetLinkKeyFormat_t*) req);
		break;
	case 55:
		zdoRemoveLinkKey((RemoveLinkKeyFormat_t*) req);
		break;
	case 56:
		zdoGetLinkKey((GetLinkKeyFormat_t*) req);
		break;
	case 57:
		zdoNwkDiscoveryReq((NwkDiscoveryReqFormat_t*) req);
		break;
	case 58:
		zdoJoinReq((JoinReqFormat_t*) req);
		break;
	case 59:
		zdoMsgCbRegister((MsgCbRegisterFormat_t*) req);
		break;
	case 60:
		zdoMsgCbRemove((MsgCbRemoveFormat_t*) req);
		break;
	case 61:
		zbSystemReset();
		break;
	case 62:
		zbAppRegisterReq((AppRegisterReqFormat_t*) req);
		break;
	case 63:
		zbStartReq();
		break;
	case 64:
		zbPermitJoiningReq((PermitJoiningReqFormat_t*) req);
		break;
	case 65:
		zbBindDevice((BindDeviceFormat_t*) req);
		break;
	case 66:
		zbAllowBind((AllowBindFormat_t*) req);
		break;
	case 67:
		zbSendDataReq((SendDataReqFormat_t*) req);
		break;
	case 68:
		zbFindDeviceReq((FindDeviceReqFormat_t*) req);
		break;
	case 69:
		zbWriteConfiguration((WriteConfigurationFormat_t*) req);
		break;
	case 70:
		zbGetDeviceInfo((GetDeviceInfoFormat_t*) req);
		break;
	case 71:
		zbReadConfiguration((ReadConfigurationFormat_t*) req);
		break;

	}

}