예제 #1
0
/*********************************************************************
 * @fn      zllSampleLight_HandleKeys
 *
 * @brief   Handles all key events for this device.
 *
 * @param   shift - true if in shift/alt.
 * @param   keys - bit field for key events.
 *
 * @return  none
 */
static void zllSampleLight_HandleKeys( byte shift, byte keys )
{
  (void)shift;  // Intentionally unreferenced parameter
#ifdef HAL_BOARD_ZLIGHT
  // Zlight has only a single button
  static uint32 keyPressTime = 0;
  if ( keys )
  {
    keyPressTime = osal_getClock();
  }
  else //key released
  {
    if ( keyPressTime )
    {
      keyPressTime = ( osal_getClock() - keyPressTime );
      if ( keyPressTime <= KEY_HOLD_SHORT_INTERVAL )
      {
        zllTarget_PermitJoin( PERMIT_JOIN_DURATION );
      }
      else if ( keyPressTime > KEY_HOLD_LONG_INTERVAL )
      {
        zllTarget_ClassicalCommissioningStart();
      }
      else
      {
        zllTarget_ResetToFactoryNew();
      }
      keyPressTime = 0;
    }
  }
#else //HAL_BOARD_CC2530EB ?
  if ( keys & CLASSIC_COMMISS_KEY )
  {
    zllTarget_ClassicalCommissioningStart();
  }

  if ( keys & FACTORY_RESET_KEY )
  {
    zllTarget_ResetToFactoryNew();
  }

  if ( keys & PERMIT_JOIN_KEY )
  {
    zllTarget_PermitJoin( PERMIT_JOIN_DURATION );
    HalLcdWriteString( "PermitJoin", HAL_LCD_LINE_3 );
  }

  if ( keys & DISPLAY_NWK_KEY_KEY )
  {
#if ( HAL_LCD == TRUE )
    zllSampleLight_PrintNwkKey( FALSE );
#endif //( HAL_LCD == TRUE )
  }

#endif //HAL_BOARD_ZLIGHT
}
예제 #2
0
/*********************************************************************
 * @fn      thermometerMeasIndicate
 *
 * @brief   Prepare and send a thermometer measurement notification
 *
 * @return  none
 */
static void thermometerMeasIndicate(void)
{

    // att value notification structure
    uint8 *p = thermometerMeas.value;

    // temperature
    uint32 temperature;

    //flags
    uint8 flags = thermometerFlags[thermometerFlagsIdx];

    // flags 1 byte long
    *p++ = flags;

    if(flags & THERMOMETER_FLAGS_FARENHEIT)
    {
        temperature =  (thermometerCelcius *9/5) +320;
    }
    else
    {
        temperature = thermometerCelcius;
    }

    temperature = 0xFF000000 | temperature;

    //osal_buffer_uint32
    osal_buffer_uint32( p, temperature );

    //temperature is 4 bytes long
    *p++;
    *p++;
    *p++;
    *p++;

    //timestamp
    if (flags & THERMOMETER_FLAGS_TIMESTAMP)
    {

        UTCTimeStruct time;

        // Get time structure from OSAL
        osal_ConvertUTCTime( &time, osal_getClock() );

        *p++ = (time.year & 0x00FF);
        *p++ = (time.year & 0xFF00)>>8;
        //*p++ = time.year;
        //*p++;

        *p++=time.month;
        *p++=time.day;
        *p++=time.hour;
        *p++=time.minutes;
        *p++=time.seconds;
    }
예제 #3
0
파일: thermometer.c 프로젝트: yzkqfll/ibaby
static void encap_picture_param(struct ther_info *ti, struct display_param *param)
{
	unsigned short time;
	UTCTimeStruct utc;

	osal_ConvertUTCTime(&utc, osal_getClock() - ti->start_sec);
	time = ((unsigned short)utc.hour << 8) | utc.minutes;

	param->time = time;
	param->batt_percentage = ti->batt_percentage;
	param->ble_link = ti->ble_connect;
	param->temp = ti->temp_current;
	param->max_temp = ti->temp_max;
}
/***************************************************************************************************
 * @fn      MT_SysGetUtcTime
 *
 * @brief   Get the OSAL UTC time
 *
 * @param   None
 *
 * @return  32-bit and Parsed UTC time
 ***************************************************************************************************/
void MT_SysGetUtcTime(void)
{
  uint8 len;
  uint8 *buf;

  len = sizeof( UTCTime ) + sizeof( UTCTimeStruct );

  buf = osal_mem_alloc( len );
  if ( buf )
  {
    uint8 *pBuf;
    UTCTime utcSecs;
    UTCTimeStruct utcTime;

    // Get current 32-bit UTC time and parse it
    utcSecs = osal_getClock();
    osal_ConvertUTCTime( &utcTime, utcSecs );

    // Start with 32-bit UTC time
    pBuf = osal_buffer_uint32( buf, utcSecs );

    // Concatenate parsed UTC time fields
    *pBuf++ = utcTime.hour;
    *pBuf++ = utcTime.minutes;
    *pBuf++ = utcTime.seconds;
    *pBuf++ = utcTime.month + 1;  // Convert to human numbers
    *pBuf++ = utcTime.day + 1;
    *pBuf++ = LO_UINT16( utcTime.year );
    *pBuf++ = HI_UINT16( utcTime.year );

    /* Build and send back the response */
    MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS),
                                   MT_SYS_GET_TIME, (uint8)(pBuf-buf), buf);

    osal_mem_free( buf );
  }
}
예제 #5
0
/*********************************************************************
 * @fn          loadcontrol_event_loop
 *
 * @brief       Event Loop Processor for loadcontrol.
 *
 * @param       uint8 task id - load control task id
 * @param       uint16 events - event bitmask
 *
 * @return      none
 */
