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