uint16 loadcontrol_event_loop( uint8 task_id, uint16 events )
{
  afIncomingMSGPacket_t *MSGpkt;

  if ( events & SYS_EVENT_MSG )
  {
    while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( loadControlTaskID )) )
    {
      switch ( MSGpkt->hdr.event )
      {
        case ZCL_INCOMING_MSG:
          // Incoming ZCL foundation command/response messages
          loadcontrol_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt );
          break;

        case KEY_CHANGE:
          loadcontrol_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
          break;

        case ZDO_STATE_CHANGE:
          if (DEV_ROUTER == (devStates_t)(MSGpkt->hdr.status))
          {
#if SECURE
            {
              // check to see if link key had already been established
              linkKeyStatus = loadcontrol_KeyEstablish_ReturnLinkKey(ESPAddr.addr.shortAddr);

              if (linkKeyStatus != ZSuccess)
              {
                // send out key establishment request
                osal_set_event( loadControlTaskID, LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT);
              }
            }
#endif
          }
          break;

        default:
          break;
      }

      // Release the memory
      osal_msg_deallocate( (uint8 *)MSGpkt );
    }

    // return unprocessed events
    return (events ^ SYS_EVENT_MSG);
  }

  // event to intiate key establishment request
  if ( events & LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT )
  {
    zclGeneral_KeyEstablish_InitiateKeyEstablishment(loadControlTaskID, &ESPAddr, loadControlTransID);

    return ( events ^ LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT );
  }

  // handle processing of identify timeout event triggered by an identify command
  if ( events & LOADCONTROL_IDENTIFY_TIMEOUT_EVT )
  {
    if ( loadControlIdentifyTime > 0 )
    {
      loadControlIdentifyTime--;
    }
    loadcontrol_ProcessIdentifyTimeChange();

    return ( events ^ LOADCONTROL_IDENTIFY_TIMEOUT_EVT );
  }

  // event to get current time
  if ( events & LOADCONTROL_UPDATE_TIME_EVT )
  {
    loadControlTime = osal_getClock();
    osal_start_timerEx( loadControlTaskID, LOADCONTROL_UPDATE_TIME_EVT, LOADCONTROL_UPDATE_TIME_PERIOD );

    return ( events ^ LOADCONTROL_UPDATE_TIME_EVT );
  }

  // event to handle load control complete event
  if ( events & LOADCONTROL_LOAD_CTRL_EVT )
  {
    // load control evt completed

    // Send response back
    // DisableDefaultResponse is set to false - it is recommended to turn on
    // default response since Report Event Status Command does not have
    // a response.
    rsp.eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_COMPLETED;
    zclSE_LoadControl_Send_ReportEventStatus( LOADCONTROL_ENDPOINT, &ESPAddr,
                                            &rsp, false, loadControlTransID );

    HalLcdWriteString("Load Evt Complete", HAL_LCD_LINE_3);

    HalLedSet(HAL_LED_4, HAL_LED_MODE_OFF);

    return ( events ^ LOADCONTROL_LOAD_CTRL_EVT );

  }

  // Discard unknown events
  return 0;
}
예제 #6
0
파일: thermometer.c 프로젝트: yzkqfll/ibaby
static void ther_handle_ps_event(unsigned char event, unsigned char *data, unsigned char *len)
{
	struct ther_info *ti = &ther_info;
	UTCTimeStruct utc;
	uint16 high_temp_threshold;

	switch (event) {
	case THER_PS_GET_WARNING_ENABLED:
		*data = ti->warning_enabled;
		*len = 1;
		print(LOG_DBG, MODULE "get warning enabled: %d\n", *data);
		break;

	case THER_PS_SET_WARNING_ENABLED:
		ti->warning_enabled = *data;
		print(LOG_DBG, MODULE "set warning enabled: %d\n", *data);
		break;

	case THER_PS_CLEAR_WARNING:
		print(LOG_DBG, MODULE "clear warning: %d\n", *data);
		ther_clear_high_temp_warning(ti);
		break;

	case THER_PS_GET_HIGH_WARN_TEMP:
		memcpy(data, &ti->high_temp_threshold, sizeof(ti->high_temp_threshold));
		*len = sizeof(ti->high_temp_threshold);
		print(LOG_DBG, MODULE "get high temp: %d\n", *(unsigned short *)data);
		break;

	case THER_PS_SET_HIGH_WARN_TEMP:
		memcpy(&high_temp_threshold, data, sizeof(high_temp_threshold));

		if (storage_write_high_temp_threshold(high_temp_threshold)) {
			print(LOG_DBG, MODULE "set high temp: %d\n", high_temp_threshold);
			ti->high_temp_threshold = high_temp_threshold;
			ti->next_warning_threshold = ti->high_temp_threshold;
		} else {
			print(LOG_DBG, MODULE "set high temp: %d failed\n", high_temp_threshold);
		}

		break;

	case THER_PS_GET_TIME:
		osal_ConvertUTCTime(&utc, osal_getClock());

		memcpy(data, &utc, sizeof(utc));
		*len = sizeof(utc);
		print(LOG_DBG, MODULE "get time: %d-%02d-%02d %02d:%02d:%02d\n",
				utc.year, utc.month, utc.day, utc.hour, utc.minutes, utc.seconds);
		break;

	case THER_PS_SET_TIME:
		memcpy(&utc, data, sizeof(utc));
		osal_setClock(osal_ConvertUTCSecs(&utc));
		print(LOG_DBG, MODULE "set time: %d-%02d-%02d %02d:%02d:%02d\n",
				utc.year, utc.month, utc.day, utc.hour, utc.minutes, utc.seconds);

		ti->start_sec = osal_ConvertUTCSecs(&utc);
		break;

	case THER_PS_GET_DEBUG:
		{
			ti->mode = CAL_MODE;
			/*
			 * stop temp measurement
			 */
			osal_stop_timerEx(ti->task_id, TH_TEMP_MEASURE_EVT);
			ther_temp_power_on();
			ti->temp_measure_stage = TEMP_STAGE_SETUP;

			/*
			 * stop batt measurement
			 */
			osal_stop_timerEx(ti->task_id, TH_BATT_EVT);
		}
		*(unsigned short *)data = ther_get_hw_adc(HAL_ADC_CHANNEL_0, FROM_CUSTOM);
		*len = 2;
		break;

	case THER_PS_SET_DEBUG:
		break;

	default:
		*len = 0;
		break;
	}
}
예제 #7
0
/*********************************************************************
 * @fn      thermometerMeasIndicate
 *
 * @brief   Prepare and send a thermometer measurement indication
 *
 * @return  none
 */
static void thermometerMeasIndicate(void)
{
    // Thermometer measurement value stored in this structure.
    attHandleValueInd_t thermometerMeas;

    thermometerMeas.pValue = GATT_bm_alloc(gapConnHandle,
                                           ATT_HANDLE_VALUE_IND,
                                           THERMOMETER_MEAS_LEN, NULL);
    if (thermometerMeas.pValue != NULL)
    {
        // att value notification structure
        uint8 *p = thermometerMeas.pValue;

        // temperature
        uint32 temperature;

        //flags
        uint8 flags = thermometerFlags[thermometerFlagsIdx];

        // flags 1 byte long
        *p++ = flags;

        if(flags & THERMOMETER_FLAGS_FARENHEIT)
        {
            temperature =  (thermometerCelcius *9/5) +320;
        }
        else
        {
            temperature = thermometerCelcius;
        }

        temperature = 0xFF000000 | temperature;

        //osal_buffer_uint32
        p = osal_buffer_uint32( p, temperature );

        //timestamp
        if (flags & THERMOMETER_FLAGS_TIMESTAMP)
        {
            UTCTimeStruct time;

            // Get time structure from OSAL
            osal_ConvertUTCTime( &time, osal_getClock() );

            *p++ = LO_UINT16(time.year);
            *p++ = HI_UINT16(time.year);
            *p++ = time.month;
            *p++ = time.day;
            *p++ = time.hour;
            *p++ = time.minutes;
            *p++ = time.seconds;
        }

        if(flags & THERMOMETER_FLAGS_TYPE)
        {
            uint8 site;
            Thermometer_GetParameter( THERMOMETER_TYPE, &site );
            *p++ =  site;
        }

        thermometerMeas.len = (uint8) (p - thermometerMeas.pValue);
        thermometerMeas.handle = THERMOMETER_TEMP_VALUE_POS;

        // Queue indication.
        thermometerStoreIndications( &thermometerMeas);

        //advertise measurement is ready
        thermometer_Advertise();
    }
}
예제 #8
0
/*********************************************************************
 * @fn      thermometerMeasNotify
 *
 * @brief   Prepare and send a thermometer measurement notification
 *
 * @return  none
 */
static void thermometerImeasNotify(void)
{
    if (temperatureIMeasCharConfig == true)
    {
        attHandleValueNoti_t thermometerIMeas;

        thermometerIMeas.pValue = GATT_bm_alloc( gapConnHandle,
                                  ATT_HANDLE_VALUE_NOTI,
                                  THERMOMETER_IMEAS_LEN, NULL );
        if ( thermometerIMeas.pValue != NULL )
        {
            // att value notification structure
            uint8 *p = thermometerIMeas.pValue;

            // temperature
            uint32 temperature;

            //flags
            uint8 flags = thermometerFlags[thermometerFlagsIdx];

            // flags 1 byte long
            *p++ = flags;

            if(flags & THERMOMETER_FLAGS_FARENHEIT)
            {
                temperature =  (thermometerCelcius *9/5) +320;
            }
            else
            {
                temperature = thermometerCelcius;
            }

            temperature = 0xFF000000 | temperature;

            //osal_buffer_uint32
            p = osal_buffer_uint32( p, temperature );

            //timestamp
            if (flags & THERMOMETER_FLAGS_TIMESTAMP)
            {
                UTCTimeStruct time;

                // Get time structure from OSAL
                osal_ConvertUTCTime( &time, osal_getClock() );

                *p++ = LO_UINT16(time.year);
                *p++ = HI_UINT16(time.year);
                *p++ = time.month;
                *p++ = time.day;
                *p++ = time.hour;
                *p++ = time.minutes;
                *p++ = time.seconds;
            }

            if(flags & THERMOMETER_FLAGS_TYPE)
            {
                uint8 site;
                Thermometer_GetParameter( THERMOMETER_TYPE, &site );
                *p++ =  site;
            }

            thermometerIMeas.len = (uint8) (p - thermometerIMeas.pValue);

            if ( Thermometer_IMeasNotify( gapConnHandle, &thermometerIMeas) != SUCCESS )
            {
                GATT_bm_free( (gattMsg_t *)&thermometerIMeas, ATT_HANDLE_VALUE_NOTI );
            }
        }
    }
}
예제 #9
0
/*********************************************************************
 * @fn      bpFinalMeas
 *
 * @brief   Prepare and send a bloodPressure measurement indication
 *
 * @return  none
 */
static void bpFinalMeas(void)
{
    
  // att value notification structure 
  uint8 *p = bloodPressureMeas.value;
  
  //flags
  uint8 flags = bloodPressureFlags[bloodPressureFlagsIdx];
  
  // flags 1 byte long
  *p++ = flags;

  //bloodpressure components
  *p++ = bpSystolic;
  *p++;
  *p++ = bpDiastolic;
  *p++;
  *p++ = bpMAP;
  *p++;
  
  //timestamp
  if (flags & BLOODPRESSURE_FLAGS_TIMESTAMP)
  {
   
    UTCTimeStruct time;
  
    // Get time structure from OSAL
    osal_ConvertUTCTime( &time, osal_getClock() );
      
    *p++ = 0x07;
    *p++ = 0xdb;
    *p++=time.month;    
    *p++=time.day;  
    *p++=time.hour;    
    *p++=time.minutes;    
    *p++=time.seconds;   
  }
  
  if(flags & BLOODPRESSURE_FLAGS_PULSE)
  {
    *p++ =  bpPulseRate;
    *p++;    
  }
 
    if(flags & BLOODPRESSURE_FLAGS_USER)
  {
    *p++ =  bpUserId;    
  }

    if(flags & BLOODPRESSURE_FLAGS_STATUS)
  {
    *p++ =  bpMeasStatus;   
    *p++;
  }
  
  bloodPressureMeas.len = (uint8) (p - bloodPressureMeas.value);
  
  //store measurment
  bpStoreIndications(&bloodPressureMeas);   

  //send stored measurements
  bpSendStoredMeas();
  
  //start disconnect timer
  osal_start_timerEx( bloodPressureTaskId, BP_DISCONNECT_EVT, BP_DISCONNECT_PERIOD );    
  
}
예제 #10
0
/*********************************************************************
 * @fn          loadcontrol_event_loop
 *
 * @brief       Event Loop Processor for loadcontrol.
 *
 * @param       uint8 task id - load control task id
 * @param       uint16 events - event bitmask
 *
 * @return      none
 */
uint16 loadcontrol_event_loop( uint8 task_id, uint16 events )
{
  afIncomingMSGPacket_t *MSGpkt;

  if ( events & SYS_EVENT_MSG )
  {
    while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( loadControlTaskID )) )
    {
      switch ( MSGpkt->hdr.event )
      {
        case ZDO_CB_MSG:
          loadcontrol_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
          break;

        case ZCL_INCOMING_MSG:
          // Incoming ZCL foundation command/response messages
          loadcontrol_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt );
          break;

        case KEY_CHANGE:
          loadcontrol_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
          break;

        case ZDO_STATE_CHANGE:
          if (DEV_ROUTER == (devStates_t)(MSGpkt->hdr.status))
          {
#if SECURE
            {
              // check to see if link key had already been established
              linkKeyStatus = loadcontrol_KeyEstablish_ReturnLinkKey(ESPAddr.addr.shortAddr);

              if (linkKeyStatus != ZSuccess)
              {
                cId_t cbkeCluster = ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT;
                zAddrType_t dstAddr;

                // Send out a match for the key establishment
                dstAddr.addrMode = AddrBroadcast;
                dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
                ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR, ZCL_SE_PROFILE_ID,
                                  1, &cbkeCluster, 0, NULL, FALSE );
              }
            }
#endif
          }
          break;

#if defined( ZCL_KEY_ESTABLISH )
        case ZCL_KEY_ESTABLISH_IND:
          if ((MSGpkt->hdr.status) == TermKeyStatus_Success)
          {
            ESPAddr.endPoint = LOADCONTROL_ENDPOINT; // set destination endpoint back to application endpoint
          }

          break;
#endif

        default:
          break;
      }

      // Release the memory
      osal_msg_deallocate( (uint8 *)MSGpkt );
    }

    // return unprocessed events
    return (events ^ SYS_EVENT_MSG);
  }

  // event to intiate key establishment request
  if ( events & LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT )
  {
    zclGeneral_KeyEstablish_InitiateKeyEstablishment(loadControlTaskID, &ESPAddr, loadControlTransID);

    return ( events ^ LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT );
  }

  // handle processing of identify timeout event triggered by an identify command
  if ( events & LOADCONTROL_IDENTIFY_TIMEOUT_EVT )
  {
    if ( loadControlIdentifyTime > 0 )
    {
      loadControlIdentifyTime--;
    }
    loadcontrol_ProcessIdentifyTimeChange();

    return ( events ^ LOADCONTROL_IDENTIFY_TIMEOUT_EVT );
  }

  // event to get current time
  if ( events & LOADCONTROL_UPDATE_TIME_EVT )
  {
    loadControlTime = osal_getClock();
    osal_start_timerEx( loadControlTaskID, LOADCONTROL_UPDATE_TIME_EVT, LOADCONTROL_UPDATE_TIME_PERIOD );

    return ( events ^ LOADCONTROL_UPDATE_TIME_EVT );
  }

  // event to handle load control complete event
  if ( events & LOADCONTROL_LOAD_CTRL_EVT )
  {
    // load control evt completed

    // Send response back
    // DisableDefaultResponse is set to FALSE - it is recommended to turn on
    // default response since Report Event Status Command does not have
    // a response.
    rsp.eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_COMPLETED;
    zclSE_LoadControl_Send_ReportEventStatus( LOADCONTROL_ENDPOINT, &ESPAddr,
                                            &rsp, FALSE, loadControlTransID );

    HalLcdWriteString("Load Evt Complete", HAL_LCD_LINE_3);

    HalLedSet(HAL_LED_4, HAL_LED_MODE_OFF);

    return ( events ^ LOADCONTROL_LOAD_CTRL_EVT );

  }

  // Discard unknown events
  return 0;
}
예제 #11
0
파일: os.c 프로젝트: JBtje/BlueBasic
long OS_get_millis(void)
{
  osalTimeUpdate();
  return osal_getClock() * 1000 + osal_getMSClock();
}
예제 #12
0
static void sensorTag_ClockGet(UTCTimeStruct *t, UTCTime delta)
{
	osal_ConvertUTCTime(t, osal_getClock() - delta);
}
예제 #13
0
uint16 SensorTag_ProcessEvent(uint8 task_id, uint16 events)
{
	VOID	task_id;	// OSAL required parameter that isn't used in this function


	///////////////////////////////////////////////////////////////////////
	// system event handle                                               //
	///////////////////////////////////////////////////////////////////////
	if (events & SYS_EVENT_MSG) {
		uint8	*msg;

		if ((msg = osal_msg_receive(sensorTag_TaskID)) != NULL) {
			sensorTag_ProcessOSALMsg((osal_event_hdr_t *) msg);

			// release the OSAL message
			osal_msg_deallocate(msg);
		}

		// return unprocessed events
		return (events ^ SYS_EVENT_MSG);
	}


	///////////////////////////////////////////////////////////////////////
	// start device event                                                //
	///////////////////////////////////////////////////////////////////////
	if (events & EVT_START_DEVICE) {
		// start the device
		GAPRole_StartDevice(&sensorTag_PeripheralCBs);

		// start bond manager
#if !defined(GAPBONDMGR_NO_SUPPORT)
		GAPBondMgr_Register(&sensorTag_BondMgrCBs);
#endif
		// start peripheral device
		oled_init();
		adxl345_softrst();
//		adxl345_self_calibration();

		steps	     = 0;
		BATCD_PXIFG  = ~(BATCD_BV);
		BATCD_IEN   |=  BATCD_IENBIT;

		osal_start_reload_timer(sensorTag_TaskID, EVT_RTC, PERIOD_RTC);
		pwmgr_state_change(PWMGR_S0, 0);

		fmsg(("\033[40;32m\n[power on]\033[0m\n"));
		return (events ^ EVT_START_DEVICE);
	}


	///////////////////////////////////////////////////////////////////////
	// key long press handle                                             //
	///////////////////////////////////////////////////////////////////////
	if (events & EVT_MODE) {
		if (key1_press) {
			oled_clr_screen();
			if ((opmode & 0xF0) == MODE_NORMAL) {
				opmode        = MODE_WORKOUT | MODE_TIME;
				workout.steps = normal.steps;
				workout.time  = osal_getClock();
				fmsg(("\033[40;32m[workout mode]\033[0m\n"));
			} else {
				opmode        = MODE_NORMAL | MODE_TIME;
				fmsg(("\033[40;32m[normal mode]\033[0m\n"));
			}

			pwmgr_state_change(pwmgr, TIME_OLED_OFF);
		}
		return (events ^ EVT_MODE);
	}

	if (events & EVT_SLEEP) {
		if (key1_press) {
			oled_clr_screen();
			opmode = MODE_SLEEP;
			fmsg(("\033[40;32m[sleep mode]\033[0m\n"));

			pwmgr_state_change(pwmgr, TIME_OLED_OFF);
		}
		return (events ^ EVT_SLEEP);
	}

	if (events & EVT_SYSRST) {
		if (key1_press) {
			fmsg(("\033[40;32m[system reset]\033[0m\n"));
			HAL_SYSTEM_RESET();
//			adxl345_self_calibration();
		}
		return (events ^ EVT_SYSRST);
	}


	///////////////////////////////////////////////////////////////////////
	// display handle                                                    //
	///////////////////////////////////////////////////////////////////////
	if (events & EVT_DISP) {
		if (pwmgr == PWMGR_S1) {
			sensorTag_HandleDisp(opmode, acc);
		} else {
			// display battery only
			sensorTag_BattDisp(batt_get_level());
		}
		if (pwmgr != PWMGR_S6)  {
			osal_start_timerEx(sensorTag_TaskID, EVT_DISP, PERIOD_DISP);
		}
		return (events ^ EVT_DISP);
	}


	///////////////////////////////////////////////////////////////////////
	// g-sensor handle                                                   //
	///////////////////////////////////////////////////////////////////////
	if (events & EVT_GSNINT1) {
		adxl345_exit_sleep();
		pwmgr_state_change(PWMGR_S3, TIME_GSEN_OFF);
		return (events ^ EVT_GSNINT1);
	}

	if (events & EVT_GSNINT2) {
		unsigned char	sampling;
		unsigned char	i;

		sampling = adxl345_chk_fifo();
		for (i=0; i<sampling; i++) {
			adxl345_read(acc);
#if (DEBUG_MESSAGE & MSG_STEPS)
			{
				unsigned long	tmp = algo_step(acc);
				if (normal.steps != tmp) {
					stepmsg(("\033[1;33mstep=%0lu\n\033[0m", tmp));
				}
				normal.steps = tmp;
			}
#else
			normal.steps = algo_step(acc);
#endif
		}

		normal.distance  = calc_distance(normal.steps, pi.stride);
		workout.distance = calc_distance((normal.steps - workout.steps), pi.stride);
		normal.calorie   = calc_calorie(normal.distance, pi.weight);
		workout.calorie  = calc_calorie(workout.distance, pi.weight);
		return (events ^ EVT_GSNINT2);
	}

	if (events & EVT_GSENSOR) {
		adxl345_exit_sleep();
		return (events ^ EVT_GSENSOR);
	}


	///////////////////////////////////////////////////////////////////////
	// RTC handle                                                        //
	///////////////////////////////////////////////////////////////////////
	if (events & EVT_RTC) {
		// performed once per second


		// record data
		if ((pwmgr != PWMGR_S5) && (pwmgr != PWMGR_S6)) {
#if defined(HAL_IMAGE_A) || defined(HAL_IMAGE_B)
			if ((osal_getClock() - mark.time) >= (12UL*60UL)) {
#else
			if ((osal_getClock() - mark.time) >= (12UL)) {
#endif
				if (!hash_is_full()) {
					unsigned short	tmp = normal.steps - mark.steps;

					switch (opmode & 0xF0) {
					case MODE_WORKOUT: tmp |= 0x8000; break;
					case MODE_SLEEP:   tmp |= 0x4000; break;
					}
					hash_put(&tmp);
				}
				mark.time  = osal_getClock();
#if defined(HAL_IMAGE_A) || defined(HAL_IMAGE_B)
				if ((mark.time % (24UL*60UL*60UL)) <= (13UL*60UL)) {
#else
				if ((mark.time % (24UL*60UL*60UL)) <= (13UL)) {
#endif
					dmsg(("reset steps...\n"));
					normal.steps  = 0;
					workout.steps = 0;
					STEPS         = 0;
				}
				mark.steps = normal.steps;
			}
		}

		// power management
		switch (pwmgr) {
		case PWMGR_S0:
			pmsg(("\033[40;35mS0 (power on)\033[0m\n"));
			if (pwmgr_saving_timer()) {
				adxl345_enter_sleep();

				osal_pwrmgr_device(PWRMGR_BATTERY);
				pwmgr_state_change(PWMGR_S4, 0);
			}
			break;

		case PWMGR_S1:
			pmsg(("\033[40;35mS1 (rtc+gsen+ble+oled)\033[0m\n"));
			if (pwmgr_saving_timer()) {
				oled_enter_sleep();
				osal_stop_timerEx(sensorTag_TaskID, EVT_MODE);
				osal_stop_timerEx(sensorTag_TaskID, EVT_SLEEP);
				osal_stop_timerEx(sensorTag_TaskID, EVT_SYSRST);

				pwmgr_state_change(PWMGR_S3, TIME_GSEN_OFF);
			}
			break;

		case PWMGR_S2:
			pmsg(("\033[40;35mS2 (rtc+gsen+ble)\033[0m\n"));
			if (gapProfileState == GAPROLE_WAITING) {
				// enable key interrupt mode
				InitBoard(OB_READY);
				pwmgr_state_change(PWMGR_S3, TIME_GSEN_OFF);
			}
			break;

		case PWMGR_S3:
			pmsg(("\033[40;35mS3 (rtc+gsen)\033[0m\n"));
			if (steps == normal.steps) {
				if (pwmgr_saving_timer()) {
					adxl345_enter_sleep();
					pwmgr_state_change(PWMGR_S4, 0);
				}
			} else {
				steps = normal.steps;
				pwmgr_state_change(pwmgr, TIME_GSEN_OFF);
			}
			break;

		case PWMGR_S4:
			pmsg(("\033[40;35mS4 (rtc)\033[0m\n"));
			dmsg(("$"));
			break;

		default:
		case PWMGR_S5:
			pmsg(("\033[40;35mS5 (shutdown)\033[0m\n"));
			adxl345_shutdown();
			osal_stop_timerEx(sensorTag_TaskID, EVT_RTC);
			break;

		case PWMGR_S6:
			pmsg(("\033[40;35mS6 (rtc+oled)\033[0m\n"));
			if (pwmgr_saving_timer()) {
				oled_enter_sleep();

				// enable key interrupt mode
				InitBoard(OB_READY);
				pwmgr_state_change(PWMGR_S5, 0);
			}
			break;
		}

		// battery measure
		if ((!batt_measure()) && (pwmgr != PWMGR_S6)) {
			pwmgr_state_change(PWMGR_S5, 0);
		}
		return (events ^ EVT_RTC);
	}


	///////////////////////////////////////////////////////////////////////
	// battery charge detect handle                                      //
	///////////////////////////////////////////////////////////////////////
	if (events & EVT_CHARGING) {
		if (pwmgr != PWMGR_S1) {
			if (!BATCD_SBIT) {
				dmsg(("[charging]\n"));
				oled_exit_sleep();
				if ((pwmgr == PWMGR_S5) || (pwmgr == PWMGR_S6)) {
					osal_start_reload_timer(sensorTag_TaskID, EVT_RTC, PERIOD_RTC);
					pwmgr_state_change(PWMGR_S4, 0);
				}
			} else {
				dmsg(("[no charge]\n"));
				oled_enter_sleep();
			}
		}
		return (events ^ EVT_CHARGING);
	}


	///////////////////////////////////////////////////////////////////////
	// discard unknown events                                            //
	///////////////////////////////////////////////////////////////////////

	return 0;
}
예제 #14
0
/******************************************************************************
 * @fn      modbus_process_msg
 * 
 * @brief   Process modbus message
 * 
 * @param   uint8 - the pointer the buffer
 *          uint8 - length 
 * 
 * @return  none
 */
static void modbus_process_msg( uint8 *data_buffer, uint8 len)
{
  uint8 num, tempByte;
  uint8 zero = 0;
  uint16 i;
  uint16 address;
  boatMonitor_t *pTempMonitor;
  
  UTCTime utcSecs;
  UTCTimeStruct utcTime;

  utcSecs = osal_getClock();
  osal_ConvertUTCTime( &utcTime, utcSecs );
  
  address = BUILD_UINT16( data_buffer[3], data_buffer[2]);
  
  if(( data_buffer[0] == modbus_id) || ( data_buffer[0] == 255))
  {
    if(data_buffer[1] == MODBUS_SINGLE_WRITE)
    {
      HalUARTWrite( 0, data_buffer, len);
      if( address == MODBUS_ADDRESS)
      {
        modbus_id = data_buffer[5];
        osal_nv_write( ZCD_NV_MODBUS_ID, 0, sizeof(modbus_id), &modbus_id);
      }
      if( address == MODBUS_BAUDRATE)
      {
        if((data_buffer[5] >=0) &&(data_buffer[5] <= 4))
        {
          modbus_set_baudrate = data_buffer[5];
          osal_nv_write( ZCD_NV_BAUDRATE, 0, sizeof(modbus_set_baudrate), &modbus_set_baudrate);
          restore_factory_setting();
        }
      }
    }
    else if( data_buffer[1] == MODBUS_MULTI_WRITE)
    {
      if( address == MODBUS_SERIALNUMBER_LOWORD)
      {
        if(data_buffer[6] == 8)
        {
          for( uint8 k=0;k<4;k++)
          {
            ttt[k] = data_buffer[2*k+8];
            osal_nv_write( ZCD_NV_SERIAL_NUM, 0, sizeof(ttt), ttt);
          }
        }
      }
      
      // write system UTC
      if( address == MODBUS_SYS_HOUR)
      {
        if( data_buffer[6] >= 12)
          modbus_setUtcTime( &data_buffer[7]);
      }
    }
    else if( data_buffer[1] == MODBUS_SINGLE_READ)
    {
      num = data_buffer[5];
      uint8 *pBuf;
      uint8 index=0;
      pBuf = osal_mem_alloc(num*2+5);
      if( pBuf != NULL)
      {
        pBuf[index++] = data_buffer[0];
        pBuf[index++] = data_buffer[1];
        pBuf[index++] = num*2;
      //modbus_send_byte( data_buffer[0], CRC_NO);
      //modbus_send_byte( data_buffer[1], CRC_NO);
      //modbus_send_byte( num*2, CRC_NO);
        for( i = 0; i < num; i++)
        {
          if ( i + address <= MODBUS_SERIALNUMBER_LOWORD + 3)
          {
            //modbus_send_byte( zero, CRC_NO);
            pBuf[index++] = zero;
            pBuf[index++] =  ttt[ i + address - MODBUS_SERIALNUMBER_LOWORD];
          }
          else if( i + address == MODBUS_FIRMWARE_VERSION_NUMBER_LO)
          {
            pBuf[index++] = zero;
            pBuf[index++] = ttt[4];
          }
          else if( i + address == MODBUS_FIRMWARE_VERSION_NUMBER_HI)
          {
            pBuf[index++] = zero;
            pBuf[index++] = ttt[5];
          }
          else if( i + address == MODBUS_ADDRESS)
          {
            pBuf[index++] = zero;
            pBuf[index++] = modbus_id;
          }
          else if( i + address == MODBUS_PRODUCT_ID)
          {
            pBuf[index++] = zero;
            pBuf[index++] = 210;
          }
          // System UTC Time
          else if( i + address == MODBUS_SYS_HOUR)
          {
            pBuf[index++] = zero;
            pBuf[index++] = utcTime.hour;
          }
          else if( i + address == MODBUS_SYS_MINUTES)
          {
            pBuf[index++] = zero;
            pBuf[index++] = utcTime.minutes;          
          }
          else if( i + address == MODBUS_SYS_SECONDS)
          {
            pBuf[index++] = zero;
            pBuf[index++] = utcTime.seconds;
          }
          else if( i + address == MODBUS_SYS_MONTH)
          {
            tempByte = utcTime.month + 1;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_SYS_DAY)
          {
            tempByte = utcTime.day + 1;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_SYS_YEAR)
          {
            tempByte = HI_UINT16( utcTime.year);
            pBuf[index++] = tempByte;
            tempByte = LO_UINT16( utcTime.year);
            pBuf[index++] = tempByte;
          }
          /*else if( i + address == MODBUS_WATER_SWITCH)
          {
            if(leaveTimeCounter){
              tempByte = water_switch;
              //leaveTimeCounter=0;
            }
            else
              tempByte = zero;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_DETECT_POWER)
          {
            uint16 power_temp;
            if(leaveTimeCounter){
              power_temp = (ad_power-196)*10/10.57+90;//(ad_power-186)*100/74+90;//((ad_power-644)*64)/100+70;
              //leaveTimeCounter = 0;
            }else
              power_temp = 0;
            
            tempByte = HI_UINT16( power_temp);
            pBuf[index++] = tempByte;
            tempByte = LO_UINT16( power_temp);
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_WATER_ID)
          {
            if(leaveTimeCounter){
              tempByte = water_id;
              //leaveTimeCounter=0;
            }
            else
              tempByte = zero;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_WATER_RSSI)
          {
            if(leaveTimeCounter){
              tempByte = (uint8)water_rssi;
              
            }
            else
              tempByte = zero;
            pBuf[index++] = 255;
            pBuf[index++] = tempByte;
          }
          
          else if( i + address == MODBUS_WATER_SWITCH1)
          {
            if(leaveTimeCounter1){
              tempByte = water_switch1;
              //leaveTimeCounter=0;
            }
            else
              tempByte = zero;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_DETECT_POWER1)
          {
            uint16 power_temp;
            if(leaveTimeCounter1){
              power_temp = (ad_power1-196)*10/10.57+90;//(ad_power-186)*100/74+90;//((ad_power-644)*64)/100+70;
              //leaveTimeCounter = 0;
            }else
              power_temp = 0;
            
            tempByte = HI_UINT16( power_temp);
            pBuf[index++] = tempByte;
            tempByte = LO_UINT16( power_temp);
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_WATER_ID1)
          {
            if(leaveTimeCounter1){
              tempByte = water_id1;
              //leaveTimeCounter=0;
            }
            else
              tempByte = zero;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }*/
          else if( i + address == MODBUS_BAUDRATE)
          {
            tempByte = modbus_set_baudrate;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          
          else if( i + address == MODBUS_PANID)
          {
            tempByte = HI_UINT16( _NIB.nwkPanId);
            pBuf[index++] = tempByte;
            tempByte = LO_UINT16( _NIB.nwkPanId);
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_DEVICE_TYPE)
          {
            tempByte = zgDeviceLogicalType;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_CHANNEL_LIST_HI)
          {
            tempByte = BREAK_UINT32(zgDefaultChannelList, 3);
            pBuf[index++] = tempByte;
            tempByte = BREAK_UINT32(zgDefaultChannelList, 2);
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_CHANNEL_LIST_LO)
          {
            tempByte = BREAK_UINT32(zgDefaultChannelList, 1);
            pBuf[index++] = tempByte;
            tempByte = BREAK_UINT32(zgDefaultChannelList, 0);
            pBuf[index++] = tempByte;
          }
          else if( (i + address >= MODBUS_EXTENDED_ADDR_HI) && (i + address <= MODBUS_EXTENDED_ADDR_LO))
          {
            tempByte = aExtendedAddress[ i+address-MODBUS_EXTENDED_ADDR_HI];
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( (i + address >= MODBUS_SECURITY_KEY_START) && (i + address <= MODBUS_SECURITY_KEY_END))
          {
            tempByte = defaultKey[ i+address-MODBUS_SECURITY_KEY_START];
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          /*else if( i + address == MODBUS_DETECT_PIN1)
          {
            uint16 power_temp;
            if(leaveTimeCounter){
              power_temp = detectPin1;
            }else
              power_temp = 0;
            
            tempByte = HI_UINT16( power_temp);
            pBuf[index++] = tempByte;
            tempByte = LO_UINT16( power_temp);
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_DETECT_PIN2)
          {
            uint16 power_temp;
            if(leaveTimeCounter){
              power_temp = detectPin2;
              //leaveTimeCounter=0;
            }else
              power_temp = 0;
            
            tempByte = HI_UINT16( power_temp);
            pBuf[index++] = tempByte;
            tempByte = LO_UINT16( power_temp);
            pBuf[index++] = tempByte;
          }*/
          else if( i + address == MODBUS_MONITOR_NUM)
          {
            tempByte = numMonitor;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( (i + address >= MODBUS_FIRST_MONITOR_ID) && ( i+ address <= MODBUS_LAST_MONITOR_ID))
          {
            if( i + address == MODBUS_FIRST_MONITOR_ID)
            {
              pTempMonitor = pBoatMonitor;
            }
            else
            {
              pTempMonitor = pBoatMonitor;
              for( uint8 j=0; j<((i+address)-MODBUS_FIRST_MONITOR_ID); j++)
              {
                if(pTempMonitor)
                  pTempMonitor = pTempMonitor->next;
              }
            }
            pBuf[index++]= zero;
            if(pTempMonitor != NULL)
            {
              pBuf[index++]= pTempMonitor->modbus_id;
            }
            else
              pBuf[index++]= zero;
          }
          else if( (i + address >= MODBUS_FIRST_DETECT_POWER) && ( i+ address <= MODBUS_LAST_DETECT_POWER))
          {
            if( i + address == MODBUS_FIRST_DETECT_POWER)
            {
              pTempMonitor = pBoatMonitor;
            }
            else
            {
              pTempMonitor = pBoatMonitor;
              for( uint8 j=0; j<((i+address)-MODBUS_FIRST_DETECT_POWER); j++)
              {
                if(pTempMonitor)
                  pTempMonitor = pTempMonitor->next;
              }
            }
            if(pTempMonitor != NULL)
            { 
              uint16 power_temp;
              power_temp = (pTempMonitor->ad_power-196)*10/10.57+90;
              tempByte = HI_UINT16( power_temp);
              pBuf[index++] = tempByte;
              tempByte = LO_UINT16( power_temp);
              pBuf[index++] = tempByte;
            }
            else
            {
              pBuf[index++]= zero;
              pBuf[index++]= zero;
            }
          }
          else if( (i + address >= MODBUS_FIRST_WATER_SWITCH) && ( i+ address <= MODBUS_LAST_WATER_SWITCH))
          {
            if( i + address == MODBUS_FIRST_WATER_SWITCH)
            {
              pTempMonitor = pBoatMonitor;
            }
            else
            {
              pTempMonitor = pBoatMonitor;
              for( uint8 j=0; j<((i+address)-MODBUS_FIRST_WATER_SWITCH); j++)
              {
                if(pTempMonitor)
                  pTempMonitor = pTempMonitor->next;
              }
            }
            pBuf[index++]= zero;
            if(pTempMonitor != NULL)
            {
              pBuf[index++]= pTempMonitor->water_switch;
            }
            else
              pBuf[index++]= zero;
          }
          else if((i + address >= MODBUS_FIRST_DETECT_PIN1) && ( i+ address <= MODBUS_LAST_DETECT_PIN1))
          {
            if( i + address == MODBUS_FIRST_DETECT_PIN1)
            {
              pTempMonitor = pBoatMonitor;
            }
            else
            {
              pTempMonitor = pBoatMonitor;
              for( uint8 j=0; j<((i+address)-MODBUS_FIRST_DETECT_PIN1); j++)
              {
                if(pTempMonitor)
                  pTempMonitor = pTempMonitor->next;
              }
            }
            if(pTempMonitor != NULL)
            { 
              tempByte = HI_UINT16( pTempMonitor->detectPin1);
              pBuf[index++] = tempByte;
              tempByte = LO_UINT16( pTempMonitor->detectPin1);
              pBuf[index++] = tempByte;
            }
            else
            {
              pBuf[index++]= zero;
              pBuf[index++]= zero;
            }
          } 
          else if((i + address >= MODBUS_FIRST_DETECT_PIN2) && ( i+ address <= MODBUS_LAST_DETECT_PIN2))
          {
            if( i + address == MODBUS_FIRST_DETECT_PIN2)
            {
              pTempMonitor = pBoatMonitor;
            }
            else
            {
              pTempMonitor = pBoatMonitor;
              for( uint8 j=0; j<((i+address)-MODBUS_FIRST_DETECT_PIN2); j++)
              {
                if(pTempMonitor)
                  pTempMonitor = pTempMonitor->next;
              }
            }
            if(pTempMonitor != NULL)
            { 
              tempByte = HI_UINT16( pTempMonitor->detectPin2);
              pBuf[index++] = tempByte;
              tempByte = LO_UINT16( pTempMonitor->detectPin2);
              pBuf[index++] = tempByte;
            }
            else
            {
              pBuf[index++]= zero;
              pBuf[index++]= zero;
            }
          }
          else if( (i + address >= MODBUS_FIRST_RSSI) && ( i+ address <= MODBUS_LAST_RSSI))
          {
            if( i + address == MODBUS_FIRST_RSSI)
            {
              pTempMonitor = pBoatMonitor;
            }
            else
            {
              pTempMonitor = pBoatMonitor;
              for( uint8 j=0; j<((i+address)-MODBUS_FIRST_RSSI); j++)
              {
                if(pTempMonitor)
                  pTempMonitor = pTempMonitor->next;
              }
            }
            if(pTempMonitor->rssi>=0)
              pBuf[index++] = 0;
            else
              pBuf[index++]= 0xff;
            
            if(pTempMonitor != NULL)
            {
              pBuf[index++]= pTempMonitor->rssi;
            }
            else
              pBuf[index++]= zero;
          }
          
          
          else
          {
            pBuf[index++] = zero;
            pBuf[index++] = zero;
          }
        }
        for( i=0; i<num*2+3; i++)
          CRC16_byte(pBuf[i]);
        pBuf[num*2+3] = CRChi;
        pBuf[num*2+4] = CRClo;
        P1_0 = 1;
        send_str_Uart( pBuf, num*2+5, 0);
        P1_0 = 0;
        osal_mem_free(pBuf);
      }
      else{
        send_str_Uart( pBuf, num*2+5, 0);
      }
    }
  }
}
예제 #15
0
/*********************************************************************
 * @fn          ipd_event_loop
 *
 * @brief       Event Loop Processor for ipd.
 *
 * @param       uint8 task_id - ipd task id
 * @param       uint16 events - event bitmask
 *
 * @return      none
 */
uint16 ipd_event_loop( uint8 task_id, uint16 events )
{
    afIncomingMSGPacket_t *MSGpkt;

    if ( events & SYS_EVENT_MSG )
    {
        while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( ipdTaskID )) )
        {
            switch ( MSGpkt->hdr.event )
            {
            case ZCL_INCOMING_MSG:
                // Incoming ZCL foundation command/response messages
                ipd_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt );
                break;

            case KEY_CHANGE:
                ipd_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
                break;

            case ZDO_STATE_CHANGE:
                if (DEV_END_DEVICE == (devStates_t)(MSGpkt->hdr.status))
                {
#if SECURE
                    {
                        // check to see if link key had already been established
                        linkKeyStatus = ipd_KeyEstablish_ReturnLinkKey(ESPAddr.addr.shortAddr);

                        if (linkKeyStatus != ZSuccess)
                        {
                            // send out key establishment request
                            osal_set_event( ipdTaskID, IPD_KEY_ESTABLISHMENT_REQUEST_EVT);
                        }
                        else
                        {
                            // link key already established, resume sending reports
                            osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD );
                        }
                    }
#else
                    {
                        osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD );
                    }
#endif
                    // Per smart energy spec end device polling requirement of not to poll < 7.5 seconds.
                    NLME_SetPollRate ( SE_DEVICE_POLL_RATE );
                }
                break;

#if defined( ZCL_KEY_ESTABLISH )
            case ZCL_KEY_ESTABLISH_IND:
                if ((MSGpkt->hdr.status) == TermKeyStatus_Success)
                {
                    osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD );
                }

                break;
#endif

            default:
                break;
            }

            // Release the memory
            osal_msg_deallocate( (uint8 *)MSGpkt );

        }

        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
    }

    // event to intiate key establishment request
    if ( events & IPD_KEY_ESTABLISHMENT_REQUEST_EVT )
    {
        zclGeneral_KeyEstablish_InitiateKeyEstablishment(ipdTaskID, &ESPAddr, ipdTransID);

        return ( events ^ IPD_KEY_ESTABLISHMENT_REQUEST_EVT );
    }

    // event to get current price
    if ( events & IPD_GET_PRICING_INFO_EVT )
    {
        zclSE_Pricing_Send_GetCurrentPrice( IPD_ENDPOINT, &ESPAddr, option, TRUE, 0 );

        osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD );

        return ( events ^ IPD_GET_PRICING_INFO_EVT );
    }

    // handle processing of identify timeout event triggered by an identify command
    if ( events & IPD_IDENTIFY_TIMEOUT_EVT )
    {
        if ( ipdIdentifyTime > 0 )
        {
            ipdIdentifyTime--;
        }
        ipd_ProcessIdentifyTimeChange();

        return ( events ^ IPD_IDENTIFY_TIMEOUT_EVT );
    }

    // event to get current time
    if ( events & IPD_UPDATE_TIME_EVT )
    {
        ipdTime = osal_getClock();
        osal_start_timerEx( ipdTaskID, IPD_UPDATE_TIME_EVT, IPD_UPDATE_TIME_PERIOD );

        return ( events ^ IPD_UPDATE_TIME_EVT );
    }

    // Discard unknown events
    return 0;
}